blob: 1508bd6eadea048798c28cdd3d199404f2d328a5 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
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
Steve Anton10542f22019-01-11 17:11:0011#ifndef RTC_BASE_BYTE_BUFFER_H_
12#define RTC_BASE_BYTE_BUFFER_H_
henrike@webrtc.orgf0488722014-05-13 18:00:2613
Yves Gerey988cc082018-10-23 10:03:0114#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 17:08:3316
Henrik Kjellanderec78f1c2017-06-29 05:52:5017#include <string>
henrike@webrtc.orgf0488722014-05-13 18:00:2618
Per Kcf2e08b2023-11-17 09:05:3619#include "absl/base/attributes.h"
Ali Tofigh7fa90572022-03-17 14:47:4920#include "absl/strings/string_view.h"
Per Kcf2e08b2023-11-17 09:05:3621#include "api/array_view.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3122#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 17:11:0023#include "rtc_base/byte_order.h"
Henrik Kjellanderec78f1c2017-06-29 05:52:5024
Danil Chapovalov7b46e172019-11-14 16:40:2325// Reads/Writes from/to buffer using network byte order (big endian)
Henrik Kjellanderec78f1c2017-06-29 05:52:5026namespace rtc {
27
Joachim Bauch4c6a30c2018-03-07 23:55:3328template <class BufferClassT>
Danil Chapovalov7b46e172019-11-14 16:40:2329class ByteBufferWriterT {
Harald Alvestrandbe023282023-12-04 09:32:1430 using value_type = typename BufferClassT::value_type;
31
Joachim Bauch4c6a30c2018-03-07 23:55:3332 public:
Danil Chapovalov7b46e172019-11-14 16:40:2333 ByteBufferWriterT() { Construct(nullptr, kDefaultCapacity); }
Harald Alvestrandbe023282023-12-04 09:32:1434 ByteBufferWriterT(const value_type* bytes, size_t len) {
35 Construct(bytes, len);
36 }
Joachim Bauch4c6a30c2018-03-07 23:55:3337
Byoungchan Lee14af7622022-01-11 20:24:5838 ByteBufferWriterT(const ByteBufferWriterT&) = delete;
39 ByteBufferWriterT& operator=(const ByteBufferWriterT&) = delete;
40
Harald Alvestrandbe023282023-12-04 09:32:1441 const value_type* Data() const { return buffer_.data(); }
Joachim Bauch4c6a30c2018-03-07 23:55:3342 size_t Length() const { return buffer_.size(); }
43 size_t Capacity() const { return buffer_.capacity(); }
Harald Alvestrandece5cb82023-12-04 19:38:1644 rtc::ArrayView<const value_type> DataView() const {
45 return rtc::MakeArrayView(Data(), Length());
46 }
47 // Accessor that returns a string_view, independent of underlying type.
48 // Intended to provide access for existing users that expect char*
49 // when the underlying type changes to uint8_t.
50 // TODO(bugs.webrtc.org/15665): Delete when users are converted.
51 absl::string_view DataAsStringView() const {
52 return absl::string_view(reinterpret_cast<const char*>(Data()), Length());
53 }
Harald Alvestrand776fe6d2023-12-11 21:38:5154 const char* DataAsCharPointer() const {
55 return reinterpret_cast<const char*>(Data());
56 }
Joachim Bauch4c6a30c2018-03-07 23:55:3357
58 // Write value to the buffer. Resizes the buffer when it is
59 // neccessary.
60 void WriteUInt8(uint8_t val) {
Harald Alvestrandf0ddae82023-12-12 12:05:2061 WriteBytesInternal(reinterpret_cast<const value_type*>(&val), 1);
Joachim Bauch4c6a30c2018-03-07 23:55:3362 }
63 void WriteUInt16(uint16_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2364 uint16_t v = HostToNetwork16(val);
Harald Alvestrandf0ddae82023-12-12 12:05:2065 WriteBytesInternal(reinterpret_cast<const value_type*>(&v), 2);
Joachim Bauch4c6a30c2018-03-07 23:55:3366 }
67 void WriteUInt24(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2368 uint32_t v = HostToNetwork32(val);
Harald Alvestrandbe023282023-12-04 09:32:1469 value_type* start = reinterpret_cast<value_type*>(&v);
Danil Chapovalov7b46e172019-11-14 16:40:2370 ++start;
Harald Alvestrandf0ddae82023-12-12 12:05:2071 WriteBytesInternal(start, 3);
Joachim Bauch4c6a30c2018-03-07 23:55:3372 }
73 void WriteUInt32(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2374 uint32_t v = HostToNetwork32(val);
Harald Alvestrandf0ddae82023-12-12 12:05:2075 WriteBytesInternal(reinterpret_cast<const value_type*>(&v), 4);
Joachim Bauch4c6a30c2018-03-07 23:55:3376 }
77 void WriteUInt64(uint64_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2378 uint64_t v = HostToNetwork64(val);
Harald Alvestrandf0ddae82023-12-12 12:05:2079 WriteBytesInternal(reinterpret_cast<const value_type*>(&v), 8);
Joachim Bauch4c6a30c2018-03-07 23:55:3380 }
81 // Serializes an unsigned varint in the format described by
82 // https://developers.google.com/protocol-buffers/docs/encoding#varints
83 // with the caveat that integers are 64-bit, not 128-bit.
84 void WriteUVarint(uint64_t val) {
85 while (val >= 0x80) {
86 // Write 7 bits at a time, then set the msb to a continuation byte
87 // (msb=1).
Harald Alvestrandbe023282023-12-04 09:32:1488 value_type byte = static_cast<value_type>(val) | 0x80;
Harald Alvestrandf0ddae82023-12-12 12:05:2089 WriteBytesInternal(&byte, 1);
Joachim Bauch4c6a30c2018-03-07 23:55:3390 val >>= 7;
91 }
Harald Alvestrandbe023282023-12-04 09:32:1492 value_type last_byte = static_cast<value_type>(val);
Harald Alvestrandf0ddae82023-12-12 12:05:2093 WriteBytesInternal(&last_byte, 1);
Joachim Bauch4c6a30c2018-03-07 23:55:3394 }
Ali Tofigh7fa90572022-03-17 14:47:4995 void WriteString(absl::string_view val) {
Harald Alvestrandf0ddae82023-12-12 12:05:2096 WriteBytesInternal(reinterpret_cast<const value_type*>(val.data()),
97 val.size());
Joachim Bauch4c6a30c2018-03-07 23:55:3398 }
Harald Alvestrandf0ddae82023-12-12 12:05:2099 // Write an array of bytes (uint8_t)
100 void WriteBytes(const uint8_t* val, size_t len) {
101 WriteBytesInternal(reinterpret_cast<const value_type*>(val), len);
102 }
Joachim Bauch4c6a30c2018-03-07 23:55:33103
Harald Alvestrandbe023282023-12-04 09:32:14104 // Reserves the given number of bytes and returns a value_type* that can be
105 // written into. Useful for functions that require a value_type* buffer and
106 // not a ByteBufferWriter.
107 value_type* ReserveWriteBuffer(size_t len) {
Joachim Bauch4c6a30c2018-03-07 23:55:33108 buffer_.SetSize(buffer_.size() + len);
109 return buffer_.data();
110 }
111
Artem Titov96e3b992021-07-26 14:03:14112 // Resize the buffer to the specified `size`.
Joachim Bauch4c6a30c2018-03-07 23:55:33113 void Resize(size_t size) { buffer_.SetSize(size); }
114
115 // Clears the contents of the buffer. After this, Length() will be 0.
116 void Clear() { buffer_.Clear(); }
117
118 private:
119 static constexpr size_t kDefaultCapacity = 4096;
120
Harald Alvestrandbe023282023-12-04 09:32:14121 void Construct(const value_type* bytes, size_t size) {
Joachim Bauch4c6a30c2018-03-07 23:55:33122 if (bytes) {
123 buffer_.AppendData(bytes, size);
124 } else {
125 buffer_.EnsureCapacity(size);
126 }
127 }
128
Harald Alvestrandf0ddae82023-12-12 12:05:20129 void WriteBytesInternal(const value_type* val, size_t len) {
130 buffer_.AppendData(val, len);
131 }
132
Joachim Bauch4c6a30c2018-03-07 23:55:33133 BufferClassT buffer_;
134
135 // There are sensible ways to define these, but they aren't needed in our code
136 // base.
Joachim Bauch4c6a30c2018-03-07 23:55:33137};
138
Harald Alvestrandf0ddae82023-12-12 12:05:20139class ByteBufferWriter : public ByteBufferWriterT<BufferT<uint8_t>> {
Henrik Kjellanderec78f1c2017-06-29 05:52:50140 public:
Henrik Kjellanderec78f1c2017-06-29 05:52:50141 ByteBufferWriter();
Harald Alvestrandf0ddae82023-12-12 12:05:20142 ByteBufferWriter(const uint8_t* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50143
Byoungchan Lee14af7622022-01-11 20:24:58144 ByteBufferWriter(const ByteBufferWriter&) = delete;
145 ByteBufferWriter& operator=(const ByteBufferWriter&) = delete;
Henrik Kjellanderec78f1c2017-06-29 05:52:50146};
147
148// The ByteBufferReader references the passed data, i.e. the pointer must be
149// valid during the lifetime of the reader.
Danil Chapovalov7b46e172019-11-14 16:40:23150class ByteBufferReader {
Henrik Kjellanderec78f1c2017-06-29 05:52:50151 public:
Per Kcf2e08b2023-11-17 09:05:36152 explicit ByteBufferReader(
153 rtc::ArrayView<const uint8_t> bytes ABSL_ATTRIBUTE_LIFETIME_BOUND);
154
Henrik Kjellanderec78f1c2017-06-29 05:52:50155 explicit ByteBufferReader(const ByteBufferWriter& buf);
156
Byoungchan Lee14af7622022-01-11 20:24:58157 ByteBufferReader(const ByteBufferReader&) = delete;
158 ByteBufferReader& operator=(const ByteBufferReader&) = delete;
159
Harald Alvestrand56926492023-12-19 15:32:38160 const uint8_t* Data() const { return bytes_ + start_; }
Henrik Kjellanderec78f1c2017-06-29 05:52:50161 // Returns number of unprocessed bytes.
162 size_t Length() const { return end_ - start_; }
Harald Alvestrand56926492023-12-19 15:32:38163 // Returns a view of the unprocessed data. Does not move current position.
Harald Alvestrandece5cb82023-12-04 19:38:16164 rtc::ArrayView<const uint8_t> DataView() const {
Harald Alvestrand72defe42023-11-16 13:33:56165 return rtc::ArrayView<const uint8_t>(bytes_ + start_, end_ - start_);
166 }
Henrik Kjellanderec78f1c2017-06-29 05:52:50167
168 // Read a next value from the buffer. Return false if there isn't
169 // enough data left for the specified type.
170 bool ReadUInt8(uint8_t* val);
171 bool ReadUInt16(uint16_t* val);
172 bool ReadUInt24(uint32_t* val);
173 bool ReadUInt32(uint32_t* val);
174 bool ReadUInt64(uint64_t* val);
175 bool ReadUVarint(uint64_t* val);
Harald Alvestrand56926492023-12-19 15:32:38176 // Copies the val.size() next bytes into val.data().
Harald Alvestrandf0907c62023-11-20 09:20:23177 bool ReadBytes(rtc::ArrayView<uint8_t> val);
Artem Titov96e3b992021-07-26 14:03:14178 // Appends next `len` bytes from the buffer to `val`. Returns false
179 // if there is less than `len` bytes left.
Henrik Kjellanderec78f1c2017-06-29 05:52:50180 bool ReadString(std::string* val, size_t len);
Tommieb4a3142024-01-15 20:06:05181 // Same as `ReadString` except that the returned string_view will point into
182 // the internal buffer (no additional buffer allocation).
183 bool ReadStringView(absl::string_view* val, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50184
Artem Titov96e3b992021-07-26 14:03:14185 // Moves current position `size` bytes forward. Returns false if
186 // there is less than `size` bytes left in the buffer. Consume doesn't
Henrik Kjellanderec78f1c2017-06-29 05:52:50187 // permanently remove data, so remembered read positions are still valid
188 // after this call.
189 bool Consume(size_t size);
190
Harald Alvestrandf0907c62023-11-20 09:20:23191 private:
Harald Alvestrand72defe42023-11-16 13:33:56192 void Construct(const uint8_t* bytes, size_t size);
Harald Alvestrandf0907c62023-11-20 09:20:23193 bool ReadBytes(uint8_t* val, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50194
Harald Alvestrand72defe42023-11-16 13:33:56195 const uint8_t* bytes_;
Henrik Kjellanderec78f1c2017-06-29 05:52:50196 size_t size_;
197 size_t start_;
198 size_t end_;
Henrik Kjellanderec78f1c2017-06-29 05:52:50199};
200
201} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26202
Steve Anton10542f22019-01-11 17:11:00203#endif // RTC_BASE_BYTE_BUFFER_H_