Line data Source code
1 : /*
2 : * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/base/bytebuffer.h"
12 :
13 : #include <string.h>
14 :
15 : #include <algorithm>
16 :
17 : #include "webrtc/base/basictypes.h"
18 : #include "webrtc/base/byteorder.h"
19 :
20 : namespace rtc {
21 :
22 : static const int DEFAULT_SIZE = 4096;
23 :
24 0 : ByteBufferWriter::ByteBufferWriter()
25 0 : : ByteBuffer(ORDER_NETWORK) {
26 0 : Construct(NULL, DEFAULT_SIZE);
27 0 : }
28 :
29 0 : ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
30 0 : : ByteBuffer(byte_order) {
31 0 : Construct(NULL, DEFAULT_SIZE);
32 0 : }
33 :
34 0 : ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
35 0 : : ByteBuffer(ORDER_NETWORK) {
36 0 : Construct(bytes, len);
37 0 : }
38 :
39 0 : ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len,
40 0 : ByteOrder byte_order)
41 0 : : ByteBuffer(byte_order) {
42 0 : Construct(bytes, len);
43 0 : }
44 :
45 0 : void ByteBufferWriter::Construct(const char* bytes, size_t len) {
46 0 : size_ = len;
47 0 : bytes_ = new char[size_];
48 :
49 0 : if (bytes) {
50 0 : end_ = len;
51 0 : memcpy(bytes_, bytes, end_);
52 : } else {
53 0 : end_ = 0;
54 : }
55 0 : }
56 :
57 0 : ByteBufferWriter::~ByteBufferWriter() {
58 0 : delete[] bytes_;
59 0 : }
60 :
61 0 : void ByteBufferWriter::WriteUInt8(uint8_t val) {
62 0 : WriteBytes(reinterpret_cast<const char*>(&val), 1);
63 0 : }
64 :
65 0 : void ByteBufferWriter::WriteUInt16(uint16_t val) {
66 0 : uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
67 0 : WriteBytes(reinterpret_cast<const char*>(&v), 2);
68 0 : }
69 :
70 0 : void ByteBufferWriter::WriteUInt24(uint32_t val) {
71 0 : uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
72 0 : char* start = reinterpret_cast<char*>(&v);
73 0 : if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
74 0 : ++start;
75 : }
76 0 : WriteBytes(start, 3);
77 0 : }
78 :
79 0 : void ByteBufferWriter::WriteUInt32(uint32_t val) {
80 0 : uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
81 0 : WriteBytes(reinterpret_cast<const char*>(&v), 4);
82 0 : }
83 :
84 0 : void ByteBufferWriter::WriteUInt64(uint64_t val) {
85 0 : uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
86 0 : WriteBytes(reinterpret_cast<const char*>(&v), 8);
87 0 : }
88 :
89 : // Serializes an unsigned varint in the format described by
90 : // https://developers.google.com/protocol-buffers/docs/encoding#varints
91 : // with the caveat that integers are 64-bit, not 128-bit.
92 0 : void ByteBufferWriter::WriteUVarint(uint64_t val) {
93 0 : while (val >= 0x80) {
94 : // Write 7 bits at a time, then set the msb to a continuation byte (msb=1).
95 0 : char byte = static_cast<char>(val) | 0x80;
96 0 : WriteBytes(&byte, 1);
97 0 : val >>= 7;
98 : }
99 0 : char last_byte = static_cast<char>(val);
100 0 : WriteBytes(&last_byte, 1);
101 0 : }
102 :
103 0 : void ByteBufferWriter::WriteString(const std::string& val) {
104 0 : WriteBytes(val.c_str(), val.size());
105 0 : }
106 :
107 0 : void ByteBufferWriter::WriteBytes(const char* val, size_t len) {
108 0 : memcpy(ReserveWriteBuffer(len), val, len);
109 0 : }
110 :
111 0 : char* ByteBufferWriter::ReserveWriteBuffer(size_t len) {
112 0 : if (Length() + len > Capacity())
113 0 : Resize(Length() + len);
114 :
115 0 : char* start = bytes_ + end_;
116 0 : end_ += len;
117 0 : return start;
118 : }
119 :
120 0 : void ByteBufferWriter::Resize(size_t size) {
121 0 : size_t len = std::min(end_, size);
122 0 : if (size > size_) {
123 : // Reallocate a larger buffer.
124 0 : size_ = std::max(size, 3 * size_ / 2);
125 0 : char* new_bytes = new char[size_];
126 0 : memcpy(new_bytes, bytes_, len);
127 0 : delete [] bytes_;
128 0 : bytes_ = new_bytes;
129 : }
130 0 : end_ = len;
131 0 : }
132 :
133 0 : void ByteBufferWriter::Clear() {
134 0 : memset(bytes_, 0, size_);
135 0 : end_ = 0;
136 0 : }
137 :
138 :
139 0 : ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
140 0 : : ByteBuffer(ORDER_NETWORK) {
141 0 : Construct(bytes, len);
142 0 : }
143 :
144 0 : ByteBufferReader::ByteBufferReader(const char* bytes, size_t len,
145 0 : ByteOrder byte_order)
146 0 : : ByteBuffer(byte_order) {
147 0 : Construct(bytes, len);
148 0 : }
149 :
150 0 : ByteBufferReader::ByteBufferReader(const char* bytes)
151 0 : : ByteBuffer(ORDER_NETWORK) {
152 0 : Construct(bytes, strlen(bytes));
153 0 : }
154 :
155 0 : ByteBufferReader::ByteBufferReader(const Buffer& buf)
156 0 : : ByteBuffer(ORDER_NETWORK) {
157 0 : Construct(buf.data<char>(), buf.size());
158 0 : }
159 :
160 0 : ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
161 0 : : ByteBuffer(buf.Order()) {
162 0 : Construct(buf.Data(), buf.Length());
163 0 : }
164 :
165 0 : void ByteBufferReader::Construct(const char* bytes, size_t len) {
166 0 : bytes_ = bytes;
167 0 : size_ = len;
168 0 : start_ = 0;
169 0 : end_ = len;
170 0 : }
171 :
172 0 : bool ByteBufferReader::ReadUInt8(uint8_t* val) {
173 0 : if (!val) return false;
174 :
175 0 : return ReadBytes(reinterpret_cast<char*>(val), 1);
176 : }
177 :
178 0 : bool ByteBufferReader::ReadUInt16(uint16_t* val) {
179 0 : if (!val) return false;
180 :
181 : uint16_t v;
182 0 : if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
183 0 : return false;
184 : } else {
185 0 : *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
186 0 : return true;
187 : }
188 : }
189 :
190 0 : bool ByteBufferReader::ReadUInt24(uint32_t* val) {
191 0 : if (!val) return false;
192 :
193 0 : uint32_t v = 0;
194 0 : char* read_into = reinterpret_cast<char*>(&v);
195 0 : if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
196 0 : ++read_into;
197 : }
198 :
199 0 : if (!ReadBytes(read_into, 3)) {
200 0 : return false;
201 : } else {
202 0 : *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
203 0 : return true;
204 : }
205 : }
206 :
207 0 : bool ByteBufferReader::ReadUInt32(uint32_t* val) {
208 0 : if (!val) return false;
209 :
210 : uint32_t v;
211 0 : if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
212 0 : return false;
213 : } else {
214 0 : *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
215 0 : return true;
216 : }
217 : }
218 :
219 0 : bool ByteBufferReader::ReadUInt64(uint64_t* val) {
220 0 : if (!val) return false;
221 :
222 : uint64_t v;
223 0 : if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
224 0 : return false;
225 : } else {
226 0 : *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
227 0 : return true;
228 : }
229 : }
230 :
231 0 : bool ByteBufferReader::ReadUVarint(uint64_t* val) {
232 0 : if (!val) {
233 0 : return false;
234 : }
235 : // Integers are deserialized 7 bits at a time, with each byte having a
236 : // continuation byte (msb=1) if there are more bytes to be read.
237 0 : uint64_t v = 0;
238 0 : for (int i = 0; i < 64; i += 7) {
239 : char byte;
240 0 : if (!ReadBytes(&byte, 1)) {
241 0 : return false;
242 : }
243 : // Read the first 7 bits of the byte, then offset by bits read so far.
244 0 : v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
245 : // True if the msb is not a continuation byte.
246 0 : if (static_cast<uint64_t>(byte) < 0x80) {
247 0 : *val = v;
248 0 : return true;
249 : }
250 : }
251 0 : return false;
252 : }
253 :
254 0 : bool ByteBufferReader::ReadString(std::string* val, size_t len) {
255 0 : if (!val) return false;
256 :
257 0 : if (len > Length()) {
258 0 : return false;
259 : } else {
260 0 : val->append(bytes_ + start_, len);
261 0 : start_ += len;
262 0 : return true;
263 : }
264 : }
265 :
266 0 : bool ByteBufferReader::ReadBytes(char* val, size_t len) {
267 0 : if (len > Length()) {
268 0 : return false;
269 : } else {
270 0 : memcpy(val, bytes_ + start_, len);
271 0 : start_ += len;
272 0 : return true;
273 : }
274 : }
275 :
276 0 : bool ByteBufferReader::Consume(size_t size) {
277 0 : if (size > Length())
278 0 : return false;
279 0 : start_ += size;
280 0 : return true;
281 : }
282 :
283 : } // namespace rtc
|