Home | History | Annotate | Download | only in base
      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 ByteBuffer::ByteBuffer(const Buffer& buf) {
     46   Construct(buf.data<char>(), buf.size(), ORDER_NETWORK);
     47 }
     48 
     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 
     65 ByteBuffer::~ByteBuffer() {
     66   delete[] bytes_;
     67 }
     68 
     69 bool ByteBuffer::ReadUInt8(uint8_t* val) {
     70   if (!val) return false;
     71 
     72   return ReadBytes(reinterpret_cast<char*>(val), 1);
     73 }
     74 
     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 
     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 
    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 
    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 
    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 
    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 
    150 void ByteBuffer::WriteUInt8(uint8_t val) {
    151   WriteBytes(reinterpret_cast<const char*>(&val), 1);
    152 }
    153 
    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 
    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 
    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 
    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 
    178 void ByteBuffer::WriteString(const std::string& val) {
    179   WriteBytes(val.c_str(), val.size());
    180 }
    181 
    182 void ByteBuffer::WriteBytes(const char* val, size_t len) {
    183   memcpy(ReserveWriteBuffer(len), val, len);
    184 }
    185 
    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 
    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 
    213 bool ByteBuffer::Consume(size_t size) {
    214   if (size > Length())
    215     return false;
    216   start_ += size;
    217   return true;
    218 }
    219 
    220 ByteBuffer::ReadPosition ByteBuffer::GetReadPosition() const {
    221   return ReadPosition(start_, version_);
    222 }
    223 
    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 
    232 void ByteBuffer::Clear() {
    233   memset(bytes_, 0, size_);
    234   start_ = end_ = 0;
    235   ++version_;
    236 }
    237 
    238 }  // namespace rtc
    239