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 #ifndef RTC_BASE_BYTE_BUFFER_H_ 12 #define RTC_BASE_BYTE_BUFFER_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <string> 18 19 #include "rtc_base/buffer.h" 20 #include "rtc_base/byte_order.h" 21 #include "rtc_base/constructor_magic.h" 22 23 // Reads/Writes from/to buffer using network byte order (big endian) 24 namespace rtc { 25 26 template <class BufferClassT> 27 class ByteBufferWriterT { 28 public: ByteBufferWriterT()29 ByteBufferWriterT() { Construct(nullptr, kDefaultCapacity); } ByteBufferWriterT(const char * bytes,size_t len)30 ByteBufferWriterT(const char* bytes, size_t len) { Construct(bytes, len); } 31 Data()32 const char* Data() const { return buffer_.data(); } Length()33 size_t Length() const { return buffer_.size(); } Capacity()34 size_t Capacity() const { return buffer_.capacity(); } 35 36 // Write value to the buffer. Resizes the buffer when it is 37 // neccessary. WriteUInt8(uint8_t val)38 void WriteUInt8(uint8_t val) { 39 WriteBytes(reinterpret_cast<const char*>(&val), 1); 40 } WriteUInt16(uint16_t val)41 void WriteUInt16(uint16_t val) { 42 uint16_t v = HostToNetwork16(val); 43 WriteBytes(reinterpret_cast<const char*>(&v), 2); 44 } WriteUInt24(uint32_t val)45 void WriteUInt24(uint32_t val) { 46 uint32_t v = HostToNetwork32(val); 47 char* start = reinterpret_cast<char*>(&v); 48 ++start; 49 WriteBytes(start, 3); 50 } WriteUInt32(uint32_t val)51 void WriteUInt32(uint32_t val) { 52 uint32_t v = HostToNetwork32(val); 53 WriteBytes(reinterpret_cast<const char*>(&v), 4); 54 } WriteUInt64(uint64_t val)55 void WriteUInt64(uint64_t val) { 56 uint64_t v = HostToNetwork64(val); 57 WriteBytes(reinterpret_cast<const char*>(&v), 8); 58 } 59 // Serializes an unsigned varint in the format described by 60 // https://developers.google.com/protocol-buffers/docs/encoding#varints 61 // with the caveat that integers are 64-bit, not 128-bit. WriteUVarint(uint64_t val)62 void WriteUVarint(uint64_t val) { 63 while (val >= 0x80) { 64 // Write 7 bits at a time, then set the msb to a continuation byte 65 // (msb=1). 66 char byte = static_cast<char>(val) | 0x80; 67 WriteBytes(&byte, 1); 68 val >>= 7; 69 } 70 char last_byte = static_cast<char>(val); 71 WriteBytes(&last_byte, 1); 72 } WriteString(const std::string & val)73 void WriteString(const std::string& val) { 74 WriteBytes(val.c_str(), val.size()); 75 } WriteBytes(const char * val,size_t len)76 void WriteBytes(const char* val, size_t len) { buffer_.AppendData(val, len); } 77 78 // Reserves the given number of bytes and returns a char* that can be written 79 // into. Useful for functions that require a char* buffer and not a 80 // ByteBufferWriter. ReserveWriteBuffer(size_t len)81 char* ReserveWriteBuffer(size_t len) { 82 buffer_.SetSize(buffer_.size() + len); 83 return buffer_.data(); 84 } 85 86 // Resize the buffer to the specified |size|. Resize(size_t size)87 void Resize(size_t size) { buffer_.SetSize(size); } 88 89 // Clears the contents of the buffer. After this, Length() will be 0. Clear()90 void Clear() { buffer_.Clear(); } 91 92 private: 93 static constexpr size_t kDefaultCapacity = 4096; 94 Construct(const char * bytes,size_t size)95 void Construct(const char* bytes, size_t size) { 96 if (bytes) { 97 buffer_.AppendData(bytes, size); 98 } else { 99 buffer_.EnsureCapacity(size); 100 } 101 } 102 103 BufferClassT buffer_; 104 105 // There are sensible ways to define these, but they aren't needed in our code 106 // base. 107 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriterT); 108 }; 109 110 class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> { 111 public: 112 ByteBufferWriter(); 113 ByteBufferWriter(const char* bytes, size_t len); 114 115 private: 116 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriter); 117 }; 118 119 // The ByteBufferReader references the passed data, i.e. the pointer must be 120 // valid during the lifetime of the reader. 121 class ByteBufferReader { 122 public: 123 ByteBufferReader(const char* bytes, size_t len); 124 125 // Initializes buffer from a zero-terminated string. 126 explicit ByteBufferReader(const char* bytes); 127 128 explicit ByteBufferReader(const Buffer& buf); 129 130 explicit ByteBufferReader(const ByteBufferWriter& buf); 131 132 // Returns start of unprocessed data. Data()133 const char* Data() const { return bytes_ + start_; } 134 // Returns number of unprocessed bytes. Length()135 size_t Length() const { return end_ - start_; } 136 137 // Read a next value from the buffer. Return false if there isn't 138 // enough data left for the specified type. 139 bool ReadUInt8(uint8_t* val); 140 bool ReadUInt16(uint16_t* val); 141 bool ReadUInt24(uint32_t* val); 142 bool ReadUInt32(uint32_t* val); 143 bool ReadUInt64(uint64_t* val); 144 bool ReadUVarint(uint64_t* val); 145 bool ReadBytes(char* val, size_t len); 146 147 // Appends next |len| bytes from the buffer to |val|. Returns false 148 // if there is less than |len| bytes left. 149 bool ReadString(std::string* val, size_t len); 150 151 // Moves current position |size| bytes forward. Returns false if 152 // there is less than |size| bytes left in the buffer. Consume doesn't 153 // permanently remove data, so remembered read positions are still valid 154 // after this call. 155 bool Consume(size_t size); 156 157 protected: 158 void Construct(const char* bytes, size_t size); 159 160 const char* bytes_; 161 size_t size_; 162 size_t start_; 163 size_t end_; 164 165 private: 166 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader); 167 }; 168 169 } // namespace rtc 170 171 #endif // RTC_BASE_BYTE_BUFFER_H_ 172