• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <assert.h>
14 #include <string.h>
15 
16 #include <algorithm>
17 
18 #include "webrtc/base/basictypes.h"
19 #include "webrtc/base/byteorder.h"
20 
21 namespace rtc {
22 
23 static const int DEFAULT_SIZE = 4096;
24 
ByteBuffer()25 ByteBuffer::ByteBuffer() {
26   Construct(NULL, DEFAULT_SIZE, ORDER_NETWORK);
27 }
28 
ByteBuffer(ByteOrder byte_order)29 ByteBuffer::ByteBuffer(ByteOrder byte_order) {
30   Construct(NULL, DEFAULT_SIZE, byte_order);
31 }
32 
ByteBuffer(const char * bytes,size_t len)33 ByteBuffer::ByteBuffer(const char* bytes, size_t len) {
34   Construct(bytes, len, ORDER_NETWORK);
35 }
36 
ByteBuffer(const char * bytes,size_t len,ByteOrder byte_order)37 ByteBuffer::ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order) {
38   Construct(bytes, len, byte_order);
39 }
40 
ByteBuffer(const char * bytes)41 ByteBuffer::ByteBuffer(const char* bytes) {
42   Construct(bytes, strlen(bytes), ORDER_NETWORK);
43 }
44 
ByteBuffer(const Buffer & buf)45 ByteBuffer::ByteBuffer(const Buffer& buf) {
46   Construct(buf.data<char>(), buf.size(), ORDER_NETWORK);
47 }
48 
Construct(const char * bytes,size_t len,ByteOrder byte_order)49 void ByteBuffer::Construct(const char* bytes, size_t len,
50                            ByteOrder byte_order) {
51   version_ = 0;
52   start_ = 0;
53   size_ = len;
54   byte_order_ = byte_order;
55   bytes_ = new char[size_];
56 
57   if (bytes) {
58     end_ = len;
59     memcpy(bytes_, bytes, end_);
60   } else {
61     end_ = 0;
62   }
63 }
64 
~ByteBuffer()65 ByteBuffer::~ByteBuffer() {
66   delete[] bytes_;
67 }
68 
ReadUInt8(uint8_t * val)69 bool ByteBuffer::ReadUInt8(uint8_t* val) {
70   if (!val) return false;
71 
72   return ReadBytes(reinterpret_cast<char*>(val), 1);
73 }
74 
ReadUInt16(uint16_t * val)75 bool ByteBuffer::ReadUInt16(uint16_t* val) {
76   if (!val) return false;
77 
78   uint16_t v;
79   if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
80     return false;
81   } else {
82     *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost16(v) : v;
83     return true;
84   }
85 }
86 
ReadUInt24(uint32_t * val)87 bool ByteBuffer::ReadUInt24(uint32_t* val) {
88   if (!val) return false;
89 
90   uint32_t v = 0;
91   char* read_into = reinterpret_cast<char*>(&v);
92   if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) {
93     ++read_into;
94   }
95 
96   if (!ReadBytes(read_into, 3)) {
97     return false;
98   } else {
99     *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v;
100     return true;
101   }
102 }
103 
ReadUInt32(uint32_t * val)104 bool ByteBuffer::ReadUInt32(uint32_t* val) {
105   if (!val) return false;
106 
107   uint32_t v;
108   if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
109     return false;
110   } else {
111     *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost32(v) : v;
112     return true;
113   }
114 }
115 
ReadUInt64(uint64_t * val)116 bool ByteBuffer::ReadUInt64(uint64_t* val) {
117   if (!val) return false;
118 
119   uint64_t v;
120   if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
121     return false;
122   } else {
123     *val = (byte_order_ == ORDER_NETWORK) ? NetworkToHost64(v) : v;
124     return true;
125   }
126 }
127 
ReadString(std::string * val,size_t len)128 bool ByteBuffer::ReadString(std::string* val, size_t len) {
129   if (!val) return false;
130 
131   if (len > Length()) {
132     return false;
133   } else {
134     val->append(bytes_ + start_, len);
135     start_ += len;
136     return true;
137   }
138 }
139 
ReadBytes(char * val,size_t len)140 bool ByteBuffer::ReadBytes(char* val, size_t len) {
141   if (len > Length()) {
142     return false;
143   } else {
144     memcpy(val, bytes_ + start_, len);
145     start_ += len;
146     return true;
147   }
148 }
149 
WriteUInt8(uint8_t val)150 void ByteBuffer::WriteUInt8(uint8_t val) {
151   WriteBytes(reinterpret_cast<const char*>(&val), 1);
152 }
153 
WriteUInt16(uint16_t val)154 void ByteBuffer::WriteUInt16(uint16_t val) {
155   uint16_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork16(val) : val;
156   WriteBytes(reinterpret_cast<const char*>(&v), 2);
157 }
158 
WriteUInt24(uint32_t val)159 void ByteBuffer::WriteUInt24(uint32_t val) {
160   uint32_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val;
161   char* start = reinterpret_cast<char*>(&v);
162   if (byte_order_ == ORDER_NETWORK || IsHostBigEndian()) {
163     ++start;
164   }
165   WriteBytes(start, 3);
166 }
167 
WriteUInt32(uint32_t val)168 void ByteBuffer::WriteUInt32(uint32_t val) {
169   uint32_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork32(val) : val;
170   WriteBytes(reinterpret_cast<const char*>(&v), 4);
171 }
172 
WriteUInt64(uint64_t val)173 void ByteBuffer::WriteUInt64(uint64_t val) {
174   uint64_t v = (byte_order_ == ORDER_NETWORK) ? HostToNetwork64(val) : val;
175   WriteBytes(reinterpret_cast<const char*>(&v), 8);
176 }
177 
WriteString(const std::string & val)178 void ByteBuffer::WriteString(const std::string& val) {
179   WriteBytes(val.c_str(), val.size());
180 }
181 
WriteBytes(const char * val,size_t len)182 void ByteBuffer::WriteBytes(const char* val, size_t len) {
183   memcpy(ReserveWriteBuffer(len), val, len);
184 }
185 
ReserveWriteBuffer(size_t len)186 char* ByteBuffer::ReserveWriteBuffer(size_t len) {
187   if (Length() + len > Capacity())
188     Resize(Length() + len);
189 
190   char* start = bytes_ + end_;
191   end_ += len;
192   return start;
193 }
194 
Resize(size_t size)195 void ByteBuffer::Resize(size_t size) {
196   size_t len = std::min(end_ - start_, size);
197   if (size <= size_) {
198     // Don't reallocate, just move data backwards
199     memmove(bytes_, bytes_ + start_, len);
200   } else {
201     // Reallocate a larger buffer.
202     size_ = std::max(size, 3 * size_ / 2);
203     char* new_bytes = new char[size_];
204     memcpy(new_bytes, bytes_ + start_, len);
205     delete [] bytes_;
206     bytes_ = new_bytes;
207   }
208   start_ = 0;
209   end_ = len;
210   ++version_;
211 }
212 
Consume(size_t size)213 bool ByteBuffer::Consume(size_t size) {
214   if (size > Length())
215     return false;
216   start_ += size;
217   return true;
218 }
219 
GetReadPosition() const220 ByteBuffer::ReadPosition ByteBuffer::GetReadPosition() const {
221   return ReadPosition(start_, version_);
222 }
223 
SetReadPosition(const ReadPosition & position)224 bool ByteBuffer::SetReadPosition(const ReadPosition &position) {
225   if (position.version_ != version_) {
226     return false;
227   }
228   start_ = position.start_;
229   return true;
230 }
231 
Clear()232 void ByteBuffer::Clear() {
233   memset(bytes_, 0, size_);
234   start_ = end_ = 0;
235   ++version_;
236 }
237 
238 }  // namespace rtc
239