blob: 9bcbb838aa4a8524964a1184666d203792592a32 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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 09:11:00 -080011#ifndef RTC_BASE_BYTE_BUFFER_H_
12#define RTC_BASE_BYTE_BUFFER_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stddef.h>
15#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020016
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020017#include <string>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018
Ali Tofigh7fa90572022-03-17 15:47:49 +010019#include "absl/strings/string_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/byte_order.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020022
Danil Chapovalov7b46e172019-11-14 17:40:23 +010023// Reads/Writes from/to buffer using network byte order (big endian)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020024namespace rtc {
25
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010026template <class BufferClassT>
Danil Chapovalov7b46e172019-11-14 17:40:23 +010027class ByteBufferWriterT {
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010028 public:
Danil Chapovalov7b46e172019-11-14 17:40:23 +010029 ByteBufferWriterT() { Construct(nullptr, kDefaultCapacity); }
30 ByteBufferWriterT(const char* bytes, size_t len) { Construct(bytes, len); }
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010031
Byoungchan Lee14af7622022-01-12 05:24:58 +090032 ByteBufferWriterT(const ByteBufferWriterT&) = delete;
33 ByteBufferWriterT& operator=(const ByteBufferWriterT&) = delete;
34
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010035 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 17:40:23 +010045 uint16_t v = HostToNetwork16(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010046 WriteBytes(reinterpret_cast<const char*>(&v), 2);
47 }
48 void WriteUInt24(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010049 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010050 char* start = reinterpret_cast<char*>(&v);
Danil Chapovalov7b46e172019-11-14 17:40:23 +010051 ++start;
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010052 WriteBytes(start, 3);
53 }
54 void WriteUInt32(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010055 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010056 WriteBytes(reinterpret_cast<const char*>(&v), 4);
57 }
58 void WriteUInt64(uint64_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010059 uint64_t v = HostToNetwork64(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010060 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 15:47:49 +010076 void WriteString(absl::string_view val) {
77 WriteBytes(val.data(), val.size());
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010078 }
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 16:03:14 +020089 // Resize the buffer to the specified `size`.
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010090 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-08 00:55:33 +0100110};
111
112class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200113 public:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200114 ByteBufferWriter();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200115 ByteBufferWriter(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200116
Byoungchan Lee14af7622022-01-12 05:24:58 +0900117 ByteBufferWriter(const ByteBufferWriter&) = delete;
118 ByteBufferWriter& operator=(const ByteBufferWriter&) = delete;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200119};
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 17:40:23 +0100123class ByteBufferReader {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200124 public:
125 ByteBufferReader(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200126
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-12 05:24:58 +0900134 ByteBufferReader(const ByteBufferReader&) = delete;
135 ByteBufferReader& operator=(const ByteBufferReader&) = delete;
136
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200137 // 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 16:03:14 +0200152 // Appends next `len` bytes from the buffer to `val`. Returns false
153 // if there is less than `len` bytes left.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200154 bool ReadString(std::string* val, size_t len);
155
Artem Titov96e3b992021-07-26 16:03:14 +0200156 // 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 07:52:50 +0200158 // 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 10:38:44 -0700162 protected:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200163 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 07:52:50 +0200169};
170
171} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000172
Steve Anton10542f22019-01-11 09:11:00 -0800173#endif // RTC_BASE_BYTE_BUFFER_H_