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/logging.h"
15
16 namespace puffin {
17
CreateForRead(const Buffer & memory)18 UniqueStreamPtr MemoryStream::CreateForRead(const Buffer& memory) {
19 return UniqueStreamPtr(new MemoryStream(&memory, nullptr));
20 }
21
CreateForWrite(Buffer * memory)22 UniqueStreamPtr MemoryStream::CreateForWrite(Buffer* memory) {
23 return UniqueStreamPtr(new MemoryStream(nullptr, memory));
24 }
25
MemoryStream(const Buffer * read_memory,Buffer * write_memory)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
GetSize(uint64_t * size) const32 bool MemoryStream::GetSize(uint64_t* size) const {
33 *size =
34 read_memory_ != nullptr ? read_memory_->size() : write_memory_->size();
35 return true;
36 }
37
GetOffset(uint64_t * offset) const38 bool MemoryStream::GetOffset(uint64_t* offset) const {
39 *offset = offset_;
40 return true;
41 }
42
Seek(uint64_t offset)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
Read(void * buffer,size_t length)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
Write(const void * buffer,size_t length)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
Close()73 bool MemoryStream::Close() {
74 open_ = false;
75 return true;
76 }
77
78 } // namespace puffin
79