diff options
author | Claudius Holeksa <mail@keldu.de> | 2023-04-29 18:44:59 +0200 |
---|---|---|
committer | Claudius Holeksa <mail@keldu.de> | 2023-04-29 18:44:59 +0200 |
commit | f07487ce8f0f3ebd5c4d1082a9521f09588fa34a (patch) | |
tree | 5cccd5e20d180cbe128dd0ae7759b50d26199af4 /forstio/io/io_helpers.cpp | |
parent | 47c44aab6cf54e4885de4138cab1aa3825f115e4 (diff) |
Added io to new repo
Diffstat (limited to 'forstio/io/io_helpers.cpp')
-rw-r--r-- | forstio/io/io_helpers.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/forstio/io/io_helpers.cpp b/forstio/io/io_helpers.cpp new file mode 100644 index 0000000..47c5017 --- /dev/null +++ b/forstio/io/io_helpers.cpp @@ -0,0 +1,85 @@ +#include "io_helpers.h" + +#include "io.h" + +#include <cassert> + +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<size_t> n_err = reader.read(task.buffer, task.max_length); + if (n_err.is_error()) { + const error &error = n_err.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.value(); + if (static_cast<size_t>(n) >= task.min_length && + static_cast<size_t>(n) <= task.max_length) { + if (read_done) { + read_done->feed(n + task.already_read); + } + read_task = std::nullopt; + } else { + task.buffer = static_cast<uint8_t *>(task.buffer) + n; + task.min_length -= static_cast<size_t>(n); + task.max_length -= static_cast<size_t>(n); + task.already_read += n; + } + + } else { + if (read_done) { + read_done->fail(critical_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<size_t> n_err = writer.write(task.buffer, task.length); + + if (n_err.is_value()) { + + size_t n = n_err.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<const uint8_t *>(task.buffer) + n; + task.length -= n; + task.already_written += n; + } + } else if (n_err.is_error()) { + const error &error = n_err.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(critical_error("Write failed")); + } + write_task = std::nullopt; + } + } +} + +} // namespace saw |