blob: cf4ce42574e959e8df76c23b6b6b37e45b1b94fc [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
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
jbauchf1f87202016-03-30 06:43:37 -070025ByteBufferWriter::ByteBufferWriter()
26 : ByteBuffer(ORDER_NETWORK) {
27 Construct(NULL, DEFAULT_SIZE);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000028}
29
jbauchf1f87202016-03-30 06:43:37 -070030ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
31 : ByteBuffer(byte_order) {
32 Construct(NULL, DEFAULT_SIZE);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000033}
34
jbauchf1f87202016-03-30 06:43:37 -070035ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
36 : ByteBuffer(ORDER_NETWORK) {
37 Construct(bytes, len);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000038}
39
jbauchf1f87202016-03-30 06:43:37 -070040ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len,
41 ByteOrder byte_order)
42 : ByteBuffer(byte_order) {
43 Construct(bytes, len);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000044}
45
jbauchf1f87202016-03-30 06:43:37 -070046void ByteBufferWriter::Construct(const char* bytes, size_t len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047 start_ = 0;
48 size_ = len;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000049 bytes_ = new char[size_];
50
51 if (bytes) {
52 end_ = len;
53 memcpy(bytes_, bytes, end_);
54 } else {
55 end_ = 0;
56 }
57}
58
jbauchf1f87202016-03-30 06:43:37 -070059ByteBufferWriter::~ByteBufferWriter() {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000060 delete[] bytes_;
61}
62
jbauchf1f87202016-03-30 06:43:37 -070063void ByteBufferWriter::WriteUInt8(uint8_t val) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000064 WriteBytes(reinterpret_cast<const char*>(&val), 1);
65}
66
jbauchf1f87202016-03-30 06:43:37 -070067void ByteBufferWriter::WriteUInt16(uint16_t val) {
68 uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000069 WriteBytes(reinterpret_cast<const char*>(&v), 2);
70}
71
jbauchf1f87202016-03-30 06:43:37 -070072void ByteBufferWriter::WriteUInt24(uint32_t val) {
73 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000074 char* start = reinterpret_cast<char*>(&v);
jbauchf1f87202016-03-30 06:43:37 -070075 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000076 ++start;
77 }
78 WriteBytes(start, 3);
79}
80
jbauchf1f87202016-03-30 06:43:37 -070081void ByteBufferWriter::WriteUInt32(uint32_t val) {
82 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000083 WriteBytes(reinterpret_cast<const char*>(&v), 4);
84}
85
jbauchf1f87202016-03-30 06:43:37 -070086void ByteBufferWriter::WriteUInt64(uint64_t val) {
87 uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000088 WriteBytes(reinterpret_cast<const char*>(&v), 8);
89}
90
jbauchf1f87202016-03-30 06:43:37 -070091void ByteBufferWriter::WriteString(const std::string& val) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000092 WriteBytes(val.c_str(), val.size());
93}
94
jbauchf1f87202016-03-30 06:43:37 -070095void ByteBufferWriter::WriteBytes(const char* val, size_t len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000096 memcpy(ReserveWriteBuffer(len), val, len);
97}
98
jbauchf1f87202016-03-30 06:43:37 -070099char* ByteBufferWriter::ReserveWriteBuffer(size_t len) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000100 if (Length() + len > Capacity())
101 Resize(Length() + len);
102
103 char* start = bytes_ + end_;
104 end_ += len;
105 return start;
106}
107
jbauchf1f87202016-03-30 06:43:37 -0700108void ByteBufferWriter::Resize(size_t size) {
andresp@webrtc.orgff689be2015-02-12 11:54:26 +0000109 size_t len = std::min(end_ - start_, size);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000110 if (size <= size_) {
111 // Don't reallocate, just move data backwards
112 memmove(bytes_, bytes_ + start_, len);
113 } else {
114 // Reallocate a larger buffer.
andresp@webrtc.orgff689be2015-02-12 11:54:26 +0000115 size_ = std::max(size, 3 * size_ / 2);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000116 char* new_bytes = new char[size_];
117 memcpy(new_bytes, bytes_ + start_, len);
118 delete [] bytes_;
119 bytes_ = new_bytes;
120 }
121 start_ = 0;
122 end_ = len;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000123}
124
jbauchf1f87202016-03-30 06:43:37 -0700125void ByteBufferWriter::Clear() {
126 memset(bytes_, 0, size_);
127 start_ = end_ = 0;
128}
129
130
131ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
132 : ByteBuffer(ORDER_NETWORK) {
133 Construct(bytes, len);
134}
135
136ByteBufferReader::ByteBufferReader(const char* bytes, size_t len,
137 ByteOrder byte_order)
138 : ByteBuffer(byte_order) {
139 Construct(bytes, len);
140}
141
142ByteBufferReader::ByteBufferReader(const char* bytes)
143 : ByteBuffer(ORDER_NETWORK) {
144 Construct(bytes, strlen(bytes));
145}
146
147ByteBufferReader::ByteBufferReader(const Buffer& buf)
148 : ByteBuffer(ORDER_NETWORK) {
149 Construct(buf.data<char>(), buf.size());
150}
151
152ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
153 : ByteBuffer(buf.Order()) {
154 Construct(buf.Data(), buf.Length());
155}
156
157void ByteBufferReader::Construct(const char* bytes, size_t len) {
158 bytes_ = bytes;
159 size_ = len;
160 start_ = 0;
161 end_ = len;
162}
163
164bool ByteBufferReader::ReadUInt8(uint8_t* val) {
165 if (!val) return false;
166
167 return ReadBytes(reinterpret_cast<char*>(val), 1);
168}
169
170bool ByteBufferReader::ReadUInt16(uint16_t* val) {
171 if (!val) return false;
172
173 uint16_t v;
174 if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
175 return false;
176 } else {
177 *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
178 return true;
179 }
180}
181
182bool ByteBufferReader::ReadUInt24(uint32_t* val) {
183 if (!val) return false;
184
185 uint32_t v = 0;
186 char* read_into = reinterpret_cast<char*>(&v);
187 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
188 ++read_into;
189 }
190
191 if (!ReadBytes(read_into, 3)) {
192 return false;
193 } else {
194 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
195 return true;
196 }
197}
198
199bool ByteBufferReader::ReadUInt32(uint32_t* val) {
200 if (!val) return false;
201
202 uint32_t v;
203 if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
204 return false;
205 } else {
206 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
207 return true;
208 }
209}
210
211bool ByteBufferReader::ReadUInt64(uint64_t* val) {
212 if (!val) return false;
213
214 uint64_t v;
215 if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
216 return false;
217 } else {
218 *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
219 return true;
220 }
221}
222
223bool ByteBufferReader::ReadString(std::string* val, size_t len) {
224 if (!val) return false;
225
226 if (len > Length()) {
227 return false;
228 } else {
229 val->append(bytes_ + start_, len);
230 start_ += len;
231 return true;
232 }
233}
234
235bool ByteBufferReader::ReadBytes(char* val, size_t len) {
236 if (len > Length()) {
237 return false;
238 } else {
239 memcpy(val, bytes_ + start_, len);
240 start_ += len;
241 return true;
242 }
243}
244
245bool ByteBufferReader::Consume(size_t size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000246 if (size > Length())
247 return false;
248 start_ += size;
249 return true;
250}
251
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000252} // namespace rtc