1 // Copyright 2017 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 "puffin/src/memory_stream.h" 6 7 #include <fcntl.h> 8 #include <unistd.h> 9 10 #include <algorithm> 11 #include <utility> 12 13 #include "puffin/src/include/puffin/common.h" 14 #include "puffin/src/set_errors.h" 15 16 namespace puffin { 17 18 UniqueStreamPtr MemoryStream::CreateForRead(const Buffer& memory) { 19 return UniqueStreamPtr(new MemoryStream(&memory, nullptr)); 20 } 21 22 UniqueStreamPtr MemoryStream::CreateForWrite(Buffer* memory) { 23 return UniqueStreamPtr(new MemoryStream(nullptr, memory)); 24 } 25 26 MemoryStream::MemoryStream(const Buffer* read_memory, Buffer* write_memory) 27 : read_memory_(read_memory), 28 write_memory_(write_memory), 29 offset_(0), 30 open_(true) {} 31 32 bool MemoryStream::GetSize(uint64_t* size) const { 33 *size = 34 read_memory_ != nullptr ? read_memory_->size() : write_memory_->size(); 35 return true; 36 } 37 38 bool MemoryStream::GetOffset(uint64_t* offset) const { 39 *offset = offset_; 40 return true; 41 } 42 43 bool MemoryStream::Seek(uint64_t offset) { 44 TEST_AND_RETURN_FALSE(open_); 45 uint64_t size; 46 GetSize(&size); 47 TEST_AND_RETURN_FALSE(offset <= size); 48 offset_ = offset; 49 return true; 50 } 51 52 bool MemoryStream::Read(void* buffer, size_t length) { 53 TEST_AND_RETURN_FALSE(open_); 54 TEST_AND_RETURN_FALSE(read_memory_ != nullptr); 55 TEST_AND_RETURN_FALSE(offset_ + length <= read_memory_->size()); 56 memcpy(buffer, read_memory_->data() + offset_, length); 57 offset_ += length; 58 return true; 59 } 60 61 bool MemoryStream::Write(const void* buffer, size_t length) { 62 // TODO(ahassani): Add a maximum size limit to prevent malicious attacks. 63 TEST_AND_RETURN_FALSE(open_); 64 TEST_AND_RETURN_FALSE(write_memory_ != nullptr); 65 if (offset_ + length > write_memory_->size()) { 66 write_memory_->resize(offset_ + length); 67 } 68 memcpy(write_memory_->data() + offset_, buffer, length); 69 offset_ += length; 70 return true; 71 } 72 73 bool MemoryStream::Close() { 74 open_ = false; 75 return true; 76 } 77 78 } // namespace puffin 79