blob: 9730ff23d6787ca7e555d1aa2a5f8c0878aa6552 [file] [log] [blame]
henrike@webrtc.org47be73b2014-05-13 18:00:261/*
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 <assert.h>
14#include <string.h>
15
16#include <algorithm>
17
18#include "webrtc/base/basictypes.h"
19#include "webrtc/base/byteorder.h"
20
21namespace rtc {
22
23static const int DEFAULT_SIZE = 4096;
24
jbauchca09a4b2016-03-30 13:43:3725ByteBufferWriter::ByteBufferWriter()
26 : ByteBuffer(ORDER_NETWORK) {
27 Construct(NULL, DEFAULT_SIZE);
henrike@webrtc.org47be73b2014-05-13 18:00:2628}
29
jbauchca09a4b2016-03-30 13:43:3730ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
31 : ByteBuffer(byte_order) {
32 Construct(NULL, DEFAULT_SIZE);
henrike@webrtc.org47be73b2014-05-13 18:00:2633}
34
jbauchca09a4b2016-03-30 13:43:3735ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
36 : ByteBuffer(ORDER_NETWORK) {
37 Construct(bytes, len);
henrike@webrtc.org47be73b2014-05-13 18:00:2638}
39
jbauchca09a4b2016-03-30 13:43:3740ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len,
41 ByteOrder byte_order)
42 : ByteBuffer(byte_order) {
43 Construct(bytes, len);
henrike@webrtc.org47be73b2014-05-13 18:00:2644}
45
jbauchca09a4b2016-03-30 13:43:3746void ByteBufferWriter::Construct(const char* bytes, size_t len) {
henrike@webrtc.org47be73b2014-05-13 18:00:2647 start_ = 0;
48 size_ = len;
henrike@webrtc.org47be73b2014-05-13 18:00:2649 bytes_ = new char[size_];
50
51 if (bytes) {
52 end_ = len;
53 memcpy(bytes_, bytes, end_);
54 } else {
55 end_ = 0;
56 }
57}
58
jbauchca09a4b2016-03-30 13:43:3759ByteBufferWriter::~ByteBufferWriter() {
henrike@webrtc.org47be73b2014-05-13 18:00:2660 delete[] bytes_;
61}
62
jbauchca09a4b2016-03-30 13:43:3763void ByteBufferWriter::WriteUInt8(uint8_t val) {
henrike@webrtc.org47be73b2014-05-13 18:00:2664 WriteBytes(reinterpret_cast<const char*>(&val), 1);
65}
66
jbauchca09a4b2016-03-30 13:43:3767void ByteBufferWriter::WriteUInt16(uint16_t val) {
68 uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
henrike@webrtc.org47be73b2014-05-13 18:00:2669 WriteBytes(reinterpret_cast<const char*>(&v), 2);
70}
71
jbauchca09a4b2016-03-30 13:43:3772void ByteBufferWriter::WriteUInt24(uint32_t val) {
73 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
henrike@webrtc.org47be73b2014-05-13 18:00:2674 char* start = reinterpret_cast<char*>(&v);
jbauchca09a4b2016-03-30 13:43:3775 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
henrike@webrtc.org47be73b2014-05-13 18:00:2676 ++start;
77 }
78 WriteBytes(start, 3);
79}
80
jbauchca09a4b2016-03-30 13:43:3781void ByteBufferWriter::WriteUInt32(uint32_t val) {
82 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
henrike@webrtc.org47be73b2014-05-13 18:00:2683 WriteBytes(reinterpret_cast<const char*>(&v), 4);
84}
85
jbauchca09a4b2016-03-30 13:43:3786void ByteBufferWriter::WriteUInt64(uint64_t val) {
87 uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
henrike@webrtc.org47be73b2014-05-13 18:00:2688 WriteBytes(reinterpret_cast<const char*>(&v), 8);
89}
90
mikescarlett6cd73eb2016-04-11 23:11:3891// Serializes an unsigned varint in the format described by
92// https://developers.google.com/protocol-buffers/docs/encoding#varints
93// with the caveat that integers are 64-bit, not 128-bit.
94void ByteBufferWriter::WriteUVarint(uint64_t val) {
95 while (val >= 0x80) {
96 // Write 7 bits at a time, then set the msb to a continuation byte (msb=1).
97 char byte = static_cast<char>(val) | 0x80;
98 WriteBytes(&byte, 1);
99 val >>= 7;
100 }
101 char last_byte = static_cast<char>(val);
102 WriteBytes(&last_byte, 1);
103}
104
jbauchca09a4b2016-03-30 13:43:37105void ByteBufferWriter::WriteString(const std::string& val) {
henrike@webrtc.org47be73b2014-05-13 18:00:26106 WriteBytes(val.c_str(), val.size());
107}
108
jbauchca09a4b2016-03-30 13:43:37109void ByteBufferWriter::WriteBytes(const char* val, size_t len) {
henrike@webrtc.org47be73b2014-05-13 18:00:26110 memcpy(ReserveWriteBuffer(len), val, len);
111}
112
jbauchca09a4b2016-03-30 13:43:37113char* ByteBufferWriter::ReserveWriteBuffer(size_t len) {
henrike@webrtc.org47be73b2014-05-13 18:00:26114 if (Length() + len > Capacity())
115 Resize(Length() + len);
116
117 char* start = bytes_ + end_;
118 end_ += len;
119 return start;
120}
121
jbauchca09a4b2016-03-30 13:43:37122void ByteBufferWriter::Resize(size_t size) {
andresp@webrtc.orgf35e2aa2015-02-12 11:54:26123 size_t len = std::min(end_ - start_, size);
henrike@webrtc.org47be73b2014-05-13 18:00:26124 if (size <= size_) {
125 // Don't reallocate, just move data backwards
126 memmove(bytes_, bytes_ + start_, len);
127 } else {
128 // Reallocate a larger buffer.
andresp@webrtc.orgf35e2aa2015-02-12 11:54:26129 size_ = std::max(size, 3 * size_ / 2);
henrike@webrtc.org47be73b2014-05-13 18:00:26130 char* new_bytes = new char[size_];
131 memcpy(new_bytes, bytes_ + start_, len);
132 delete [] bytes_;
133 bytes_ = new_bytes;
134 }
135 start_ = 0;
136 end_ = len;
henrike@webrtc.org47be73b2014-05-13 18:00:26137}
138
jbauchca09a4b2016-03-30 13:43:37139void ByteBufferWriter::Clear() {
140 memset(bytes_, 0, size_);
141 start_ = end_ = 0;
142}
143
144
145ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
146 : ByteBuffer(ORDER_NETWORK) {
147 Construct(bytes, len);
148}
149
150ByteBufferReader::ByteBufferReader(const char* bytes, size_t len,
151 ByteOrder byte_order)
152 : ByteBuffer(byte_order) {
153 Construct(bytes, len);
154}
155
156ByteBufferReader::ByteBufferReader(const char* bytes)
157 : ByteBuffer(ORDER_NETWORK) {
158 Construct(bytes, strlen(bytes));
159}
160
161ByteBufferReader::ByteBufferReader(const Buffer& buf)
162 : ByteBuffer(ORDER_NETWORK) {
163 Construct(buf.data<char>(), buf.size());
164}
165
166ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
167 : ByteBuffer(buf.Order()) {
168 Construct(buf.Data(), buf.Length());
169}
170
171void ByteBufferReader::Construct(const char* bytes, size_t len) {
172 bytes_ = bytes;
173 size_ = len;
174 start_ = 0;
175 end_ = len;
176}
177
178bool ByteBufferReader::ReadUInt8(uint8_t* val) {
179 if (!val) return false;
180
181 return ReadBytes(reinterpret_cast<char*>(val), 1);
182}
183
184bool ByteBufferReader::ReadUInt16(uint16_t* val) {
185 if (!val) return false;
186
187 uint16_t v;
188 if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
189 return false;
190 } else {
191 *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
192 return true;
193 }
194}
195
196bool ByteBufferReader::ReadUInt24(uint32_t* val) {
197 if (!val) return false;
198
199 uint32_t v = 0;
200 char* read_into = reinterpret_cast<char*>(&v);
201 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
202 ++read_into;
203 }
204
205 if (!ReadBytes(read_into, 3)) {
206 return false;
207 } else {
208 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
209 return true;
210 }
211}
212
213bool ByteBufferReader::ReadUInt32(uint32_t* val) {
214 if (!val) return false;
215
216 uint32_t v;
217 if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
218 return false;
219 } else {
220 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
221 return true;
222 }
223}
224
225bool ByteBufferReader::ReadUInt64(uint64_t* val) {
226 if (!val) return false;
227
228 uint64_t v;
229 if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
230 return false;
231 } else {
232 *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
233 return true;
234 }
235}
236
mikescarlett6cd73eb2016-04-11 23:11:38237bool ByteBufferReader::ReadUVarint(uint64_t* val) {
238 if (!val) {
239 return false;
240 }
241 // Integers are deserialized 7 bits at a time, with each byte having a
242 // continuation byte (msb=1) if there are more bytes to be read.
243 uint64_t v = 0;
244 for (int i = 0; i < 64; i += 7) {
245 char byte;
246 if (!ReadBytes(&byte, 1)) {
247 return false;
248 }
249 // Read the first 7 bits of the byte, then offset by bits read so far.
250 v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
251 // True if the msb is not a continuation byte.
252 if (static_cast<uint64_t>(byte) < 0x80) {
253 *val = v;
254 return true;
255 }
256 }
257 return false;
258}
259
jbauchca09a4b2016-03-30 13:43:37260bool ByteBufferReader::ReadString(std::string* val, size_t len) {
261 if (!val) return false;
262
263 if (len > Length()) {
264 return false;
265 } else {
266 val->append(bytes_ + start_, len);
267 start_ += len;
268 return true;
269 }
270}
271
272bool ByteBufferReader::ReadBytes(char* val, size_t len) {
273 if (len > Length()) {
274 return false;
275 } else {
276 memcpy(val, bytes_ + start_, len);
277 start_ += len;
278 return true;
279 }
280}
281
282bool ByteBufferReader::Consume(size_t size) {
henrike@webrtc.org47be73b2014-05-13 18:00:26283 if (size > Length())
284 return false;
285 start_ += size;
286 return true;
287}
288
henrike@webrtc.org47be73b2014-05-13 18:00:26289} // namespace rtc