Home | History | Annotate | Download | only in src
      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