blob: 9bcbb838aa4a8524964a1184666d203792592a32 [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
Ali Tofigh7fa90572022-03-17 14:47:4919#include "absl/strings/string_view.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3120#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 17:11:0021#include "rtc_base/byte_order.h"
Henrik Kjellanderec78f1c2017-06-29 05:52:5022
Danil Chapovalov7b46e172019-11-14 16:40:2323// Reads/Writes from/to buffer using network byte order (big endian)
Henrik Kjellanderec78f1c2017-06-29 05:52:5024namespace rtc {
25
Joachim Bauch4c6a30c2018-03-07 23:55:3326template <class BufferClassT>
Danil Chapovalov7b46e172019-11-14 16:40:2327class ByteBufferWriterT {
Joachim Bauch4c6a30c2018-03-07 23:55:3328 public:
Danil Chapovalov7b46e172019-11-14 16:40:2329 ByteBufferWriterT() { Construct(nullptr, kDefaultCapacity); }
30 ByteBufferWriterT(const char* bytes, size_t len) { Construct(bytes, len); }
Joachim Bauch4c6a30c2018-03-07 23:55:3331
Byoungchan Lee14af7622022-01-11 20:24:5832 ByteBufferWriterT(const ByteBufferWriterT&) = delete;
33 ByteBufferWriterT& operator=(const ByteBufferWriterT&) = delete;
34
Joachim Bauch4c6a30c2018-03-07 23:55:3335 const char* Data() const { return buffer_.data(); }
36 size_t Length() const { return buffer_.size(); }
37 size_t Capacity() const { return buffer_.capacity(); }
38
39 // Write value to the buffer. Resizes the buffer when it is
40 // neccessary.
41 void WriteUInt8(uint8_t val) {
42 WriteBytes(reinterpret_cast<const char*>(&val), 1);
43 }
44 void WriteUInt16(uint16_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2345 uint16_t v = HostToNetwork16(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3346 WriteBytes(reinterpret_cast<const char*>(&v), 2);
47 }
48 void WriteUInt24(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2349 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3350 char* start = reinterpret_cast<char*>(&v);
Danil Chapovalov7b46e172019-11-14 16:40:2351 ++start;
Joachim Bauch4c6a30c2018-03-07 23:55:3352 WriteBytes(start, 3);
53 }
54 void WriteUInt32(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2355 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3356 WriteBytes(reinterpret_cast<const char*>(&v), 4);
57 }
58 void WriteUInt64(uint64_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2359 uint64_t v = HostToNetwork64(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3360 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.
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 }
Ali Tofigh7fa90572022-03-17 14:47:4976 void WriteString(absl::string_view val) {
77 WriteBytes(val.data(), val.size());
Joachim Bauch4c6a30c2018-03-07 23:55:3378 }
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.
84 char* ReserveWriteBuffer(size_t len) {
85 buffer_.SetSize(buffer_.size() + len);
86 return buffer_.data();
87 }
88
Artem Titov96e3b992021-07-26 14:03:1489 // Resize the buffer to the specified `size`.
Joachim Bauch4c6a30c2018-03-07 23:55:3390 void Resize(size_t size) { buffer_.SetSize(size); }
91
92 // Clears the contents of the buffer. After this, Length() will be 0.
93 void Clear() { buffer_.Clear(); }
94
95 private:
96 static constexpr size_t kDefaultCapacity = 4096;
97
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.
Joachim Bauch4c6a30c2018-03-07 23:55:33110};
111
112class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
Henrik Kjellanderec78f1c2017-06-29 05:52:50113 public:
Henrik Kjellanderec78f1c2017-06-29 05:52:50114 ByteBufferWriter();
Henrik Kjellanderec78f1c2017-06-29 05:52:50115 ByteBufferWriter(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50116
Byoungchan Lee14af7622022-01-11 20:24:58117 ByteBufferWriter(const ByteBufferWriter&) = delete;
118 ByteBufferWriter& operator=(const ByteBufferWriter&) = delete;
Henrik Kjellanderec78f1c2017-06-29 05:52:50119};
120
121// The ByteBufferReader references the passed data, i.e. the pointer must be
122// valid during the lifetime of the reader.
Danil Chapovalov7b46e172019-11-14 16:40:23123class ByteBufferReader {
Henrik Kjellanderec78f1c2017-06-29 05:52:50124 public:
125 ByteBufferReader(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50126
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
Byoungchan Lee14af7622022-01-11 20:24:58134 ByteBufferReader(const ByteBufferReader&) = delete;
135 ByteBufferReader& operator=(const ByteBufferReader&) = delete;
136
Henrik Kjellanderec78f1c2017-06-29 05:52:50137 // Returns start of unprocessed data.
138 const char* Data() const { return bytes_ + start_; }
139 // Returns number of unprocessed bytes.
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
Artem Titov96e3b992021-07-26 14:03:14152 // Appends next `len` bytes from the buffer to `val`. Returns false
153 // if there is less than `len` bytes left.
Henrik Kjellanderec78f1c2017-06-29 05:52:50154 bool ReadString(std::string* val, size_t len);
155
Artem Titov96e3b992021-07-26 14:03:14156 // Moves current position `size` bytes forward. Returns false if
157 // there is less than `size` bytes left in the buffer. Consume doesn't
Henrik Kjellanderec78f1c2017-06-29 05:52:50158 // permanently remove data, so remembered read positions are still valid
159 // after this call.
160 bool Consume(size_t size);
161
Qingsi Wang558b93b2018-08-30 17:38:44162 protected:
Henrik Kjellanderec78f1c2017-06-29 05:52:50163 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_;
Henrik Kjellanderec78f1c2017-06-29 05:52:50169};
170
171} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26172
Steve Anton10542f22019-01-11 17:11:00173#endif // RTC_BASE_BYTE_BUFFER_H_