blob: fc383f0a3363aa5a764d2c7c1f46bec74362fb8b [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
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 17:11:0020#include "rtc_base/byte_order.h"
21#include "rtc_base/constructor_magic.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
32 const char* Data() const { return buffer_.data(); }
33 size_t Length() const { return buffer_.size(); }
34 size_t Capacity() const { return buffer_.capacity(); }
35
36 // Write value to the buffer. Resizes the buffer when it is
37 // neccessary.
38 void WriteUInt8(uint8_t val) {
39 WriteBytes(reinterpret_cast<const char*>(&val), 1);
40 }
41 void WriteUInt16(uint16_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2342 uint16_t v = HostToNetwork16(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3343 WriteBytes(reinterpret_cast<const char*>(&v), 2);
44 }
45 void WriteUInt24(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2346 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3347 char* start = reinterpret_cast<char*>(&v);
Danil Chapovalov7b46e172019-11-14 16:40:2348 ++start;
Joachim Bauch4c6a30c2018-03-07 23:55:3349 WriteBytes(start, 3);
50 }
51 void WriteUInt32(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2352 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3353 WriteBytes(reinterpret_cast<const char*>(&v), 4);
54 }
55 void WriteUInt64(uint64_t val) {
Danil Chapovalov7b46e172019-11-14 16:40:2356 uint64_t v = HostToNetwork64(val);
Joachim Bauch4c6a30c2018-03-07 23:55:3357 WriteBytes(reinterpret_cast<const char*>(&v), 8);
58 }
59 // Serializes an unsigned varint in the format described by
60 // https://developers.google.com/protocol-buffers/docs/encoding#varints
61 // with the caveat that integers are 64-bit, not 128-bit.
62 void WriteUVarint(uint64_t val) {
63 while (val >= 0x80) {
64 // Write 7 bits at a time, then set the msb to a continuation byte
65 // (msb=1).
66 char byte = static_cast<char>(val) | 0x80;
67 WriteBytes(&byte, 1);
68 val >>= 7;
69 }
70 char last_byte = static_cast<char>(val);
71 WriteBytes(&last_byte, 1);
72 }
73 void WriteString(const std::string& val) {
74 WriteBytes(val.c_str(), val.size());
75 }
76 void WriteBytes(const char* val, size_t len) { buffer_.AppendData(val, len); }
77
78 // Reserves the given number of bytes and returns a char* that can be written
79 // into. Useful for functions that require a char* buffer and not a
80 // ByteBufferWriter.
81 char* ReserveWriteBuffer(size_t len) {
82 buffer_.SetSize(buffer_.size() + len);
83 return buffer_.data();
84 }
85
Artem Titov96e3b992021-07-26 14:03:1486 // Resize the buffer to the specified `size`.
Joachim Bauch4c6a30c2018-03-07 23:55:3387 void Resize(size_t size) { buffer_.SetSize(size); }
88
89 // Clears the contents of the buffer. After this, Length() will be 0.
90 void Clear() { buffer_.Clear(); }
91
92 private:
93 static constexpr size_t kDefaultCapacity = 4096;
94
95 void Construct(const char* bytes, size_t size) {
96 if (bytes) {
97 buffer_.AppendData(bytes, size);
98 } else {
99 buffer_.EnsureCapacity(size);
100 }
101 }
102
103 BufferClassT buffer_;
104
105 // There are sensible ways to define these, but they aren't needed in our code
106 // base.
107 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriterT);
108};
109
110class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
Henrik Kjellanderec78f1c2017-06-29 05:52:50111 public:
Henrik Kjellanderec78f1c2017-06-29 05:52:50112 ByteBufferWriter();
Henrik Kjellanderec78f1c2017-06-29 05:52:50113 ByteBufferWriter(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50114
Henrik Kjellanderec78f1c2017-06-29 05:52:50115 private:
Henrik Kjellanderec78f1c2017-06-29 05:52:50116 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriter);
117};
118
119// The ByteBufferReader references the passed data, i.e. the pointer must be
120// valid during the lifetime of the reader.
Danil Chapovalov7b46e172019-11-14 16:40:23121class ByteBufferReader {
Henrik Kjellanderec78f1c2017-06-29 05:52:50122 public:
123 ByteBufferReader(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 05:52:50124
125 // Initializes buffer from a zero-terminated string.
126 explicit ByteBufferReader(const char* bytes);
127
128 explicit ByteBufferReader(const Buffer& buf);
129
130 explicit ByteBufferReader(const ByteBufferWriter& buf);
131
132 // Returns start of unprocessed data.
133 const char* Data() const { return bytes_ + start_; }
134 // Returns number of unprocessed bytes.
135 size_t Length() const { return end_ - start_; }
136
137 // Read a next value from the buffer. Return false if there isn't
138 // enough data left for the specified type.
139 bool ReadUInt8(uint8_t* val);
140 bool ReadUInt16(uint16_t* val);
141 bool ReadUInt24(uint32_t* val);
142 bool ReadUInt32(uint32_t* val);
143 bool ReadUInt64(uint64_t* val);
144 bool ReadUVarint(uint64_t* val);
145 bool ReadBytes(char* val, size_t len);
146
Artem Titov96e3b992021-07-26 14:03:14147 // Appends next `len` bytes from the buffer to `val`. Returns false
148 // if there is less than `len` bytes left.
Henrik Kjellanderec78f1c2017-06-29 05:52:50149 bool ReadString(std::string* val, size_t len);
150
Artem Titov96e3b992021-07-26 14:03:14151 // Moves current position `size` bytes forward. Returns false if
152 // there is less than `size` bytes left in the buffer. Consume doesn't
Henrik Kjellanderec78f1c2017-06-29 05:52:50153 // permanently remove data, so remembered read positions are still valid
154 // after this call.
155 bool Consume(size_t size);
156
Qingsi Wang558b93b2018-08-30 17:38:44157 protected:
Henrik Kjellanderec78f1c2017-06-29 05:52:50158 void Construct(const char* bytes, size_t size);
159
160 const char* bytes_;
161 size_t size_;
162 size_t start_;
163 size_t end_;
164
Qingsi Wang558b93b2018-08-30 17:38:44165 private:
Henrik Kjellanderec78f1c2017-06-29 05:52:50166 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
167};
168
169} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26170
Steve Anton10542f22019-01-11 17:11:00171#endif // RTC_BASE_BYTE_BUFFER_H_