blob: e48d708378c0a1145b129a780a828c8ce0d52d17 [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"
21#include "rtc_base/constructor_magic.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020022
23namespace rtc {
24
25class ByteBuffer {
26 public:
27 enum ByteOrder {
28 ORDER_NETWORK = 0, // Default, use network byte order (big endian).
29 ORDER_HOST, // Use the native order of the host.
30 };
31
32 explicit ByteBuffer(ByteOrder byte_order) : byte_order_(byte_order) {}
33
34 ByteOrder Order() const { return byte_order_; }
35
36 private:
37 ByteOrder byte_order_;
38
39 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
40};
41
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010042template <class BufferClassT>
43class ByteBufferWriterT : public ByteBuffer {
44 public:
45 // |byte_order| defines order of bytes in the buffer.
46 ByteBufferWriterT() : ByteBuffer(ORDER_NETWORK) {
47 Construct(nullptr, kDefaultCapacity);
48 }
49 explicit ByteBufferWriterT(ByteOrder byte_order) : ByteBuffer(byte_order) {
50 Construct(nullptr, kDefaultCapacity);
51 }
52 ByteBufferWriterT(const char* bytes, size_t len) : ByteBuffer(ORDER_NETWORK) {
53 Construct(bytes, len);
54 }
55 ByteBufferWriterT(const char* bytes, size_t len, ByteOrder byte_order)
56 : ByteBuffer(byte_order) {
57 Construct(bytes, len);
58 }
59
60 const char* Data() const { return buffer_.data(); }
61 size_t Length() const { return buffer_.size(); }
62 size_t Capacity() const { return buffer_.capacity(); }
63
64 // Write value to the buffer. Resizes the buffer when it is
65 // neccessary.
66 void WriteUInt8(uint8_t val) {
67 WriteBytes(reinterpret_cast<const char*>(&val), 1);
68 }
69 void WriteUInt16(uint16_t val) {
70 uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
71 WriteBytes(reinterpret_cast<const char*>(&v), 2);
72 }
73 void WriteUInt24(uint32_t val) {
74 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
75 char* start = reinterpret_cast<char*>(&v);
76 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
77 ++start;
78 }
79 WriteBytes(start, 3);
80 }
81 void WriteUInt32(uint32_t val) {
82 uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
83 WriteBytes(reinterpret_cast<const char*>(&v), 4);
84 }
85 void WriteUInt64(uint64_t val) {
86 uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
87 WriteBytes(reinterpret_cast<const char*>(&v), 8);
88 }
89 // Serializes an unsigned varint in the format described by
90 // https://developers.google.com/protocol-buffers/docs/encoding#varints
91 // with the caveat that integers are 64-bit, not 128-bit.
92 void WriteUVarint(uint64_t val) {
93 while (val >= 0x80) {
94 // Write 7 bits at a time, then set the msb to a continuation byte
95 // (msb=1).
96 char byte = static_cast<char>(val) | 0x80;
97 WriteBytes(&byte, 1);
98 val >>= 7;
99 }
100 char last_byte = static_cast<char>(val);
101 WriteBytes(&last_byte, 1);
102 }
103 void WriteString(const std::string& val) {
104 WriteBytes(val.c_str(), val.size());
105 }
106 void WriteBytes(const char* val, size_t len) { buffer_.AppendData(val, len); }
107
108 // Reserves the given number of bytes and returns a char* that can be written
109 // into. Useful for functions that require a char* buffer and not a
110 // ByteBufferWriter.
111 char* ReserveWriteBuffer(size_t len) {
112 buffer_.SetSize(buffer_.size() + len);
113 return buffer_.data();
114 }
115
116 // Resize the buffer to the specified |size|.
117 void Resize(size_t size) { buffer_.SetSize(size); }
118
119 // Clears the contents of the buffer. After this, Length() will be 0.
120 void Clear() { buffer_.Clear(); }
121
122 private:
123 static constexpr size_t kDefaultCapacity = 4096;
124
125 void Construct(const char* bytes, size_t size) {
126 if (bytes) {
127 buffer_.AppendData(bytes, size);
128 } else {
129 buffer_.EnsureCapacity(size);
130 }
131 }
132
133 BufferClassT buffer_;
134
135 // There are sensible ways to define these, but they aren't needed in our code
136 // base.
137 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriterT);
138};
139
140class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200141 public:
142 // |byte_order| defines order of bytes in the buffer.
143 ByteBufferWriter();
144 explicit ByteBufferWriter(ByteOrder byte_order);
145 ByteBufferWriter(const char* bytes, size_t len);
146 ByteBufferWriter(const char* bytes, size_t len, ByteOrder byte_order);
147
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200148 private:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200149 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriter);
150};
151
152// The ByteBufferReader references the passed data, i.e. the pointer must be
153// valid during the lifetime of the reader.
154class ByteBufferReader : public ByteBuffer {
155 public:
156 ByteBufferReader(const char* bytes, size_t len);
157 ByteBufferReader(const char* bytes, size_t len, ByteOrder byte_order);
158
159 // Initializes buffer from a zero-terminated string.
160 explicit ByteBufferReader(const char* bytes);
161
162 explicit ByteBufferReader(const Buffer& buf);
163
164 explicit ByteBufferReader(const ByteBufferWriter& buf);
165
166 // Returns start of unprocessed data.
167 const char* Data() const { return bytes_ + start_; }
168 // Returns number of unprocessed bytes.
169 size_t Length() const { return end_ - start_; }
170
171 // Read a next value from the buffer. Return false if there isn't
172 // enough data left for the specified type.
173 bool ReadUInt8(uint8_t* val);
174 bool ReadUInt16(uint16_t* val);
175 bool ReadUInt24(uint32_t* val);
176 bool ReadUInt32(uint32_t* val);
177 bool ReadUInt64(uint64_t* val);
178 bool ReadUVarint(uint64_t* val);
179 bool ReadBytes(char* val, size_t len);
180
181 // Appends next |len| bytes from the buffer to |val|. Returns false
182 // if there is less than |len| bytes left.
183 bool ReadString(std::string* val, size_t len);
184
185 // Moves current position |size| bytes forward. Returns false if
186 // there is less than |size| bytes left in the buffer. Consume doesn't
187 // permanently remove data, so remembered read positions are still valid
188 // after this call.
189 bool Consume(size_t size);
190
Qingsi Wang558b93b2018-08-30 10:38:44 -0700191 protected:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200192 void Construct(const char* bytes, size_t size);
193
194 const char* bytes_;
195 size_t size_;
196 size_t start_;
197 size_t end_;
198
Qingsi Wang558b93b2018-08-30 10:38:44 -0700199 private:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200200 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
201};
202
203} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000204
Steve Anton10542f22019-01-11 09:11:00 -0800205#endif // RTC_BASE_BYTE_BUFFER_H_