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