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 25 ByteBuffer::ByteBuffer() { 26 Construct(NULL, DEFAULT_SIZE, ORDER_NETWORK); 27 } 28 29 ByteBuffer::ByteBuffer(ByteOrder byte_order) { 30 Construct(NULL, DEFAULT_SIZE, byte_order); 31 } 32 33 ByteBuffer::ByteBuffer(const char* bytes, size_t len) { 34 Construct(bytes, len, ORDER_NETWORK); 35 } 36 37 ByteBuffer::ByteBuffer(const char* bytes, size_t len, ByteOrder byte_order) { 38 Construct(bytes, len, byte_order); 39 } 40 41 ByteBuffer::ByteBuffer(const char* bytes) { 42 Construct(bytes, strlen(bytes), ORDER_NETWORK); 43 } 44 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 61 ByteBuffer::~ByteBuffer() { 62 delete[] bytes_; 63 } 64 65 bool ByteBuffer::ReadUInt8(uint8* val) { 66 if (!val) return false; 67 68 return ReadBytes(reinterpret_cast<char*>(val), 1); 69 } 70 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 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 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 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 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 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 146 void ByteBuffer::WriteUInt8(uint8 val) { 147 WriteBytes(reinterpret_cast<const char*>(&val), 1); 148 } 149 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 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 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 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 174 void ByteBuffer::WriteString(const std::string& val) { 175 WriteBytes(val.c_str(), val.size()); 176 } 177 178 void ByteBuffer::WriteBytes(const char* val, size_t len) { 179 memcpy(ReserveWriteBuffer(len), val, len); 180 } 181 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 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 209 bool ByteBuffer::Consume(size_t size) { 210 if (size > Length()) 211 return false; 212 start_ += size; 213 return true; 214 } 215 216 ByteBuffer::ReadPosition ByteBuffer::GetReadPosition() const { 217 return ReadPosition(start_, version_); 218 } 219 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 228 void ByteBuffer::Clear() { 229 memset(bytes_, 0, size_); 230 start_ = end_ = 0; 231 ++version_; 232 } 233 234 } // namespace rtc 235