blob: 31fc8cbfea5afffb7e2461052e5a63c7fc34b22c [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
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
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 17:40:23 +010042 uint16_t v = HostToNetwork16(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010043 WriteBytes(reinterpret_cast<const char*>(&v), 2);
44 }
45 void WriteUInt24(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010046 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010047 char* start = reinterpret_cast<char*>(&v);
Danil Chapovalov7b46e172019-11-14 17:40:23 +010048 ++start;
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010049 WriteBytes(start, 3);
50 }
51 void WriteUInt32(uint32_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010052 uint32_t v = HostToNetwork32(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010053 WriteBytes(reinterpret_cast<const char*>(&v), 4);
54 }
55 void WriteUInt64(uint64_t val) {
Danil Chapovalov7b46e172019-11-14 17:40:23 +010056 uint64_t v = HostToNetwork64(val);
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010057 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
86 // Resize the buffer to the specified |size|.
87 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 07:52:50 +0200111 public:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200112 ByteBufferWriter();
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200113 ByteBufferWriter(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200114
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200115 private:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200116 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 17:40:23 +0100121class ByteBufferReader {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200122 public:
123 ByteBufferReader(const char* bytes, size_t len);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200124
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
147 // Appends next |len| bytes from the buffer to |val|. Returns false
148 // if there is less than |len| bytes left.
149 bool ReadString(std::string* val, size_t len);
150
151 // Moves current position |size| bytes forward. Returns false if
152 // there is less than |size| bytes left in the buffer. Consume doesn't
153 // 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 10:38:44 -0700157 protected:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200158 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 10:38:44 -0700165 private:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200166 RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
167};
168
169} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000170
Steve Anton10542f22019-01-11 09:11:00 -0800171#endif // RTC_BASE_BYTE_BUFFER_H_