aboutsummaryrefslogtreecommitdiff
path: root/src/base/io/AutoReadStream.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-10-06 13:57:39 +0800
committercrupest <crupest@outlook.com>2024-10-06 13:57:39 +0800
commitdfe62dcf8bcefc523b466e127c3edc4dc2756629 (patch)
tree1c751a14ba0da07ca2ff805633f97568060aa4c9 /src/base/io/AutoReadStream.cpp
parentf51eb955e188858272230a990565931e7403f23b (diff)
downloadcru-dfe62dcf8bcefc523b466e127c3edc4dc2756629.tar.gz
cru-dfe62dcf8bcefc523b466e127c3edc4dc2756629.tar.bz2
cru-dfe62dcf8bcefc523b466e127c3edc4dc2756629.zip
Rename common to base.
Diffstat (limited to 'src/base/io/AutoReadStream.cpp')
-rw-r--r--src/base/io/AutoReadStream.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/base/io/AutoReadStream.cpp b/src/base/io/AutoReadStream.cpp
new file mode 100644
index 00000000..c24f61d1
--- /dev/null
+++ b/src/base/io/AutoReadStream.cpp
@@ -0,0 +1,56 @@
+#include "cru/base/io/AutoReadStream.h"
+#include "cru/base/io/Stream.h"
+
+#include <thread>
+
+namespace cru::io {
+
+AutoReadStream::AutoReadStream(Stream* stream, bool auto_delete,
+ const AutoReadStreamOptions& options)
+ : Stream(false, true, stream->CanSeek()) {
+ auto buffer_stream_options = options.GetBufferStreamOptions();
+ stream_ = stream;
+ size_per_read_ = buffer_stream_options.GetBlockSizeOrDefault();
+ buffer_stream_ = std::make_unique<BufferStream>(buffer_stream_options);
+ background_thread_ = std::thread(&AutoReadStream::BackgroundThreadRun, this);
+}
+
+AutoReadStream::~AutoReadStream() {
+ if (auto_delete_) {
+ delete stream_;
+ }
+}
+
+Index AutoReadStream::DoRead(std::byte* buffer, Index offset, Index size) {
+ std::unique_lock lock(buffer_stream_mutex_);
+ return buffer_stream_->Read(buffer, offset, size);
+}
+
+Index AutoReadStream::DoWrite(const std::byte* buffer, Index offset,
+ Index size) {
+ return stream_->Write(buffer, offset, size);
+}
+
+void AutoReadStream::DoFlush() { stream_->Flush(); }
+
+void AutoReadStream::DoClose() {}
+
+void AutoReadStream::BackgroundThreadRun() {
+ std::vector<std::byte> buffer(size_per_read_);
+ while (true) {
+ try {
+ auto read = stream_->Read(buffer.data(), buffer.size());
+ if (read == 0) {
+ buffer_stream_->SetEof();
+ break;
+ } else {
+ buffer_stream_->Write(buffer.data(), read);
+ }
+ } catch (const StreamAlreadyClosedException& exception) {
+ buffer_stream_->SetEof();
+ break;
+ }
+ }
+}
+
+} // namespace cru::io