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