#include "io_helpers.h" #include "io.h" #include namespace saw { void read_task_and_step_helper::read_step(input_stream &reader) { while (read_task.has_value()) { read_io_task &task = *read_task; error_or n_err = reader.read(task.buffer, task.max_length); if (n_err.is_error()) { const error &error = n_err.get_error(); if (error.is_critical()) { if (read_done) { read_done->fail(error.copy_error()); } read_task = std::nullopt; } break; } else if (n_err.is_value()) { size_t n = n_err.get_value(); if (static_cast(n) >= task.min_length && static_cast(n) <= task.max_length) { if (read_done) { read_done->feed(n + task.already_read); } read_task = std::nullopt; } else { task.buffer = static_cast(task.buffer) + n; task.min_length -= static_cast(n); task.max_length -= static_cast(n); task.already_read += n; } } else { if (read_done) { read_done->fail(make_error("Read failed")); } read_task = std::nullopt; } } } void write_task_and_step_helper::write_step(output_stream &writer) { while (write_task.has_value()) { write_io_task &task = *write_task; error_or n_err = writer.write(task.buffer, task.length); if (n_err.is_value()) { size_t n = n_err.get_value(); assert(n <= task.length); if (n == task.length) { if (write_done) { write_done->feed(n + task.already_written); } write_task = std::nullopt; } else { task.buffer = static_cast(task.buffer) + n; task.length -= n; task.already_written += n; } } else if (n_err.is_error()) { const error &error = n_err.get_error(); if (error.is_critical()) { if (write_done) { write_done->fail(error.copy_error()); } write_task = std::nullopt; } break; } else { if (write_done) { write_done->fail(make_error("Write failed")); } write_task = std::nullopt; } } } } // namespace saw