Darin Petkov | e971f33 | 2010-09-22 16:57:25 -0700 | [diff] [blame] | 1 | // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "update_engine/buffered_file_writer.h" |
| 6 | |
| 7 | namespace chromeos_update_engine { |
| 8 | |
| 9 | BufferedFileWriter::BufferedFileWriter(FileWriter* next, size_t buffer_size) |
| 10 | : next_(next), |
| 11 | buffer_(new char[buffer_size]), |
| 12 | buffer_size_(buffer_size), |
| 13 | buffered_bytes_(0) {} |
| 14 | |
| 15 | BufferedFileWriter::~BufferedFileWriter() {} |
| 16 | |
| 17 | int BufferedFileWriter::Open(const char* path, int flags, mode_t mode) { |
| 18 | return next_->Open(path, flags, mode); |
| 19 | } |
| 20 | |
| 21 | ssize_t BufferedFileWriter::Write(const void* bytes, size_t count) { |
| 22 | size_t copied_bytes = 0; |
| 23 | while (copied_bytes < count) { |
| 24 | // Buffers as many bytes as possible. |
| 25 | size_t remaining_free = buffer_size_ - buffered_bytes_; |
| 26 | size_t copy_bytes = count - copied_bytes; |
| 27 | if (copy_bytes > remaining_free) { |
| 28 | copy_bytes = remaining_free; |
| 29 | } |
| 30 | const char* char_bytes = reinterpret_cast<const char*>(bytes); |
| 31 | memcpy(&buffer_[buffered_bytes_], char_bytes + copied_bytes, copy_bytes); |
| 32 | buffered_bytes_ += copy_bytes; |
| 33 | copied_bytes += copy_bytes; |
| 34 | |
| 35 | // If full, sends the buffer to the next FileWriter. |
| 36 | if (buffered_bytes_ == buffer_size_) { |
| 37 | ssize_t rc = WriteBuffer(); |
| 38 | if (rc < 0) |
| 39 | return rc; |
| 40 | } |
| 41 | } |
| 42 | return count; |
| 43 | } |
| 44 | |
| 45 | int BufferedFileWriter::Close() { |
| 46 | // Flushes the buffer first, then closes the next FileWriter. |
| 47 | ssize_t rc_write = WriteBuffer(); |
| 48 | int rc_close = next_->Close(); |
| 49 | return (rc_write < 0) ? rc_write : rc_close; |
| 50 | } |
| 51 | |
| 52 | ssize_t BufferedFileWriter::WriteBuffer() { |
| 53 | if (buffered_bytes_ == 0) |
| 54 | return 0; |
| 55 | ssize_t rc = next_->Write(&buffer_[0], buffered_bytes_); |
| 56 | buffered_bytes_ = 0; |
| 57 | return rc; |
| 58 | } |
| 59 | |
| 60 | } // namespace chromeos_update_engine |