diff options
-rw-r--r-- | include/cru/common/Buffer.h | 28 | ||||
-rw-r--r-- | include/cru/common/io/BufferStream.h | 6 | ||||
-rw-r--r-- | src/common/Buffer.cpp | 30 | ||||
-rw-r--r-- | src/common/io/BufferStream.cpp | 28 |
4 files changed, 79 insertions, 13 deletions
diff --git a/include/cru/common/Buffer.h b/include/cru/common/Buffer.h index 8574cd86..69c47aff 100644 --- a/include/cru/common/Buffer.h +++ b/include/cru/common/Buffer.h @@ -17,7 +17,7 @@ class Buffer final { ~Buffer(); - private: + public: Index GetBufferSize() const { return size_; } Index GetUsedSize() const { return used_end_ - used_begin_; } bool IsNull() const { return ptr_ == nullptr; } @@ -71,7 +71,8 @@ class Buffer final { * written and the size of it will be returned, leaving exceeded data not * saved. */ - Index PushFront(std::byte* other, Index other_size, bool use_memmove = false); + Index PushFront(const std::byte* other, Index other_size, + bool use_memmove = false); /** * @brief Append data to the back of used bytes and increase used size. @@ -81,7 +82,8 @@ class Buffer final { * written and the size of it will be returned, leaving exceeded data not * saved. */ - Index PushBack(std::byte* other, Index other_size, bool use_memmove = false); + Index PushBack(const std::byte* other, Index other_size, + bool use_memmove = false); /** * @brief Move forward the used-begin ptr. @@ -93,6 +95,16 @@ class Buffer final { Index PopFront(Index size); /** + * @brief Pop front data of used bytes into another buffer. + * @return The actual size popped. + * + * If given size is bigger than current used size, then only current used size + * of bytes will be popped. If given size is smaller than current used size, + * then only given size of bytes will be popped. + */ + Index PopFront(std::byte* buffer, Index size, bool use_memmove = false); + + /** * @brief Move backward the used-end ptr. * @return The actual size moved backward. * @@ -101,6 +113,16 @@ class Buffer final { */ Index PopEnd(Index size); + /** + * @brief Pop back data of used bytes into another buffer. + * @return The actual size popped. + * + * If given size is bigger than current used size, then only current used size + * of bytes will be popped. If given size is smaller than current used size, + * then only given size of bytes will be popped. + */ + Index PopEnd(std::byte* buffer, Index size, bool use_memmove = false); + operator std::byte*() { return GetPtr(); } operator const std::byte*() const { return GetPtr(); } diff --git a/include/cru/common/io/BufferStream.h b/include/cru/common/io/BufferStream.h index 64d1bb56..a95b3487 100644 --- a/include/cru/common/io/BufferStream.h +++ b/include/cru/common/io/BufferStream.h @@ -1,8 +1,8 @@ #pragma once #include "../Buffer.h" -#include "Stream.h" #include "../Exception.h" +#include "Stream.h" #include <condition_variable> #include <list> @@ -10,9 +10,9 @@ namespace cru::io { class WriteAfterEofException : public Exception { - public: + public: using Exception::Exception; - ~WriteAfterEofException() override = default; + ~WriteAfterEofException() override = default; }; struct BufferStreamOptions { diff --git a/src/common/Buffer.cpp b/src/common/Buffer.cpp index 00bbd166..67e67735 100644 --- a/src/common/Buffer.cpp +++ b/src/common/Buffer.cpp @@ -76,7 +76,8 @@ void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { } } -Index Buffer::PushFront(std::byte* other, Index other_size, bool use_memmove) { +Index Buffer::PushFront(const std::byte* other, Index other_size, + bool use_memmove) { auto copy_size = std::min(used_begin_, other_size); if (copy_size) { @@ -88,7 +89,8 @@ Index Buffer::PushFront(std::byte* other, Index other_size, bool use_memmove) { return copy_size; } -Index Buffer::PushBack(std::byte* other, Index other_size, bool use_memmove) { +Index Buffer::PushBack(const std::byte* other, Index other_size, + bool use_memmove) { auto copy_size = std::min(size_ - used_end_, other_size); if (copy_size) { @@ -106,12 +108,36 @@ Index Buffer::PopFront(Index size) { return move; } +Index Buffer::PopFront(std::byte* buffer, Index size, bool use_memmove) { + auto pop_size = std::min(GetUsedSize(), size); + + if (pop_size) { + used_begin_ += pop_size; + (use_memmove ? std::memmove : std::memcpy)( + buffer, GetUsedBeginPtr() - pop_size, pop_size); + } + + return pop_size; +} + Index Buffer::PopEnd(Index size) { auto move = std::min(size_ - used_end_, size); used_end_ += move; return move; } +Index Buffer::PopEnd(std::byte* buffer, Index size, bool use_memmove) { + auto pop_size = std::min(GetUsedSize(), size); + + if (pop_size) { + used_end_ -= pop_size; + (use_memmove ? std::memmove : std::memcpy)(buffer, GetUsedEndPtr(), + pop_size); + } + + return pop_size; +} + void Buffer::Copy_(const Buffer& other) { if (other.ptr_ == nullptr) { ptr_ = nullptr; diff --git a/src/common/io/BufferStream.cpp b/src/common/io/BufferStream.cpp index d4780f7a..c08d04a5 100644 --- a/src/common/io/BufferStream.cpp +++ b/src/common/io/BufferStream.cpp @@ -1,5 +1,4 @@ #include "cru/common/io/BufferStream.h" -#include <memory> #include "cru/common/io/Stream.h" namespace cru::io { @@ -26,20 +25,39 @@ Index BufferStream::Seek(Index offset, SeekOrigin origin) { bool BufferStream::CanRead() { CheckClosed(); - return true; } + return true; +} Index BufferStream::Read(std::byte* buffer, Index offset, Index size) { std::unique_lock lock(mutex_); - Index written_size = 0; + condition_variable_.wait(lock, + [this] { return !buffer_list_.empty() || eof_; }); - if (eof_ && buffer_list_.empty()) { + if (eof_) { return 0; } + Index written_size = 0; + auto current_offset = offset; + auto rest_size = size; + while (!buffer_list_.empty()) { - + auto& stream_buffer = buffer_list_.front(); + auto this_written_size = + stream_buffer.PopFront(buffer + current_offset, rest_size); + if (stream_buffer.GetUsedSize() == 0) { + buffer_list_.pop_front(); + } + written_size += this_written_size; + rest_size -= this_written_size; + current_offset += this_written_size; + if (rest_size == 0) { + break; + } } + + return written_size; } } // namespace cru::io |