blob: b675953f908fcbb9db00f59c1a7075b04816663e [file] [log] [blame]
Brian Silverman395d6252013-09-13 20:58:14 -07001// Copyright 2012 Google Inc. All Rights Reserved.
2//
3// Modified by FRC Team 971.
4//
5
6#include "gbuffer.h"
7
8#include <stddef.h>
9#include <stdint.h>
10#include <cstring>
11
12#include "aos/common/logging/logging.h"
13
14#include "ghexdump.h"
15
16namespace glibusb {
17
18Buffer::Buffer() {}
19
20Buffer::~Buffer() {}
21
22Buffer::Buffer(const void *src, Buffer::size_type length) {
23 buffer_.resize(length);
24 if (length > 0) {
25 uint8_t *dst = &(buffer_[0]);
26 memcpy(dst, src, length);
27 }
28}
29
30bool Buffer::operator==(const Buffer &other) const {
31 return buffer_ == other.buffer_;
32}
33
34bool Buffer::operator!=(const Buffer &other) const {
35 return !(*this == other);
36}
37
38Buffer *Buffer::MakeSlice(Buffer::size_type offset,
39 Buffer::size_type length) const {
40 CHECK_LE(offset + length, buffer_.size());
41 if (length == 0) {
42 return new Buffer();
43 } else {
44 const uint8_t *p = &(buffer_[offset]);
45 return new Buffer(p, length);
46 }
47}
48
49void Buffer::Clear() {
50 buffer_.clear();
51}
52
53void Buffer::Resize(Buffer::size_type length) {
54 buffer_.resize(length);
55}
56
57void *Buffer::GetBufferPointer(Buffer::size_type length) {
58 return GetBufferPointer(0, length);
59}
60
61const void *Buffer::GetBufferPointer(Buffer::size_type length) const {
62 return GetBufferPointer(0, length);
63}
64
65void *Buffer::GetBufferPointer(Buffer::size_type offset,
66 Buffer::size_type length) {
67 if (length == 0) {
68 return NULL;
69 } else {
70 CHECK_LE(offset + length, buffer_.size());
71 uint8_t *p = &(buffer_[offset]);
72 return static_cast<void *>(p);
73 }
74}
75
76const void *Buffer::GetBufferPointer(Buffer::size_type offset,
77 Buffer::size_type length) const {
78 if (length == 0) {
79 return NULL;
80 } else {
81 CHECK_LE(offset + length, buffer_.size());
82 const uint8_t *p = &(buffer_[offset]);
83 return static_cast<const void *>(p);
84 }
85}
86
87// Specialized template for Get
88template <>
89Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
90 uint8_t *value_out) const {
91 CHECK_LT(byte_offset, buffer_.size());
92 *CHECK_NOTNULL(value_out) = buffer_[byte_offset];
93 return sizeof(uint8_t);
94}
95
96// Specialized template for Get
97template <>
98Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
99 int8_t *value_out) const {
100 uint8_t value;
101 Get(byte_offset, &value);
102 *CHECK_NOTNULL(value_out) = static_cast<int8_t>(value);
103 return sizeof(int8_t);
104}
105
106// Specialized template for Get
107template <>
108Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
109 uint16_t *value_out) const {
110 CHECK_LT(byte_offset + 1, buffer_.size());
111 uint16_t byte0 = static_cast<uint16_t>(buffer_[byte_offset]);
112 uint16_t byte1 = static_cast<uint16_t>(buffer_[byte_offset + 1]);
113 uint16_t value = byte0 | (byte1 << 8);
114 *CHECK_NOTNULL(value_out) = value;
115 return sizeof(uint16_t);
116}
117
118// Specialized template for Get
119template <>
120Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
121 int16_t *value_out) const {
122 uint16_t value;
123 Get(byte_offset, &value);
124 *CHECK_NOTNULL(value_out) = static_cast<int16_t>(value);
125 return sizeof(int16_t);
126}
127
128// Specialized template for Get
129template <>
130Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
131 uint32_t *value_out) const {
132 CHECK_LT(byte_offset + 3, buffer_.size());
133 uint32_t byte0 = static_cast<uint32_t>(buffer_[byte_offset]);
134 uint32_t byte1 = static_cast<uint32_t>(buffer_[byte_offset + 1]);
135 uint32_t byte2 = static_cast<uint32_t>(buffer_[byte_offset + 2]);
136 uint32_t byte3 = static_cast<uint32_t>(buffer_[byte_offset + 3]);
137 uint32_t value = byte0 | (byte1 << 8) | (byte2 << 16) | (byte3 << 24);
138 *CHECK_NOTNULL(value_out) = value;
139 return sizeof(uint32_t);
140}
141
142// Specialized template for Get
143template <>
144Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
145 int32_t *value_out) const {
146 uint32_t value;
147 Get(byte_offset, &value);
148 *CHECK_NOTNULL(value_out) = static_cast<int32_t>(value);
149 return sizeof(int32_t);
150}
151
152// Specialized template for Get
153template <>
154Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
155 uint64_t *value_out) const {
156 CHECK_LT(byte_offset + 7, buffer_.size());
157 uint64_t byte0 = static_cast<uint64_t>(buffer_[byte_offset]);
158 uint64_t byte1 = static_cast<uint64_t>(buffer_[byte_offset + 1]);
159 uint64_t byte2 = static_cast<uint64_t>(buffer_[byte_offset + 2]);
160 uint64_t byte3 = static_cast<uint64_t>(buffer_[byte_offset + 3]);
161 uint64_t byte4 = static_cast<uint64_t>(buffer_[byte_offset + 4]);
162 uint64_t byte5 = static_cast<uint64_t>(buffer_[byte_offset + 5]);
163 uint64_t byte6 = static_cast<uint64_t>(buffer_[byte_offset + 6]);
164 uint64_t byte7 = static_cast<uint64_t>(buffer_[byte_offset + 7]);
165 uint64_t value =
166 byte0 | (byte1 << 8) | (byte2 << 16) | (byte3 << 24) |
167 (byte4 << 32) | (byte5 << 40) | (byte6 << 48) | (byte7 << 56);
168 *CHECK_NOTNULL(value_out) = value;
169 return sizeof(uint64_t);
170}
171
172// Specialized template for Get
173template <>
174Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
175 int64_t *value_out) const {
176 uint64_t value;
177 Get(byte_offset, &value);
178 *CHECK_NOTNULL(value_out) = static_cast<int64_t>(value);
179 return sizeof(int64_t);
180}
181
182Buffer::size_type Buffer::Get(Buffer::size_type byte_offset,
183 std::string *out) const {
184 CHECK_NOTNULL(out);
185 out->clear();
186 size_type n = 0;
187 for (size_t i = byte_offset; /**/; ++i, ++n) {
188 uint8_t p;
189 Get(i, &p);
190 if (!p) {
191 break;
192 }
193 out->push_back(static_cast<char>(p));
194 }
195
196 // strings are always padded out to 4 bytes
197 n = (n + 3) & ~3;
198 return n;
199}
200
201// Specialized template for Put
202template <>
203Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, uint8_t value) {
204 CHECK_LT(byte_offset, buffer_.size());
205 buffer_[byte_offset] = value;
206 return sizeof(uint8_t);
207}
208
209// Specialized template for Put
210template <>
211Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, int8_t value) {
212 return Put(byte_offset, static_cast<uint8_t>(value));
213}
214
215// Specialized template for Put
216template <>
217Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, uint16_t value) {
218 CHECK_LT(byte_offset + 1, buffer_.size());
219 uint8_t byte_0 = static_cast<uint8_t>(value & 0xff);
220 uint8_t byte_1 = static_cast<uint8_t>((value >> 8) & 0xff);
221 buffer_[byte_offset] = byte_0;
222 buffer_[byte_offset + 1] = byte_1;
223 return sizeof(uint16_t);
224}
225
226// Specialized template for Put
227template <>
228Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, int16_t value) {
229 return Put(byte_offset, static_cast<uint16_t>(value));
230}
231
232// Specialized template for Put
233template <>
234Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, uint32_t value) {
235 CHECK_LT(byte_offset + 3, buffer_.size());
236 uint8_t byte_0 = static_cast<uint8_t>(value & 0xff);
237 uint8_t byte_1 = static_cast<uint8_t>((value >> 8) & 0xff);
238 uint8_t byte_2 = static_cast<uint8_t>((value >> 16) & 0xff);
239 uint8_t byte_3 = static_cast<uint8_t>((value >> 24) & 0xff);
240 buffer_[byte_offset] = byte_0;
241 buffer_[byte_offset + 1] = byte_1;
242 buffer_[byte_offset + 2] = byte_2;
243 buffer_[byte_offset + 3] = byte_3;
244 return sizeof(uint32_t);
245}
246
247// Specialized template for Put
248template <>
249Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, int32_t value) {
250 return Put(byte_offset, static_cast<uint32_t>(value));
251}
252
253// Specialized template for Put
254template <>
255Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, uint64_t value) {
256 CHECK_LT(byte_offset + 7, buffer_.size());
257 uint8_t byte_0 = static_cast<uint8_t>(value & 0xff);
258 uint8_t byte_1 = static_cast<uint8_t>((value >> 8) & 0xff);
259 uint8_t byte_2 = static_cast<uint8_t>((value >> 16) & 0xff);
260 uint8_t byte_3 = static_cast<uint8_t>((value >> 24) & 0xff);
261 uint8_t byte_4 = static_cast<uint8_t>((value >> 32) & 0xff);
262 uint8_t byte_5 = static_cast<uint8_t>((value >> 40) & 0xff);
263 uint8_t byte_6 = static_cast<uint8_t>((value >> 48) & 0xff);
264 uint8_t byte_7 = static_cast<uint8_t>((value >> 56) & 0xff);
265 buffer_[byte_offset] = byte_0;
266 buffer_[byte_offset + 1] = byte_1;
267 buffer_[byte_offset + 2] = byte_2;
268 buffer_[byte_offset + 3] = byte_3;
269 buffer_[byte_offset + 4] = byte_4;
270 buffer_[byte_offset + 5] = byte_5;
271 buffer_[byte_offset + 6] = byte_6;
272 buffer_[byte_offset + 7] = byte_7;
273 return sizeof(uint64_t);
274}
275
276// Specialized template for Put
277template <>
278Buffer::size_type Buffer::Put(Buffer::size_type byte_offset, int64_t value) {
279 return Put(byte_offset, static_cast<uint64_t>(value));
280}
281
282void Buffer::Append(const Buffer &source) {
283 buffer_.insert(buffer_.end(), source.buffer_.begin(), source.buffer_.end());
284}
285
286void Buffer::AddHeader(Buffer::size_type length) {
287 buffer_.insert(buffer_.begin(), length, 0);
288}
289
290void Buffer::RemoveHeader(Buffer::size_type length) {
291 if (length > 0) {
292 CHECK_LE(length, buffer_.size());
293 buffer_.erase(buffer_.begin(), buffer_.begin() + length);
294 }
295}
296
297void Buffer::Copy(const Buffer &source) {
298 buffer_.assign(source.buffer_.begin(), source.buffer_.end());
299}
300
301#if 0
302void Buffer::WriteOrDie(File *fp) const {
303 size_type n = Length();
304 const void *p = GetBufferPointer(n);
305 fp->WriteOrDie(p, n);
306}
307
308void Buffer::WriteToPathOrDie(const char *name) const {
309 FileCloser file(File::OpenOrDie(name, "w"));
310 WriteOrDie(file.get());
311}
312#endif
313
314std::string Buffer::Dump() const {
315 size_type n = Length();
316 if (n == 0) {
317 return "";
318 } else {
319 return glibusb::Dump(&(buffer_[0]), n);
320 }
321}
322
323} // namespace glibusb