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