blob: d2dda3c8e13dee9155a2c3c2a8eb05dbf136f20b [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/byte_order.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020021
Danil Chapovalov7b46e172019-11-14 17:40:23 +010022// Reads/Writes from/to buffer using network byte order (big endian)
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020023namespace rtc {
24
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010025template <class BufferClassT>
Danil Chapovalov7b46e172019-11-14 17:40:23 +010026class ByteBufferWriterT {
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010027 public:
Danil Chapovalov7b46e172019-11-14 17:40:23 +010028 ByteBufferWriterT() { Construct(nullptr, kDefaultCapacity); }
29 ByteBufferWriterT(const char* bytes, size_t len) { Construct(bytes, len); }
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010030
Byoungchan Lee14af7622022-01-12 05:24:58 +090031 ByteBufferWriterT(const ByteBufferWriterT&) = delete;
32 ByteBufferWriterT& operator=(const ByteBufferWriterT&) = delete;
33
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010034 const char* Data() const { return buffer_.data(); }
35 size_t Length() const { return buffer_.size(); }
36 size_t Capacity() const { return buffer_.capacity(); }
37
38 // Write value to the buffer. Resizes the buffer when it is
39 // neccessary.
40 void WriteUInt8(uint8_t val) {
41 WriteBytes(reinterpret_cast<const char*>(&val), 1);
42 }
43 void WriteUInt16(uint16_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010044 uint16_t v = HostToNetwork16(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010045 WriteBytes(reinterpret_cast<const char*>(&v), 2);
46 }
47 void WriteUInt24(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010048 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010049 char* start = reinterpret_cast<char*>(&v);
Danil Chapovalov7b46e172019-11-14 17:40:23 +010050 ++start;
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010051 WriteBytes(start, 3);
52 }
53 void WriteUInt32(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010054 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010055 WriteBytes(reinterpret_cast<const char*>(&v), 4);
56 }
57 void WriteUInt64(uint64_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010058 uint64_t v = HostToNetwork64(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010059 WriteBytes(reinterpret_cast<const char*>(&v), 8);
60 }
61 // Serializes an unsigned varint in the format described by
62 // https://developers.google.com/protocol-buffers/docs/encoding#varints
63 // with the caveat that integers are 64-bit, not 128-bit.
64 void WriteUVarint(uint64_t val) {
65 while (val >= 0x80) {
66 // Write 7 bits at a time, then set the msb to a continuation byte
67 // (msb=1).
68 char byte = static_cast<char>(val) | 0x80;
69 WriteBytes(&byte, 1);
70 val >>= 7;
71 }
72 char last_byte = static_cast<char>(val);
73 WriteBytes(&last_byte, 1);
74 }
75 void WriteString(const std::string& val) {
76 WriteBytes(val.c_str(), val.size());
77 }
78 void WriteBytes(const char* val, size_t len) { buffer_.AppendData(val, len); }
79
80 // Reserves the given number of bytes and returns a char* that can be written
81 // into. Useful for functions that require a char* buffer and not a
82 // ByteBufferWriter.
83 char* ReserveWriteBuffer(size_t len) {
84 buffer_.SetSize(buffer_.size() + len);
85 return buffer_.data();
86 }
87
Artem Titov96e3b992021-07-26 16:03:14 +020088 // Resize the buffer to the specified `size`.
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010089 void Resize(size_t size) { buffer_.SetSize(size); }
90
91 // Clears the contents of the buffer. After this, Length() will be 0.
92 void Clear() { buffer_.Clear(); }
93
94 private:
95 static constexpr size_t kDefaultCapacity = 4096;
96
97 void Construct(const char* bytes, size_t size) {
98 if (bytes) {
99 buffer_.AppendData(bytes, size);
100 } else {
101 buffer_.EnsureCapacity(size);
102 }
103 }
104
105 BufferClassT buffer_;
106
107 // There are sensible ways to define these, but they aren't needed in our code
108 // base.
Joachim Bauch4c6a30c2018-03-08 00:55:33 +0100109};
110
111class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200112 public:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200113 ByteBufferWriter();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200114 ByteBufferWriter(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200115
Byoungchan Lee14af7622022-01-12 05:24:58 +0900116 ByteBufferWriter(const ByteBufferWriter&) = delete;
117 ByteBufferWriter& operator=(const ByteBufferWriter&) = delete;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200118};
119
120// The ByteBufferReader references the passed data, i.e. the pointer must be
121// valid during the lifetime of the reader.
Danil Chapovalov7b46e172019-11-14 17:40:23 +0100122class ByteBufferReader {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200123 public:
124 ByteBufferReader(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200125
126 // Initializes buffer from a zero-terminated string.
127 explicit ByteBufferReader(const char* bytes);
128
129 explicit ByteBufferReader(const Buffer& buf);
130
131 explicit ByteBufferReader(const ByteBufferWriter& buf);
132
Byoungchan Lee14af7622022-01-12 05:24:58 +0900133 ByteBufferReader(const ByteBufferReader&) = delete;
134 ByteBufferReader& operator=(const ByteBufferReader&) = delete;
135
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200136 // Returns start of unprocessed data.
137 const char* Data() const { return bytes_ + start_; }
138 // Returns number of unprocessed bytes.
139 size_t Length() const { return end_ - start_; }
140
141 // Read a next value from the buffer. Return false if there isn't
142 // enough data left for the specified type.
143 bool ReadUInt8(uint8_t* val);
144 bool ReadUInt16(uint16_t* val);
145 bool ReadUInt24(uint32_t* val);
146 bool ReadUInt32(uint32_t* val);
147 bool ReadUInt64(uint64_t* val);
148 bool ReadUVarint(uint64_t* val);
149 bool ReadBytes(char* val, size_t len);
150
Artem Titov96e3b992021-07-26 16:03:14 +0200151 // Appends next `len` bytes from the buffer to `val`. Returns false
152 // if there is less than `len` bytes left.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200153 bool ReadString(std::string* val, size_t len);
154
Artem Titov96e3b992021-07-26 16:03:14 +0200155 // Moves current position `size` bytes forward. Returns false if
156 // there is less than `size` bytes left in the buffer. Consume doesn't
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200157 // permanently remove data, so remembered read positions are still valid
158 // after this call.
159 bool Consume(size_t size);
160
Qingsi Wang558b93b2018-08-30 10:38:44 -0700161 protected:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200162 void Construct(const char* bytes, size_t size);
163
164 const char* bytes_;
165 size_t size_;
166 size_t start_;
167 size_t end_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200168};
169
170} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000171
Steve Anton10542f22019-01-11 09:11:00 -0800172#endif // RTC_BASE_BYTE_BUFFER_H_