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