1 /*
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
11 #include "rtc_base/byte_buffer.h"
12
13 #include <string.h>
14
15 namespace rtc {
16
ByteBufferWriter()17 ByteBufferWriter::ByteBufferWriter() : ByteBufferWriterT() {}
18
ByteBufferWriter(const char * bytes,size_t len)19 ByteBufferWriter::ByteBufferWriter(const char* bytes, size_t len)
20 : ByteBufferWriterT(bytes, len) {}
21
ByteBufferReader(const char * bytes,size_t len)22 ByteBufferReader::ByteBufferReader(const char* bytes, size_t len) {
23 Construct(bytes, len);
24 }
25
ByteBufferReader(const char * bytes)26 ByteBufferReader::ByteBufferReader(const char* bytes) {
27 Construct(bytes, strlen(bytes));
28 }
29
ByteBufferReader(const Buffer & buf)30 ByteBufferReader::ByteBufferReader(const Buffer& buf) {
31 Construct(buf.data<char>(), buf.size());
32 }
33
ByteBufferReader(const ByteBufferWriter & buf)34 ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf) {
35 Construct(buf.Data(), buf.Length());
36 }
37
Construct(const char * bytes,size_t len)38 void ByteBufferReader::Construct(const char* bytes, size_t len) {
39 bytes_ = bytes;
40 size_ = len;
41 start_ = 0;
42 end_ = len;
43 }
44
ReadUInt8(uint8_t * val)45 bool ByteBufferReader::ReadUInt8(uint8_t* val) {
46 if (!val)
47 return false;
48
49 return ReadBytes(reinterpret_cast<char*>(val), 1);
50 }
51
ReadUInt16(uint16_t * val)52 bool ByteBufferReader::ReadUInt16(uint16_t* val) {
53 if (!val)
54 return false;
55
56 uint16_t v;
57 if (!ReadBytes(reinterpret_cast<char*>(&v), 2)) {
58 return false;
59 } else {
60 *val = NetworkToHost16(v);
61 return true;
62 }
63 }
64
ReadUInt24(uint32_t * val)65 bool ByteBufferReader::ReadUInt24(uint32_t* val) {
66 if (!val)
67 return false;
68
69 uint32_t v = 0;
70 char* read_into = reinterpret_cast<char*>(&v);
71 ++read_into;
72
73 if (!ReadBytes(read_into, 3)) {
74 return false;
75 } else {
76 *val = NetworkToHost32(v);
77 return true;
78 }
79 }
80
ReadUInt32(uint32_t * val)81 bool ByteBufferReader::ReadUInt32(uint32_t* val) {
82 if (!val)
83 return false;
84
85 uint32_t v;
86 if (!ReadBytes(reinterpret_cast<char*>(&v), 4)) {
87 return false;
88 } else {
89 *val = NetworkToHost32(v);
90 return true;
91 }
92 }
93
ReadUInt64(uint64_t * val)94 bool ByteBufferReader::ReadUInt64(uint64_t* val) {
95 if (!val)
96 return false;
97
98 uint64_t v;
99 if (!ReadBytes(reinterpret_cast<char*>(&v), 8)) {
100 return false;
101 } else {
102 *val = NetworkToHost64(v);
103 return true;
104 }
105 }
106
ReadUVarint(uint64_t * val)107 bool ByteBufferReader::ReadUVarint(uint64_t* val) {
108 if (!val) {
109 return false;
110 }
111 // Integers are deserialized 7 bits at a time, with each byte having a
112 // continuation byte (msb=1) if there are more bytes to be read.
113 uint64_t v = 0;
114 for (int i = 0; i < 64; i += 7) {
115 char byte;
116 if (!ReadBytes(&byte, 1)) {
117 return false;
118 }
119 // Read the first 7 bits of the byte, then offset by bits read so far.
120 v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
121 // True if the msb is not a continuation byte.
122 if (static_cast<uint64_t>(byte) < 0x80) {
123 *val = v;
124 return true;
125 }
126 }
127 return false;
128 }
129
ReadString(std::string * val,size_t len)130 bool ByteBufferReader::ReadString(std::string* val, size_t len) {
131 if (!val)
132 return false;
133
134 if (len > Length()) {
135 return false;
136 } else {
137 val->append(bytes_ + start_, len);
138 start_ += len;
139 return true;
140 }
141 }
142
ReadBytes(char * val,size_t len)143 bool ByteBufferReader::ReadBytes(char* val, size_t len) {
144 if (len > Length()) {
145 return false;
146 } else {
147 memcpy(val, bytes_ + start_, len);
148 start_ += len;
149 return true;
150 }
151 }
152
Consume(size_t size)153 bool ByteBufferReader::Consume(size_t size) {
154 if (size > Length())
155 return false;
156 start_ += size;
157 return true;
158 }
159
160 } // namespace rtc
161