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