| // Copyright 2015 The Weave Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/streams.h" |
| |
| #include <base/bind.h> |
| #include <base/callback.h> |
| #include <weave/provider/task_runner.h> |
| #include <weave/stream.h> |
| |
| namespace weave { |
| |
| namespace {} // namespace |
| |
| MemoryStream::MemoryStream(const std::vector<uint8_t>& data, |
| provider::TaskRunner* task_runner) |
| : data_{data}, task_runner_{task_runner} {} |
| |
| void MemoryStream::Read(void* buffer, |
| size_t size_to_read, |
| const ReadCallback& callback) { |
| CHECK_LE(read_position_, data_.size()); |
| size_t size_read = std::min(size_to_read, data_.size() - read_position_); |
| if (size_read > 0) |
| memcpy(buffer, data_.data() + read_position_, size_read); |
| read_position_ += size_read; |
| task_runner_->PostDelayedTask(FROM_HERE, |
| base::Bind(callback, size_read, nullptr), {}); |
| } |
| |
| void MemoryStream::Write(const void* buffer, |
| size_t size_to_write, |
| const WriteCallback& callback) { |
| data_.insert(data_.end(), static_cast<const char*>(buffer), |
| static_cast<const char*>(buffer) + size_to_write); |
| task_runner_->PostDelayedTask(FROM_HERE, base::Bind(callback, nullptr), {}); |
| } |
| |
| StreamCopier::StreamCopier(InputStream* source, OutputStream* destination) |
| : source_{source}, destination_{destination}, buffer_(4096) {} |
| |
| void StreamCopier::Copy(const InputStream::ReadCallback& callback) { |
| source_->Read(buffer_.data(), buffer_.size(), |
| base::Bind(&StreamCopier::OnReadDone, |
| weak_ptr_factory_.GetWeakPtr(), callback)); |
| } |
| |
| void StreamCopier::OnReadDone(const InputStream::ReadCallback& callback, |
| size_t size, |
| ErrorPtr error) { |
| if (error) |
| return callback.Run(0, std::move(error)); |
| |
| size_done_ += size; |
| if (size) { |
| return destination_->Write( |
| buffer_.data(), size, |
| base::Bind(&StreamCopier::OnWriteDone, weak_ptr_factory_.GetWeakPtr(), |
| callback)); |
| } |
| callback.Run(size_done_, nullptr); |
| } |
| |
| void StreamCopier::OnWriteDone(const InputStream::ReadCallback& callback, |
| ErrorPtr error) { |
| if (error) |
| return callback.Run(size_done_, std::move(error)); |
| Copy(callback); |
| } |
| |
| } // namespace weave |