blob: b2d75182a4d4fb293e570362cdd13e3c55f05d29 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_base/bytebuffer.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000012
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013#include <string.h>
14
15#include <algorithm>
16
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017namespace rtc {
18
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010019ByteBufferWriter::ByteBufferWriter() : ByteBufferWriterT() {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000020
jbauchf1f87202016-03-30 06:43:37 -070021ByteBufferWriter::ByteBufferWriter(ByteOrder byte_order)
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010022 : ByteBufferWriterT(byte_order) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023
jbauchf1f87202016-03-30 06:43:37 -070024ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010025 : ByteBufferWriterT(bytes, len) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000026
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010027ByteBufferWriter::ByteBufferWriter(const char* bytes,
28 size_t len,
jbauchf1f87202016-03-30 06:43:37 -070029 ByteOrder byte_order)
Joachim Bauch4c6a30c2018-03-08 00:55:33 +010030 : ByteBufferWriterT(bytes, len, byte_order) {}
jbauchf1f87202016-03-30 06:43:37 -070031
32ByteBufferReader::ByteBufferReader(const char* bytes, size_t len)
33 : ByteBuffer(ORDER_NETWORK) {
34 Construct(bytes, len);
35}
36
37ByteBufferReader::ByteBufferReader(const char* bytes, size_t len,
38 ByteOrder byte_order)
39 : ByteBuffer(byte_order) {
40 Construct(bytes, len);
41}
42
43ByteBufferReader::ByteBufferReader(const char* bytes)
44 : ByteBuffer(ORDER_NETWORK) {
45 Construct(bytes, strlen(bytes));
46}
47
48ByteBufferReader::ByteBufferReader(const Buffer& buf)
49 : ByteBuffer(ORDER_NETWORK) {
50 Construct(buf.data<char>(), buf.size());
51}
52
53ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf)
54 : ByteBuffer(buf.Order()) {
55 Construct(buf.Data(), buf.Length());
56}
57
58void ByteBufferReader::Construct(const char* bytes, size_t len) {
59 bytes_ = bytes;
60 size_ = len;
61 start_ = 0;
62 end_ = len;
63}
64
65bool ByteBufferReader::ReadUInt8(uint8_t* val) {
66 if (!val) return false;
67
68 return ReadBytes(reinterpret_cast<char*>(val), 1);
69}
70
71bool ByteBufferReader::ReadUInt16(uint16_t* val) {
72 if (!val) return false;
73
74 uint16_t v;
75 if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
76 return false;
77 } else {
78 *val = (Order() == ORDER_NETWORK) ? NetworkToHost16(v) : v;
79 return true;
80 }
81}
82
83bool ByteBufferReader::ReadUInt24(uint32_t* val) {
84 if (!val) return false;
85
86 uint32_t v = 0;
87 char* read_into = reinterpret_cast<char*>(&v);
88 if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
89 ++read_into;
90 }
91
92 if (!ReadBytes(read_into, 3)) {
93 return false;
94 } else {
95 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
96 return true;
97 }
98}
99
100bool ByteBufferReader::ReadUInt32(uint32_t* val) {
101 if (!val) return false;
102
103 uint32_t v;
104 if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
105 return false;
106 } else {
107 *val = (Order() == ORDER_NETWORK) ? NetworkToHost32(v) : v;
108 return true;
109 }
110}
111
112bool ByteBufferReader::ReadUInt64(uint64_t* val) {
113 if (!val) return false;
114
115 uint64_t v;
116 if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
117 return false;
118 } else {
119 *val = (Order() == ORDER_NETWORK) ? NetworkToHost64(v) : v;
120 return true;
121 }
122}
123
mikescarlett9a20fa62016-04-11 16:11:38 -0700124bool ByteBufferReader::ReadUVarint(uint64_t* val) {
125 if (!val) {
126 return false;
127 }
128 // Integers are deserialized 7 bits at a time, with each byte having a
129 // continuation byte (msb=1) if there are more bytes to be read.
130 uint64_t v = 0;
131 for (int i = 0; i < 64; i += 7) {
132 char byte;
133 if (!ReadBytes(&byte, 1)) {
134 return false;
135 }
136 // Read the first 7 bits of the byte, then offset by bits read so far.
137 v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
138 // True if the msb is not a continuation byte.
139 if (static_cast<uint64_t>(byte) < 0x80) {
140 *val = v;
141 return true;
142 }
143 }
144 return false;
145}
146
jbauchf1f87202016-03-30 06:43:37 -0700147bool ByteBufferReader::ReadString(std::string* val, size_t len) {
148 if (!val) return false;
149
150 if (len > Length()) {
151 return false;
152 } else {
153 val->append(bytes_ + start_, len);
154 start_ += len;
155 return true;
156 }
157}
158
159bool ByteBufferReader::ReadBytes(char* val, size_t len) {
160 if (len > Length()) {
161 return false;
162 } else {
163 memcpy(val, bytes_ + start_, len);
164 start_ += len;
165 return true;
166 }
167}
168
169bool ByteBufferReader::Consume(size_t size) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000170 if (size > Length())
171 return false;
172 start_ += size;
173 return true;
174}
175
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000176} // namespace rtc