1 : // Copyright 2016 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/common/binary_stream.h"
16 :
17 : #include "base/logging.h"
18 :
19 : namespace common {
20 :
21 : namespace {
22 :
23 : template <typename StringType>
24 E : bool ReadStringImpl(const BinaryStreamParser* reader, StringType* str) {
25 E : DCHECK_NE(static_cast<StringType*>(nullptr), str);
26 E : DCHECK_NE(static_cast<BinaryStreamParser*>(nullptr), reader);
27 E : str->clear();
28 :
29 E : while (true) {
30 : StringType::value_type chr;
31 E : if (!reader->Read(&chr))
32 E : return false;
33 :
34 E : if (chr == '\0')
35 E : return true;
36 :
37 E : str->push_back(chr);
38 E : }
39 E : }
40 :
41 : } // namespace
42 :
43 : BinaryBufferStreamReader::BinaryBufferStreamReader(const void* data, size_t len)
44 E : : data_(reinterpret_cast<const uint8_t*>(data)), pos_(0), len_(len) {
45 E : }
46 :
47 : BinaryBufferStreamReader::BinaryBufferStreamReader(
48 : const base::StringPiece& data)
49 E : : data_(reinterpret_cast<const uint8_t*>(data.data())),
50 E : pos_(0),
51 E : len_(data.length()) {
52 E : }
53 :
54 E : bool BinaryBufferStreamReader::Read(size_t len, void* out) {
55 E : DCHECK(IsValid());
56 :
57 E : if (bytes_remaining() < len)
58 E : return false;
59 :
60 E : DCHECK_GE(bytes_remaining(), len);
61 :
62 E : ::memcpy(out, data_ + pos_, len);
63 E : pos_ += len;
64 :
65 E : return true;
66 E : }
67 :
68 E : size_t BinaryBufferStreamReader::Position() const {
69 E : return pos_;
70 E : }
71 :
72 E : bool BinaryBufferStreamReader::AtEnd() const {
73 E : return bytes_remaining() == 0;
74 E : }
75 :
76 E : bool BinaryBufferStreamReader::IsValid() {
77 E : if (data_ == nullptr && bytes_remaining() != 0)
78 i : return false;
79 :
80 E : return true;
81 E : }
82 :
83 : BinaryVectorStreamReader::BinaryVectorStreamReader(std::vector<uint8_t>* data)
84 E : : position_(0U), data_(data) {
85 E : DCHECK(data);
86 E : }
87 :
88 E : bool BinaryVectorStreamReader::Read(size_t len, void* out) {
89 E : DCHECK(len == 0 || out != nullptr);
90 E : DCHECK(data_);
91 :
92 E : if (data_->size() < position_ + len)
93 E : return false;
94 :
95 E : ::memcpy(out, &data_->at(position_), len);
96 E : position_ += len;
97 :
98 E : return true;
99 E : }
100 :
101 i : size_t BinaryVectorStreamReader::Position() const {
102 i : return position_;
103 i : }
104 :
105 i : bool BinaryVectorStreamReader::AtEnd() const {
106 : // Cater for the case where the vector shrinks from under the reader.
107 i : return position_ >= data_->size();
108 i : }
109 :
110 : BinaryStreamParser::BinaryStreamParser(BinaryStreamReader* stream_reader)
111 E : : stream_reader_(stream_reader) {
112 E : }
113 :
114 E : bool BinaryStreamParser::ReadBytes(size_t len, void* out) const {
115 E : DCHECK_NE(static_cast<void*>(nullptr), out);
116 :
117 E : return stream_reader_->Read(len, out);
118 E : }
119 :
120 E : bool BinaryStreamParser::ReadString(std::string* str) const {
121 E : return ReadStringImpl(this, str);
122 E : }
123 :
124 E : bool BinaryStreamParser::ReadString(std::wstring* str) const {
125 E : return ReadStringImpl(this, str);
126 E : }
127 :
128 E : bool BinaryStreamParser::AlignTo(size_t alignment) const {
129 E : const size_t remainder = stream_reader_->Position() % alignment;
130 E : if (remainder == 0)
131 E : return true;
132 :
133 E : size_t to_read = alignment - remainder;
134 E : for (size_t i = 0; i != to_read; ++i) {
135 E : uint8_t discard = 0;
136 E : if (!stream_reader_->Read(sizeof(discard), &discard))
137 E : return false;
138 E : }
139 :
140 E : return true;
141 E : }
142 :
143 : } // namespace common
|