blob: c2ffe609341fbb74339d2c2101cfc298741bf342 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013#include <string.h>
14
15#include <algorithm>
16
17#include "webrtc/base/basictypes.h"
18#include "webrtc/base/byteorder.h"
19
20namespace rtc {
21
22static const int DEFAULT_SIZE = 4096;
23
jbauchf1f87202016-03-30 06:43:37 -070024ByteBufferWriter::ByteBufferWriter()
25 : ByteBuffer(ORDER_NETWORK) {
26 Construct(NULL, DEFAULT_SIZE);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000027}
28
jbauchf1f87202016-03-30 06:43:37 -070029ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
30 : ByteBuffer(byte_order) {
31 Construct(NULL, DEFAULT_SIZE);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032}
33
jbauchf1f87202016-03-30 06:43:37 -070034ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
35 : ByteBuffer(ORDER_NETWORK) {
36 Construct(bytes, len);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000037}
38
jbauchf1f87202016-03-30 06:43:37 -070039ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len,
40 ByteOrder byte_order)
41 : ByteBuffer(byte_order) {
42 Construct(bytes, len);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000043}
44
jbauchf1f87202016-03-30 06:43:37 -070045void ByteBufferWriter::Construct(const char* bytes, size_t len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000046 start_ = 0;
47 size_ = len;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000048 bytes_ = new char[size_];
49
50 if (bytes) {
51 end_ = len;
52 memcpy(bytes_, bytes, end_);
53 } else {
54 end_ = 0;
55 }
56}
57
jbauchf1f87202016-03-30 06:43:37 -070058ByteBufferWriter::~ByteBufferWriter() {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000059 delete[] bytes_;
60}
61
jbauchf1f87202016-03-30 06:43:37 -070062void ByteBufferWriter::WriteUInt8(uint8_t val) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000063 WriteBytes(reinterpret_cast<const char*>(&val), 1);
64}
65
jbauchf1f87202016-03-30 06:43:37 -070066void ByteBufferWriter::WriteUInt16(uint16_t val) {
67 uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000068 WriteBytes(reinterpret_cast<const char*>(&v), 2);
69}
70
jbauchf1f87202016-03-30 06:43:37 -070071void ByteBufferWriter::WriteUInt24(uint32_t val) {
72 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000073 char* start = reinterpret_cast<char*>(&v);
jbauchf1f87202016-03-30 06:43:37 -070074 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000075 ++start;
76 }
77 WriteBytes(start, 3);
78}
79
jbauchf1f87202016-03-30 06:43:37 -070080void ByteBufferWriter::WriteUInt32(uint32_t val) {
81 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000082 WriteBytes(reinterpret_cast<const char*>(&v), 4);
83}
84
jbauchf1f87202016-03-30 06:43:37 -070085void ByteBufferWriter::WriteUInt64(uint64_t val) {
86 uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000087 WriteBytes(reinterpret_cast<const char*>(&v), 8);
88}
89
mikescarlett9a20fa62016-04-11 16:11:38 -070090// Serializes an unsigned varint in the format described by
91// https://developers.google.com/protocol-buffers/docs/encoding#varints
92// with the caveat that integers are 64-bit, not 128-bit.
93void ByteBufferWriter::WriteUVarint(uint64_t val) {
94 while (val >= 0x80) {
95 // Write 7 bits at a time, then set the msb to a continuation byte (msb=1).
96 char byte = static_cast<char>(val) | 0x80;
97 WriteBytes(&byte, 1);
98 val >>= 7;
99 }
100 char last_byte = static_cast<char>(val);
101 WriteBytes(&last_byte, 1);
102}
103
jbauchf1f87202016-03-30 06:43:37 -0700104void ByteBufferWriter::WriteString(const std::string& val) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000105 WriteBytes(val.c_str(), val.size());
106}
107
jbauchf1f87202016-03-30 06:43:37 -0700108void ByteBufferWriter::WriteBytes(const char* val, size_t len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000109 memcpy(ReserveWriteBuffer(len), val, len);
110}
111
jbauchf1f87202016-03-30 06:43:37 -0700112char* ByteBufferWriter::ReserveWriteBuffer(size_t len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000113 if (Length() + len > Capacity())
114 Resize(Length() + len);
115
116 char* start = bytes_ + end_;
117 end_ += len;
118 return start;
119}
120
jbauchf1f87202016-03-30 06:43:37 -0700121void ByteBufferWriter::Resize(size_t size) {
andresp@webrtc.orgff689be2015-02-12 11:54:26 +0000122 size_t len = std::min(end_ - start_, size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000123 if (size <= size_) {
124 // Don't reallocate, just move data backwards
125 memmove(bytes_, bytes_ + start_, len);
126 } else {
127 // Reallocate a larger buffer.
andresp@webrtc.orgff689be2015-02-12 11:54:26 +0000128 size_ = std::max(size, 3 * size_ / 2);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000129 char* new_bytes = new char[size_];
130 memcpy(new_bytes, bytes_ + start_, len);
131 delete [] bytes_;
132 bytes_ = new_bytes;
133 }
134 start_ = 0;
135 end_ = len;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000136}
137
jbauchf1f87202016-03-30 06:43:37 -0700138void ByteBufferWriter::Clear() {
139 memset(bytes_, 0, size_);
140 start_ = end_ = 0;
141}
142
143
144ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
145 : ByteBuffer(ORDER_NETWORK) {
146 Construct(bytes, len);
147}
148
149ByteBufferReader::ByteBufferReader(const char* bytes, size_t len,
150 ByteOrder byte_order)
151 : ByteBuffer(byte_order) {
152 Construct(bytes, len);
153}
154
155ByteBufferReader::ByteBufferReader(const char* bytes)
156 : ByteBuffer(ORDER_NETWORK) {
157 Construct(bytes, strlen(bytes));
158}
159
160ByteBufferReader::ByteBufferReader(const Buffer& buf)
161 : ByteBuffer(ORDER_NETWORK) {
162 Construct(buf.data<char>(), buf.size());
163}
164
165ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
166 : ByteBuffer(buf.Order()) {
167 Construct(buf.Data(), buf.Length());
168}
169
170void ByteBufferReader::Construct(const char* bytes, size_t len) {
171 bytes_ = bytes;
172 size_ = len;
173 start_ = 0;
174 end_ = len;
175}
176
177bool ByteBufferReader::ReadUInt8(uint8_t* val) {
178 if (!val) return false;
179
180 return ReadBytes(reinterpret_cast<char*>(val), 1);
181}
182
183bool ByteBufferReader::ReadUInt16(uint16_t* val) {
184 if (!val) return false;
185
186 uint16_t v;
187 if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
188 return false;
189 } else {
190 *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
191 return true;
192 }
193}
194
195bool ByteBufferReader::ReadUInt24(uint32_t* val) {
196 if (!val) return false;
197
198 uint32_t v = 0;
199 char* read_into = reinterpret_cast<char*>(&v);
200 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
201 ++read_into;
202 }
203
204 if (!ReadBytes(read_into, 3)) {
205 return false;
206 } else {
207 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
208 return true;
209 }
210}
211
212bool ByteBufferReader::ReadUInt32(uint32_t* val) {
213 if (!val) return false;
214
215 uint32_t v;
216 if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
217 return false;
218 } else {
219 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
220 return true;
221 }
222}
223
224bool ByteBufferReader::ReadUInt64(uint64_t* val) {
225 if (!val) return false;
226
227 uint64_t v;
228 if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
229 return false;
230 } else {
231 *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
232 return true;
233 }
234}
235
mikescarlett9a20fa62016-04-11 16:11:38 -0700236bool ByteBufferReader::ReadUVarint(uint64_t* val) {
237 if (!val) {
238 return false;
239 }
240 // Integers are deserialized 7 bits at a time, with each byte having a
241 // continuation byte (msb=1) if there are more bytes to be read.
242 uint64_t v = 0;
243 for (int i = 0; i < 64; i += 7) {
244 char byte;
245 if (!ReadBytes(&byte, 1)) {
246 return false;
247 }
248 // Read the first 7 bits of the byte, then offset by bits read so far.
249 v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
250 // True if the msb is not a continuation byte.
251 if (static_cast<uint64_t>(byte) < 0x80) {
252 *val = v;
253 return true;
254 }
255 }
256 return false;
257}
258
jbauchf1f87202016-03-30 06:43:37 -0700259bool ByteBufferReader::ReadString(std::string* val, size_t len) {
260 if (!val) return false;
261
262 if (len > Length()) {
263 return false;
264 } else {
265 val->append(bytes_ + start_, len);
266 start_ += len;
267 return true;
268 }
269}
270
271bool ByteBufferReader::ReadBytes(char* val, size_t len) {
272 if (len > Length()) {
273 return false;
274 } else {
275 memcpy(val, bytes_ + start_, len);
276 start_ += len;
277 return true;
278 }
279}
280
281bool ByteBufferReader::Consume(size_t size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000282 if (size > Length())
283 return false;
284 start_ += size;
285 return true;
286}
287
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000288} // namespace rtc