aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-05-12 00:19:16 +0800
committercrupest <crupest@outlook.com>2024-05-12 00:19:16 +0800
commitd861d799d2f614a6b58a8f0c0bc6a8911ad0dcfd (patch)
treeadfe4096c07d7bf039b52d3d21d8ef742c8da837
parentdd62b63e1c577abe53d0f9cabe8e9a635c4c8fcf (diff)
downloadcru-d861d799d2f614a6b58a8f0c0bc6a8911ad0dcfd.tar.gz
cru-d861d799d2f614a6b58a8f0c0bc6a8911ad0dcfd.tar.bz2
cru-d861d799d2f614a6b58a8f0c0bc6a8911ad0dcfd.zip
WORKING: fix Buffer and implement BufferStream::Read.
-rw-r--r--include/cru/common/Buffer.h28
-rw-r--r--include/cru/common/io/BufferStream.h6
-rw-r--r--src/common/Buffer.cpp30
-rw-r--r--src/common/io/BufferStream.cpp28
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