diff options
author | Dominick Allen <djallen@librehumanitas.org> | 2025-01-01 17:41:17 -0600 |
---|---|---|
committer | Dominick Allen <djallen@librehumanitas.org> | 2025-01-01 17:41:17 -0600 |
commit | 16379362c02a2472f00fac49cad62788547c9519 (patch) | |
tree | 9b7f42acbba8dd259a536287a2b130e92ad2e2c7 /source/fud_file.cpp | |
parent | 012df4bc38777c9053353ec2c4213bba67d63ab4 (diff) |
Add CSV parsing, printing, fix buffered file reading.
Diffstat (limited to 'source/fud_file.cpp')
-rw-r--r-- | source/fud_file.cpp | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/source/fud_file.cpp b/source/fud_file.cpp index 55f8dbc..caf0f5a 100644 --- a/source/fud_file.cpp +++ b/source/fud_file.cpp @@ -17,6 +17,8 @@ #include "fud_file.hpp" +#include "fud_algorithm.hpp" + #include <cerrno> #include <fcntl.h> #include <linux/openat2.h> @@ -625,6 +627,7 @@ DrainResult BufferedRegularFile::write(const std::byte* source, size_t length, O DrainResult BufferedRegularFile::read(std::byte* sink, size_t length, Option<size_t> maxExtraAttempts) { + auto extraAttempts = maxExtraAttempts.valueOr(0); DrainResult result{0, FudStatus::Success}; if (sink == nullptr) { @@ -637,15 +640,6 @@ DrainResult BufferedRegularFile::read(std::byte* sink, size_t length, Option<siz return result; } - if (m_lastOperation != Operation::Write) { - m_bufferLength = 0; - m_lastOperation = Operation::Write; - } - - if (length == 0) { - return result; - } - if (m_lastOperation == Operation::Write && m_bufferLength > 0) { result.status = FudStatus::OperationInvalid; return result; @@ -653,13 +647,18 @@ DrainResult BufferedRegularFile::read(std::byte* sink, size_t length, Option<siz if (m_lastOperation != Operation::Read) { m_lastOperation = Operation::Read; + m_bufferPosition = 0; + m_bufferLength = 0; + } + + if (length == 0) { + return result; } if (m_bufferLength > 0 && m_bufferPosition < m_bufferLength) { - auto count = m_bufferLength - m_bufferPosition; - if (count > length) { - count = length; - } + auto remainingLength = m_bufferLength - m_bufferPosition; + auto count = min(length, remainingLength); + auto copyStatus = copyMem(sink, length, m_buffer.data() + m_bufferPosition, count); fudAssert(copyStatus == FudStatus::Success); @@ -677,23 +676,52 @@ DrainResult BufferedRegularFile::read(std::byte* sink, size_t length, Option<siz m_bufferLength = 0; } + if (length == 0) { + return result; + } + + fudAssert(m_bufferLength == 0); + fudAssert(m_bufferPosition == 0); + if (length > m_buffer.size()) { - auto drainResult = m_file.read(sink, length, maxExtraAttempts.valueOr(0)); + auto drainResult = m_file.read(sink, length, extraAttempts); + + sink += drainResult.bytesDrained; + length -= drainResult.bytesDrained; + result.status = drainResult.status; result.bytesDrained += drainResult.bytesDrained; + return result; } - if (length == 0 || result.status != FudStatus::Success) { + fudAssert(length > 0); + + if (result.status != FudStatus::Success) { return result; } - fudAssert(m_bufferLength == 0 && m_bufferPosition == 0); - auto drainResult = m_file.read(m_buffer.data(), m_buffer.size(), maxExtraAttempts.valueOr(0)); - if (drainResult.status != FudStatus::Success && drainResult.status != FudStatus::Partial) { - result.status = drainResult.status; - } else { - result.status = FudStatus::Success; + fudAssert(m_bufferLength == 0); + fudAssert(m_bufferPosition == 0); + + auto drainResult = m_file.read(m_buffer.data(), m_buffer.size(), extraAttempts); + result.status = drainResult.status; + if (drainResult.status == FudStatus::Success || drainResult.status == FudStatus::Partial) { m_bufferLength = drainResult.bytesDrained; + + auto count = min(length, m_bufferLength); + + auto copyStatus = copyMem(sink, count, m_buffer.data(), count); + fudAssert(copyStatus == FudStatus::Success); + + sink += count; + length -= count; + + if (drainResult.status == FudStatus::Partial && length == 0) { + drainResult.status = FudStatus::Success; + } + + m_bufferPosition = count; + result.bytesDrained += count; } return result; @@ -713,6 +741,12 @@ DrainResult BufferedRegularFile::flush(size_t maxExtraAttempts) return {0, FudStatus::Success}; } + if (m_lastOperation != Operation::Write) { + m_bufferLength = 0; + m_bufferPosition = 0; + return {0, FudStatus::Success}; + } + auto drainResult = m_file.write(m_buffer.data(), m_bufferLength, maxExtraAttempts); if (drainResult.status == FudStatus::Success) { m_bufferLength = 0; |