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