1*07fb1d06SElliott Hughes // Copyright 2017 The ChromiumOS Authors
2*07fb1d06SElliott Hughes // Use of this source code is governed by a BSD-style license that can be
3*07fb1d06SElliott Hughes // found in the LICENSE file.
4*07fb1d06SElliott Hughes
5*07fb1d06SElliott Hughes #include "puffin/memory_stream.h"
6*07fb1d06SElliott Hughes
7*07fb1d06SElliott Hughes #include <fcntl.h>
8*07fb1d06SElliott Hughes #include <unistd.h>
9*07fb1d06SElliott Hughes
10*07fb1d06SElliott Hughes #include <algorithm>
11*07fb1d06SElliott Hughes #include <utility>
12*07fb1d06SElliott Hughes
13*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/common.h"
14*07fb1d06SElliott Hughes #include "puffin/src/logging.h"
15*07fb1d06SElliott Hughes
16*07fb1d06SElliott Hughes namespace puffin {
17*07fb1d06SElliott Hughes
CreateForRead(const Buffer & memory)18*07fb1d06SElliott Hughes UniqueStreamPtr MemoryStream::CreateForRead(const Buffer& memory) {
19*07fb1d06SElliott Hughes return UniqueStreamPtr(new MemoryStream(&memory, nullptr));
20*07fb1d06SElliott Hughes }
21*07fb1d06SElliott Hughes
CreateForWrite(Buffer * memory)22*07fb1d06SElliott Hughes UniqueStreamPtr MemoryStream::CreateForWrite(Buffer* memory) {
23*07fb1d06SElliott Hughes return UniqueStreamPtr(new MemoryStream(nullptr, memory));
24*07fb1d06SElliott Hughes }
25*07fb1d06SElliott Hughes
MemoryStream(const Buffer * read_memory,Buffer * write_memory)26*07fb1d06SElliott Hughes MemoryStream::MemoryStream(const Buffer* read_memory, Buffer* write_memory)
27*07fb1d06SElliott Hughes : read_memory_(read_memory),
28*07fb1d06SElliott Hughes write_memory_(write_memory),
29*07fb1d06SElliott Hughes offset_(0),
30*07fb1d06SElliott Hughes open_(true) {}
31*07fb1d06SElliott Hughes
GetSize(uint64_t * size) const32*07fb1d06SElliott Hughes bool MemoryStream::GetSize(uint64_t* size) const {
33*07fb1d06SElliott Hughes *size =
34*07fb1d06SElliott Hughes read_memory_ != nullptr ? read_memory_->size() : write_memory_->size();
35*07fb1d06SElliott Hughes return true;
36*07fb1d06SElliott Hughes }
37*07fb1d06SElliott Hughes
GetOffset(uint64_t * offset) const38*07fb1d06SElliott Hughes bool MemoryStream::GetOffset(uint64_t* offset) const {
39*07fb1d06SElliott Hughes *offset = offset_;
40*07fb1d06SElliott Hughes return true;
41*07fb1d06SElliott Hughes }
42*07fb1d06SElliott Hughes
Seek(uint64_t offset)43*07fb1d06SElliott Hughes bool MemoryStream::Seek(uint64_t offset) {
44*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(open_);
45*07fb1d06SElliott Hughes uint64_t size;
46*07fb1d06SElliott Hughes GetSize(&size);
47*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(offset <= size);
48*07fb1d06SElliott Hughes offset_ = offset;
49*07fb1d06SElliott Hughes return true;
50*07fb1d06SElliott Hughes }
51*07fb1d06SElliott Hughes
Read(void * buffer,size_t length)52*07fb1d06SElliott Hughes bool MemoryStream::Read(void* buffer, size_t length) {
53*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(open_);
54*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(read_memory_ != nullptr);
55*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(offset_ + length <= read_memory_->size());
56*07fb1d06SElliott Hughes memcpy(buffer, read_memory_->data() + offset_, length);
57*07fb1d06SElliott Hughes offset_ += length;
58*07fb1d06SElliott Hughes return true;
59*07fb1d06SElliott Hughes }
60*07fb1d06SElliott Hughes
Write(const void * buffer,size_t length)61*07fb1d06SElliott Hughes bool MemoryStream::Write(const void* buffer, size_t length) {
62*07fb1d06SElliott Hughes // TODO(ahassani): Add a maximum size limit to prevent malicious attacks.
63*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(open_);
64*07fb1d06SElliott Hughes TEST_AND_RETURN_FALSE(write_memory_ != nullptr);
65*07fb1d06SElliott Hughes if (offset_ + length > write_memory_->size()) {
66*07fb1d06SElliott Hughes write_memory_->resize(offset_ + length);
67*07fb1d06SElliott Hughes }
68*07fb1d06SElliott Hughes memcpy(write_memory_->data() + offset_, buffer, length);
69*07fb1d06SElliott Hughes offset_ += length;
70*07fb1d06SElliott Hughes return true;
71*07fb1d06SElliott Hughes }
72*07fb1d06SElliott Hughes
Close()73*07fb1d06SElliott Hughes bool MemoryStream::Close() {
74*07fb1d06SElliott Hughes open_ = false;
75*07fb1d06SElliott Hughes return true;
76*07fb1d06SElliott Hughes }
77*07fb1d06SElliott Hughes
78*07fb1d06SElliott Hughes } // namespace puffin
79