blob: 94fc6acf08027412a25ed7367320f76e21ddad10 [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
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "rtc_base/bytebuffer.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2612
henrike@webrtc.orgf0488722014-05-13 18:00:2613#include <string.h>
14
15#include <algorithm>
16
henrike@webrtc.orgf0488722014-05-13 18:00:2617namespace rtc {
18
Joachim Bauch4c6a30c2018-03-07 23:55:3319ByteBufferWriter::ByteBufferWriter() : ByteBufferWriterT() {}
henrike@webrtc.orgf0488722014-05-13 18:00:2620
jbauchf1f87202016-03-30 13:43:3721ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
Joachim Bauch4c6a30c2018-03-07 23:55:3322 : ByteBufferWriterT(byte_order) {}
henrike@webrtc.orgf0488722014-05-13 18:00:2623
jbauchf1f87202016-03-30 13:43:3724ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
Joachim Bauch4c6a30c2018-03-07 23:55:3325 : ByteBufferWriterT(bytes, len) {}
henrike@webrtc.orgf0488722014-05-13 18:00:2626
Joachim Bauch4c6a30c2018-03-07 23:55:3327ByteBufferWriter::ByteBufferWriter(const char* bytes,
28 size_t len,
jbauchf1f87202016-03-30 13:43:3729 ByteOrder byte_order)
Joachim Bauch4c6a30c2018-03-07 23:55:3330 : ByteBufferWriterT(bytes, len, byte_order) {}
jbauchf1f87202016-03-30 13:43:3731
32ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
33 : ByteBuffer(ORDER_NETWORK) {
34 Construct(bytes, len);
35}
36
Yves Gerey665174f2018-06-19 13:03:0537ByteBufferReader::ByteBufferReader(const char* bytes,
38 size_t len,
jbauchf1f87202016-03-30 13:43:3739 ByteOrder byte_order)
40 : ByteBuffer(byte_order) {
41 Construct(bytes, len);
42}
43
44ByteBufferReader::ByteBufferReader(const char* bytes)
45 : ByteBuffer(ORDER_NETWORK) {
46 Construct(bytes, strlen(bytes));
47}
48
49ByteBufferReader::ByteBufferReader(const Buffer& buf)
50 : ByteBuffer(ORDER_NETWORK) {
51 Construct(buf.data<char>(), buf.size());
52}
53
54ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
55 : ByteBuffer(buf.Order()) {
56 Construct(buf.Data(), buf.Length());
57}
58
59void ByteBufferReader::Construct(const char* bytes, size_t len) {
60 bytes_ = bytes;
61 size_ = len;
62 start_ = 0;
63 end_ = len;
64}
65
66bool ByteBufferReader::ReadUInt8(uint8_t* val) {
Yves Gerey665174f2018-06-19 13:03:0567 if (!val)
68 return false;
jbauchf1f87202016-03-30 13:43:3769
70 return ReadBytes(reinterpret_cast<char*>(val), 1);
71}
72
73bool ByteBufferReader::ReadUInt16(uint16_t* val) {
Yves Gerey665174f2018-06-19 13:03:0574 if (!val)
75 return false;
jbauchf1f87202016-03-30 13:43:3776
77 uint16_t v;
78 if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
79 return false;
80 } else {
81 *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
82 return true;
83 }
84}
85
86bool ByteBufferReader::ReadUInt24(uint32_t* val) {
Yves Gerey665174f2018-06-19 13:03:0587 if (!val)
88 return false;
jbauchf1f87202016-03-30 13:43:3789
90 uint32_t v = 0;
91 char* read_into = reinterpret_cast<char*>(&v);
92 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
93 ++read_into;
94 }
95
96 if (!ReadBytes(read_into, 3)) {
97 return false;
98 } else {
99 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
100 return true;
101 }
102}
103
104bool ByteBufferReader::ReadUInt32(uint32_t* val) {
Yves Gerey665174f2018-06-19 13:03:05105 if (!val)
106 return false;
jbauchf1f87202016-03-30 13:43:37107
108 uint32_t v;
109 if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
110 return false;
111 } else {
112 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
113 return true;
114 }
115}
116
117bool ByteBufferReader::ReadUInt64(uint64_t* val) {
Yves Gerey665174f2018-06-19 13:03:05118 if (!val)
119 return false;
jbauchf1f87202016-03-30 13:43:37120
121 uint64_t v;
122 if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
123 return false;
124 } else {
125 *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
126 return true;
127 }
128}
129
mikescarlett9a20fa62016-04-11 23:11:38130bool ByteBufferReader::ReadUVarint(uint64_t* val) {
131 if (!val) {
132 return false;
133 }
134 // Integers are deserialized 7 bits at a time, with each byte having a
135 // continuation byte (msb=1) if there are more bytes to be read.
136 uint64_t v = 0;
137 for (int i = 0; i < 64; i += 7) {
138 char byte;
139 if (!ReadBytes(&byte, 1)) {
140 return false;
141 }
142 // Read the first 7 bits of the byte, then offset by bits read so far.
143 v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
144 // True if the msb is not a continuation byte.
145 if (static_cast<uint64_t>(byte) < 0x80) {
146 *val = v;
147 return true;
148 }
149 }
150 return false;
151}
152
jbauchf1f87202016-03-30 13:43:37153bool ByteBufferReader::ReadString(std::string* val, size_t len) {
Yves Gerey665174f2018-06-19 13:03:05154 if (!val)
155 return false;
jbauchf1f87202016-03-30 13:43:37156
157 if (len > Length()) {
158 return false;
159 } else {
160 val->append(bytes_ + start_, len);
161 start_ += len;
162 return true;
163 }
164}
165
166bool ByteBufferReader::ReadBytes(char* val, size_t len) {
167 if (len > Length()) {
168 return false;
169 } else {
170 memcpy(val, bytes_ + start_, len);
171 start_ += len;
172 return true;
173 }
174}
175
176bool ByteBufferReader::Consume(size_t size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26177 if (size > Length())
178 return false;
179 start_ += size;
180 return true;
181}
182
henrike@webrtc.orgf0488722014-05-13 18:00:26183} // namespace rtc