1 // Copyright (c) 2010 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31 
32 // byte_cursor_unittest.cc: Unit tests for google_breakpad::ByteBuffer
33 // and google_breakpad::ByteCursor.
34 
35 #include <string>
36 
37 #include <string.h>
38 
39 #include "breakpad_googletest_includes.h"
40 #include "common/byte_cursor.h"
41 #include "common/using_std_string.h"
42 
43 using google_breakpad::ByteBuffer;
44 using google_breakpad::ByteCursor;
45 
TEST(Buffer,SizeOfNothing)46 TEST(Buffer, SizeOfNothing) {
47   uint8_t data[1];
48   ByteBuffer buffer(data, 0);
49   EXPECT_EQ(0U, buffer.Size());
50 }
51 
TEST(Buffer,SizeOfSomething)52 TEST(Buffer, SizeOfSomething) {
53   uint8_t data[10];
54   ByteBuffer buffer(data, sizeof(data));
55   EXPECT_EQ(10U, buffer.Size());
56 }
57 
TEST(Extent,AvailableEmpty)58 TEST(Extent, AvailableEmpty) {
59   uint8_t data[1];
60   ByteBuffer buffer(data, 0);
61   ByteCursor cursor(&buffer);
62   EXPECT_EQ(0U, cursor.Available());
63 }
64 
TEST(Extent,AtEndEmpty)65 TEST(Extent, AtEndEmpty) {
66   uint8_t data[1];
67   ByteBuffer buffer(data, 0);
68   ByteCursor cursor(&buffer);
69   EXPECT_TRUE(cursor.AtEnd());
70 }
71 
TEST(Extent,AsBoolEmpty)72 TEST(Extent, AsBoolEmpty) {
73   uint8_t data[1];
74   ByteBuffer buffer(data, 0);
75   ByteCursor cursor(&buffer);
76   EXPECT_TRUE(cursor);
77 }
78 
TEST(Extent,AvailableSome)79 TEST(Extent, AvailableSome) {
80   uint8_t data[10];
81   ByteBuffer buffer(data, sizeof(data));
82   ByteCursor cursor(&buffer);
83   EXPECT_EQ(10U, cursor.Available());
84 }
85 
TEST(Extent,AtEndSome)86 TEST(Extent, AtEndSome) {
87   uint8_t data[10];
88   ByteBuffer buffer(data, sizeof(data));
89   ByteCursor cursor(&buffer);
90   EXPECT_FALSE(cursor.AtEnd());
91   EXPECT_TRUE(cursor.Skip(sizeof(data)).AtEnd());
92 }
93 
TEST(Extent,AsBoolSome)94 TEST(Extent, AsBoolSome) {
95   uint8_t data[10];
96   ByteBuffer buffer(data, sizeof(data));
97   ByteCursor cursor(&buffer);
98   EXPECT_TRUE(cursor);
99   EXPECT_TRUE(cursor.Skip(sizeof(data)));
100   EXPECT_FALSE(cursor.Skip(1));
101 }
102 
TEST(Extent,Cursor)103 TEST(Extent, Cursor) {
104   uint8_t data[] = { 0xf7,
105                      0x9f, 0xbe,
106                      0x67, 0xfb, 0xd3, 0x58,
107                      0x6f, 0x36, 0xde, 0xd1,
108                      0x2a, 0x2a, 0x2a };
109   ByteBuffer buffer(data, sizeof(data));
110   ByteCursor cursor(&buffer);
111 
112   uint8_t a;
113   uint16_t b;
114   uint32_t c;
115   uint32_t d;
116   uint8_t stars[3];
117 
118   EXPECT_EQ(data + 0U, cursor.here());
119 
120   EXPECT_TRUE(cursor >> a);
121   EXPECT_EQ(data + 1U, cursor.here());
122 
123   EXPECT_TRUE(cursor >> b);
124   EXPECT_EQ(data + 3U, cursor.here());
125 
126   EXPECT_TRUE(cursor >> c);
127   EXPECT_EQ(data + 7U, cursor.here());
128 
129   EXPECT_TRUE(cursor.Skip(4));
130   EXPECT_EQ(data + 11U, cursor.here());
131 
132   EXPECT_TRUE(cursor.Read(stars, 3));
133   EXPECT_EQ(data + 14U, cursor.here());
134 
135   EXPECT_FALSE(cursor >> d);
136   EXPECT_EQ(data + 14U, cursor.here());
137 }
138 
TEST(Extent,SetOffset)139 TEST(Extent, SetOffset) {
140   uint8_t data[] = { 0x5c, 0x79, 0x8c, 0xd5 };
141   ByteBuffer buffer(data, sizeof(data));
142   ByteCursor cursor(&buffer);
143 
144   uint8_t a, b, c, d, e;
145   EXPECT_TRUE(cursor >> a);
146   EXPECT_EQ(0x5cU, a);
147   EXPECT_EQ(data + 1U, cursor.here());
148   EXPECT_TRUE(((cursor >> b).set_here(data + 3) >> c).set_here(data + 1)
149               >> d >> e);
150   EXPECT_EQ(0x79U, b);
151   EXPECT_EQ(0xd5U, c);
152   EXPECT_EQ(0x79U, d);
153   EXPECT_EQ(0x8cU, e);
154   EXPECT_EQ(data + 3U, cursor.here());
155 }
156 
TEST(BigEndian,Signed1)157 TEST(BigEndian, Signed1) {
158   uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff };
159   ByteBuffer buffer(data, sizeof(data));
160   ByteCursor cursor(&buffer);
161   cursor.set_big_endian(true);
162   int a, b, c, d, e;
163   ASSERT_TRUE(cursor
164               .Read(1, true, &a)
165               .Read(1, true, &b)
166               .Read(1, true, &c)
167               .Read(1, true, &d));
168   EXPECT_EQ(0,     a);
169   EXPECT_EQ(0x7f,  b);
170   EXPECT_EQ(-0x80, c);
171   EXPECT_EQ(-1,    d);
172   EXPECT_TRUE(cursor.AtEnd());
173   EXPECT_FALSE(cursor.Read(1, true, &e));
174 }
175 
TEST(BigEndian,Signed2)176 TEST(BigEndian, Signed2) {
177   uint8_t data[] = { 0x00, 0x00,   0x00, 0x80,   0x7f, 0xff,
178                      0x80, 0x00,   0x80, 0x80,   0xff, 0xff,
179                      0x39, 0xf1,   0x8a, 0xbc,   0x5a, 0xec };
180   ByteBuffer buffer(data, sizeof(data));
181   ByteCursor cursor(&buffer, true);
182   int a, b, c, d, e, f, g, h, i, j;
183   ASSERT_TRUE(cursor
184               .Read(2, true, &a)
185               .Read(2, true, &b)
186               .Read(2, true, &c)
187               .Read(2, true, &d)
188               .Read(2, true, &e)
189               .Read(2, true, &f)
190               .Read(2, true, &g)
191               .Read(2, true, &h)
192               .Read(2, true, &i));
193   EXPECT_EQ(0,       a);
194   EXPECT_EQ(0x80,    b);
195   EXPECT_EQ(0x7fff,  c);
196   EXPECT_EQ(-0x8000, d);
197   EXPECT_EQ(-0x7f80, e);
198   EXPECT_EQ(-1,      f);
199   EXPECT_EQ(0x39f1,  g);
200   EXPECT_EQ(-0x7544, h);
201   EXPECT_EQ(0x5aec,  i);
202   EXPECT_TRUE(cursor.AtEnd());
203   EXPECT_FALSE(cursor.Read(2, true, &j));
204 }
205 
TEST(BigEndian,Signed4)206 TEST(BigEndian, Signed4) {
207   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00,
208                      0x7f, 0xff, 0xff, 0xff,
209                      0x80, 0x00, 0x00, 0x00,
210                      0xff, 0xff, 0xff, 0xff,
211                      0xb6, 0xb1, 0xff, 0xef,
212                      0x19, 0x6a, 0xca, 0x46 };
213   ByteBuffer buffer(data, sizeof(data));
214   ByteCursor cursor(&buffer);
215   cursor.set_big_endian(true);
216   int64_t a, b, c, d, e, f, g;
217   ASSERT_TRUE(cursor
218               .Read(4, true, &a)
219               .Read(4, true, &b)
220               .Read(4, true, &c)
221               .Read(4, true, &d)
222               .Read(4, true, &e)
223               .Read(4, true, &f));
224   EXPECT_EQ(0,                    a);
225   EXPECT_EQ(0x7fffffff,           b);
226   EXPECT_EQ(-0x80000000LL,        c);
227   EXPECT_EQ(-1,                   d);
228   EXPECT_EQ((int32_t) 0xb6b1ffef, e);
229   EXPECT_EQ(0x196aca46,           f);
230   EXPECT_TRUE(cursor.AtEnd());
231   EXPECT_FALSE(cursor.Read(4, true, &g));
232 }
233 
TEST(BigEndian,Signed8)234 TEST(BigEndian, Signed8) {
235   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236                      0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
237                      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
239                      0x93, 0x20, 0xd5, 0xe9, 0xd2, 0xd5, 0x87, 0x9c,
240                      0x4e, 0x42, 0x49, 0xd2, 0x7f, 0x84, 0x14, 0xa4 };
241   ByteBuffer buffer(data, sizeof(data));
242   ByteCursor cursor(&buffer, true);
243   int64_t a, b, c, d, e, f, g;
244   ASSERT_TRUE(cursor
245               .Read(8, true, &a)
246               .Read(8, true, &b)
247               .Read(8, true, &c)
248               .Read(8, true, &d)
249               .Read(8, true, &e)
250               .Read(8, true, &f));
251   EXPECT_EQ(0,                               a);
252   EXPECT_EQ(0x7fffffffffffffffLL,            b);
253   EXPECT_EQ(-0x7fffffffffffffffLL - 1,       c);
254   EXPECT_EQ(-1,                              d);
255   EXPECT_EQ((int64_t) 0x9320d5e9d2d5879cULL, e);
256   EXPECT_EQ(0x4e4249d27f8414a4LL,            f);
257   EXPECT_TRUE(cursor.AtEnd());
258   EXPECT_FALSE(cursor.Read(8, true, &g));
259 }
260 
TEST(BigEndian,Unsigned1)261 TEST(BigEndian, Unsigned1) {
262   uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff };
263   ByteBuffer buffer(data, sizeof(data));
264   ByteCursor cursor(&buffer);
265   cursor.set_big_endian(true);
266   int32_t a, b, c, d, e;
267   ASSERT_TRUE(cursor
268               .Read(1, false, &a)
269               .Read(1, false, &b)
270               .Read(1, false, &c)
271               .Read(1, false, &d));
272   EXPECT_EQ(0,    a);
273   EXPECT_EQ(0x7f, b);
274   EXPECT_EQ(0x80, c);
275   EXPECT_EQ(0xff, d);
276   EXPECT_TRUE(cursor.AtEnd());
277   EXPECT_FALSE(cursor.Read(1, false, &e));
278 }
279 
TEST(BigEndian,Unsigned2)280 TEST(BigEndian, Unsigned2) {
281   uint8_t data[] = { 0x00, 0x00,   0x00, 0x80,   0x7f, 0xff,
282                      0x80, 0x00,   0x80, 0x80,   0xff, 0xff,
283                      0x39, 0xf1,   0x8a, 0xbc,   0x5a, 0xec };
284   ByteBuffer buffer(data, sizeof(data));
285   ByteCursor cursor(&buffer, true);
286   int64_t a, b, c, d, e, f, g, h, i, j;
287   ASSERT_TRUE(cursor
288               .Read(2, false, &a)
289               .Read(2, false, &b)
290               .Read(2, false, &c)
291               .Read(2, false, &d)
292               .Read(2, false, &e)
293               .Read(2, false, &f)
294               .Read(2, false, &g)
295               .Read(2, false, &h)
296               .Read(2, false, &i));
297   EXPECT_EQ(0,      a);
298   EXPECT_EQ(0x80,   b);
299   EXPECT_EQ(0x7fff, c);
300   EXPECT_EQ(0x8000, d);
301   EXPECT_EQ(0x8080, e);
302   EXPECT_EQ(0xffff, f);
303   EXPECT_EQ(0x39f1, g);
304   EXPECT_EQ(0x8abc, h);
305   EXPECT_EQ(0x5aec, i);
306   EXPECT_TRUE(cursor.AtEnd());
307   EXPECT_FALSE(cursor.Read(2, false, &j));
308 }
309 
TEST(BigEndian,Unsigned4)310 TEST(BigEndian, Unsigned4) {
311   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00,
312                      0x7f, 0xff, 0xff, 0xff,
313                      0x80, 0x00, 0x00, 0x00,
314                      0xff, 0xff, 0xff, 0xff,
315                      0xb6, 0xb1, 0xff, 0xef,
316                      0x19, 0x6a, 0xca, 0x46 };
317   ByteBuffer buffer(data, sizeof(data));
318   ByteCursor cursor(&buffer);
319   cursor.set_big_endian(true);
320   int64_t a, b, c, d, e, f, g;
321   ASSERT_TRUE(cursor
322               .Read(4, false, &a)
323               .Read(4, false, &b)
324               .Read(4, false, &c)
325               .Read(4, false, &d)
326               .Read(4, false, &e)
327               .Read(4, false, &f));
328   EXPECT_EQ(0,          a);
329   EXPECT_EQ(0x7fffffff, b);
330   EXPECT_EQ(0x80000000, c);
331   EXPECT_EQ(0xffffffff, d);
332   EXPECT_EQ(0xb6b1ffef, e);
333   EXPECT_EQ(0x196aca46, f);
334   EXPECT_TRUE(cursor.AtEnd());
335   EXPECT_FALSE(cursor.Read(4, false, &g));
336 }
337 
TEST(BigEndian,Unsigned8)338 TEST(BigEndian, Unsigned8) {
339   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340                      0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
341                      0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
343                      0x93, 0x20, 0xd5, 0xe9, 0xd2, 0xd5, 0x87, 0x9c,
344                      0x4e, 0x42, 0x49, 0xd2, 0x7f, 0x84, 0x14, 0xa4 };
345   ByteBuffer buffer(data, sizeof(data));
346   ByteCursor cursor(&buffer, true);
347   uint64_t a, b, c, d, e, f, g;
348   ASSERT_TRUE(cursor
349               .Read(8, false, &a)
350               .Read(8, false, &b)
351               .Read(8, false, &c)
352               .Read(8, false, &d)
353               .Read(8, false, &e)
354               .Read(8, false, &f));
355   EXPECT_EQ(0U,                    a);
356   EXPECT_EQ(0x7fffffffffffffffULL, b);
357   EXPECT_EQ(0x8000000000000000ULL, c);
358   EXPECT_EQ(0xffffffffffffffffULL, d);
359   EXPECT_EQ(0x9320d5e9d2d5879cULL, e);
360   EXPECT_EQ(0x4e4249d27f8414a4ULL, f);
361   EXPECT_TRUE(cursor.AtEnd());
362   EXPECT_FALSE(cursor.Read(8, false, &g));
363 }
364 
TEST(LittleEndian,Signed1)365 TEST(LittleEndian, Signed1) {
366   uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff };
367   ByteBuffer buffer(data, sizeof(data));
368   ByteCursor cursor(&buffer);
369   int32_t a, b, c, d, e;
370   ASSERT_TRUE(cursor
371               .Read(1, true, &a)
372               .Read(1, true, &b)
373               .Read(1, true, &c)
374               .Read(1, true, &d));
375   EXPECT_EQ(0,     a);
376   EXPECT_EQ(0x7f,  b);
377   EXPECT_EQ(-0x80, c);
378   EXPECT_EQ(-1,    d);
379   EXPECT_TRUE(cursor.AtEnd());
380   EXPECT_FALSE(cursor.Read(1, true, &e));
381 }
382 
TEST(LittleEndian,Signed2)383 TEST(LittleEndian, Signed2) {
384   uint8_t data[] = { 0x00, 0x00,   0x80, 0x00,   0xff, 0x7f,
385                      0x00, 0x80,   0x80, 0x80,   0xff, 0xff,
386                      0xf1, 0x39,   0xbc, 0x8a,   0xec, 0x5a };
387   ByteBuffer buffer(data, sizeof(data));
388   ByteCursor cursor(&buffer, false);
389   int32_t a, b, c, d, e, f, g, h, i, j;
390   ASSERT_TRUE(cursor
391               .Read(2, true, &a)
392               .Read(2, true, &b)
393               .Read(2, true, &c)
394               .Read(2, true, &d)
395               .Read(2, true, &e)
396               .Read(2, true, &f)
397               .Read(2, true, &g)
398               .Read(2, true, &h)
399               .Read(2, true, &i));
400   EXPECT_EQ(0,       a);
401   EXPECT_EQ(0x80,    b);
402   EXPECT_EQ(0x7fff,  c);
403   EXPECT_EQ(-0x8000, d);
404   EXPECT_EQ(-0x7f80, e);
405   EXPECT_EQ(-1,      f);
406   EXPECT_EQ(0x39f1,  g);
407   EXPECT_EQ(-0x7544, h);
408   EXPECT_EQ(0x5aec,  i);
409   EXPECT_TRUE(cursor.AtEnd());
410   EXPECT_FALSE(cursor.Read(2, true, &j));
411 }
412 
TEST(LittleEndian,Signed4)413 TEST(LittleEndian, Signed4) {
414   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00,
415                      0xff, 0xff, 0xff, 0x7f,
416                      0x00, 0x00, 0x00, 0x80,
417                      0xff, 0xff, 0xff, 0xff,
418                      0xef, 0xff, 0xb1, 0xb6,
419                      0x46, 0xca, 0x6a, 0x19 };
420   ByteBuffer buffer(data, sizeof(data));
421   ByteCursor cursor(&buffer);
422   int64_t a, b, c, d, e, f, g;
423   ASSERT_TRUE(cursor
424               .Read(4, true, &a)
425               .Read(4, true, &b)
426               .Read(4, true, &c)
427               .Read(4, true, &d)
428               .Read(4, true, &e)
429               .Read(4, true, &f));
430   EXPECT_EQ(0,                    a);
431   EXPECT_EQ(0x7fffffff,           b);
432   EXPECT_EQ(-0x80000000LL,        c);
433   EXPECT_EQ(-1,                   d);
434   EXPECT_EQ((int32_t) 0xb6b1ffef, e);
435   EXPECT_EQ(0x196aca46,           f);
436   EXPECT_TRUE(cursor.AtEnd());
437   EXPECT_FALSE(cursor.Read(4, true, &g));
438 }
439 
TEST(LittleEndian,Signed8)440 TEST(LittleEndian, Signed8) {
441   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
443                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
444                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
445                      0x9c, 0x87, 0xd5, 0xd2, 0xe9, 0xd5, 0x20, 0x93,
446                      0xa4, 0x14, 0x84, 0x7f, 0xd2, 0x49, 0x42, 0x4e };
447   ByteBuffer buffer(data, sizeof(data));
448   ByteCursor cursor(&buffer, false);
449   int64_t a, b, c, d, e, f, g;
450   ASSERT_TRUE(cursor
451               .Read(8, true, &a)
452               .Read(8, true, &b)
453               .Read(8, true, &c)
454               .Read(8, true, &d)
455               .Read(8, true, &e)
456               .Read(8, true, &f));
457   EXPECT_EQ(0,                               a);
458   EXPECT_EQ(0x7fffffffffffffffLL,            b);
459   EXPECT_EQ(-0x7fffffffffffffffLL - 1,       c);
460   EXPECT_EQ(-1,                              d);
461   EXPECT_EQ((int64_t) 0x9320d5e9d2d5879cULL, e);
462   EXPECT_EQ(0x4e4249d27f8414a4LL,            f);
463   EXPECT_TRUE(cursor.AtEnd());
464   EXPECT_FALSE(cursor.Read(8, true, &g));
465 }
466 
TEST(LittleEndian,Unsigned1)467 TEST(LittleEndian, Unsigned1) {
468   uint8_t data[] = { 0x00, 0x7f, 0x80, 0xff };
469   ByteBuffer buffer(data, sizeof(data));
470   ByteCursor cursor(&buffer);
471   int32_t a, b, c, d, e;
472   ASSERT_TRUE(cursor
473               .Read(1, false, &a)
474               .Read(1, false, &b)
475               .Read(1, false, &c)
476               .Read(1, false, &d));
477   EXPECT_EQ(0,    a);
478   EXPECT_EQ(0x7f, b);
479   EXPECT_EQ(0x80, c);
480   EXPECT_EQ(0xff, d);
481   EXPECT_TRUE(cursor.AtEnd());
482   EXPECT_FALSE(cursor.Read(1, false, &e));
483 }
484 
TEST(LittleEndian,Unsigned2)485 TEST(LittleEndian, Unsigned2) {
486   uint8_t data[] = { 0x00, 0x00,   0x80, 0x00,   0xff, 0x7f,
487                      0x00, 0x80,   0x80, 0x80,   0xff, 0xff,
488                      0xf1, 0x39,   0xbc, 0x8a,   0xec, 0x5a };
489   ByteBuffer buffer(data, sizeof(data));
490   ByteCursor cursor(&buffer);
491   int32_t a, b, c, d, e, f, g, h, i, j;
492   ASSERT_TRUE(cursor
493               .Read(2, false, &a)
494               .Read(2, false, &b)
495               .Read(2, false, &c)
496               .Read(2, false, &d)
497               .Read(2, false, &e)
498               .Read(2, false, &f)
499               .Read(2, false, &g)
500               .Read(2, false, &h)
501               .Read(2, false, &i));
502   EXPECT_EQ(0,      a);
503   EXPECT_EQ(0x80,   b);
504   EXPECT_EQ(0x7fff, c);
505   EXPECT_EQ(0x8000, d);
506   EXPECT_EQ(0x8080, e);
507   EXPECT_EQ(0xffff, f);
508   EXPECT_EQ(0x39f1, g);
509   EXPECT_EQ(0x8abc, h);
510   EXPECT_EQ(0x5aec, i);
511   EXPECT_TRUE(cursor.AtEnd());
512   EXPECT_FALSE(cursor.Read(2, false, &j));
513 }
514 
TEST(LittleEndian,Unsigned4)515 TEST(LittleEndian, Unsigned4) {
516   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00,
517                      0xff, 0xff, 0xff, 0x7f,
518                      0x00, 0x00, 0x00, 0x80,
519                      0xff, 0xff, 0xff, 0xff,
520                      0xef, 0xff, 0xb1, 0xb6,
521                      0x46, 0xca, 0x6a, 0x19 };
522   ByteBuffer buffer(data, sizeof(data));
523   ByteCursor cursor(&buffer);
524   int64_t a, b, c, d, e, f, g;
525   ASSERT_TRUE(cursor
526               .Read(4, false, &a)
527               .Read(4, false, &b)
528               .Read(4, false, &c)
529               .Read(4, false, &d)
530               .Read(4, false, &e)
531               .Read(4, false, &f));
532   EXPECT_EQ(0,          a);
533   EXPECT_EQ(0x7fffffff, b);
534   EXPECT_EQ(0x80000000, c);
535   EXPECT_EQ(0xffffffff, d);
536   EXPECT_EQ(0xb6b1ffef, e);
537   EXPECT_EQ(0x196aca46, f);
538   EXPECT_TRUE(cursor.AtEnd());
539   EXPECT_FALSE(cursor.Read(4, false, &g));
540 }
541 
TEST(LittleEndian,Unsigned8)542 TEST(LittleEndian, Unsigned8) {
543   uint8_t data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
545                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
546                      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
547                      0x9c, 0x87, 0xd5, 0xd2, 0xe9, 0xd5, 0x20, 0x93,
548                      0xa4, 0x14, 0x84, 0x7f, 0xd2, 0x49, 0x42, 0x4e };
549   ByteBuffer buffer(data, sizeof(data));
550   ByteCursor cursor(&buffer);
551   uint64_t a, b, c, d, e, f, g;
552   ASSERT_TRUE(cursor
553               .Read(8, false, &a)
554               .Read(8, false, &b)
555               .Read(8, false, &c)
556               .Read(8, false, &d)
557               .Read(8, false, &e)
558               .Read(8, false, &f));
559   EXPECT_EQ(0U,                    a);
560   EXPECT_EQ(0x7fffffffffffffffULL, b);
561   EXPECT_EQ(0x8000000000000000ULL, c);
562   EXPECT_EQ(0xffffffffffffffffULL, d);
563   EXPECT_EQ(0x9320d5e9d2d5879cULL, e);
564   EXPECT_EQ(0x4e4249d27f8414a4ULL, f);
565   EXPECT_TRUE(cursor.AtEnd());
566   EXPECT_FALSE(cursor.Read(8, false, &g));
567 }
568 
TEST(Extractor,Signed1)569 TEST(Extractor, Signed1) {
570   uint8_t data[] = { 0xfd };
571   ByteBuffer buffer(data, sizeof(data));
572   ByteCursor cursor(&buffer);
573   int8_t a;
574   EXPECT_TRUE(cursor >> a);
575   EXPECT_EQ(-3, a);
576   EXPECT_FALSE(cursor >> a);
577 }
578 
TEST(Extractor,Signed2)579 TEST(Extractor, Signed2) {
580   uint8_t data[] = { 0x13, 0xcd };
581   ByteBuffer buffer(data, sizeof(data));
582   ByteCursor cursor(&buffer);
583   int16_t a;
584   EXPECT_TRUE(cursor >> a);
585   EXPECT_EQ(-13037, a);
586   EXPECT_FALSE(cursor >> a);
587 }
588 
TEST(Extractor,Signed4)589 TEST(Extractor, Signed4) {
590   uint8_t data[] = { 0xd2, 0xe4, 0x53, 0xe9 };
591   ByteBuffer buffer(data, sizeof(data));
592   ByteCursor cursor(&buffer);
593   int32_t a;
594   // For some reason, G++ 4.4.1 complains:
595   //   warning: array subscript is above array bounds
596   // in ByteCursor::Read(size_t, bool, T *) as it inlines this call, but
597   // I'm not able to see how such a reference would occur.
598   EXPECT_TRUE(cursor >> a);
599   EXPECT_EQ(-380377902, a);
600   EXPECT_FALSE(cursor >> a);
601 }
602 
TEST(Extractor,Unsigned1)603 TEST(Extractor, Unsigned1) {
604   uint8_t data[] = { 0xfd };
605   ByteBuffer buffer(data, sizeof(data));
606   ByteCursor cursor(&buffer);
607   uint8_t a;
608   EXPECT_TRUE(cursor >> a);
609   EXPECT_EQ(0xfd, a);
610   EXPECT_FALSE(cursor >> a);
611 }
612 
TEST(Extractor,Unsigned2)613 TEST(Extractor, Unsigned2) {
614   uint8_t data[] = { 0x13, 0xcd };
615   ByteBuffer buffer(data, sizeof(data));
616   ByteCursor cursor(&buffer);
617   uint16_t a;
618   EXPECT_TRUE(cursor >> a);
619   EXPECT_EQ(0xcd13, a);
620   EXPECT_FALSE(cursor >> a);
621 }
622 
TEST(Extractor,Unsigned4)623 TEST(Extractor, Unsigned4) {
624   uint8_t data[] = { 0xd2, 0xe4, 0x53, 0xe9 };
625   ByteBuffer buffer(data, sizeof(data));
626   ByteCursor cursor(&buffer);
627   uint32_t a;
628   // For some reason, G++ 4.4.1 complains:
629   //   warning: array subscript is above array bounds
630   // in ByteCursor::Read(size_t, bool, T *) as it inlines this call, but
631   // I'm not able to see how such a reference would occur.
632   EXPECT_TRUE(cursor >> a);
633   EXPECT_EQ(0xe953e4d2, a);
634   EXPECT_FALSE(cursor >> a);
635   EXPECT_FALSE(cursor >> a);
636 }
637 
TEST(Extractor,Mixed)638 TEST(Extractor, Mixed) {
639   uint8_t data[] = { 0x42,
640                      0x25, 0x0b,
641                      0x3d, 0x25, 0xed, 0x2a,
642                      0xec, 0x16, 0x9e, 0x14, 0x61, 0x5b, 0x2c, 0xcf,
643                      0xd8,
644                      0x22, 0xa5,
645                      0x3a, 0x02, 0x6a, 0xd7,
646                      0x93, 0x2a, 0x2d, 0x8d, 0xb4, 0x95, 0xe0, 0xc6 };
647   ByteBuffer buffer(data, sizeof(data));
648   ByteCursor cursor(&buffer);
649   cursor.set_big_endian(true);
650 
651   uint8_t a;
652   uint16_t b;
653   uint32_t c;
654   uint64_t d;
655   int8_t e;
656   int16_t f;
657   int32_t g;
658   int64_t h;
659   int z;
660   EXPECT_FALSE(cursor.AtEnd());
661   EXPECT_TRUE(cursor >> a >> b >> c >> d >> e >> f >> g >> h);
662   EXPECT_EQ(0x42U, a);
663   EXPECT_EQ(0x250bU, b);
664   EXPECT_EQ(0x3d25ed2aU, c);
665   EXPECT_EQ(0xec169e14615b2ccfULL, d);
666   EXPECT_EQ(-40, e);
667   EXPECT_EQ(0x22a5, f);
668   EXPECT_EQ(0x3a026ad7, g);
669   EXPECT_EQ(-7842405714468937530LL, h);
670 
671   EXPECT_TRUE(cursor.AtEnd());
672   EXPECT_FALSE(cursor >> z);
673 }
674 
TEST(Strings,Zero)675 TEST(Strings, Zero) {
676   uint8_t data[] = { 0xa6 };
677   ByteBuffer buffer(data, 0);
678   ByteCursor cursor(&buffer);
679 
680   uint8_t received[1];
681   received[0] = 0xc2;
682   EXPECT_TRUE(cursor.Read(received, 0));
683   EXPECT_EQ(0xc2U, received[0]);
684 }
685 
TEST(Strings,Some)686 TEST(Strings, Some) {
687   uint8_t data[] = { 0x5d, 0x31, 0x09, 0xa6, 0x2e, 0x2c, 0x83, 0xbb };
688   ByteBuffer buffer(data, sizeof(data));
689   ByteCursor cursor(&buffer);
690 
691   uint8_t received[7] = { 0xa7, 0xf7, 0x43, 0x0c, 0x27, 0xea, 0xed };
692   EXPECT_TRUE(cursor.Skip(2).Read(received, 5));
693   uint8_t expected[7] = { 0x09, 0xa6, 0x2e, 0x2c, 0x83, 0xea, 0xed };
694   EXPECT_TRUE(memcmp(received, expected, 7) == 0);
695 }
696 
TEST(Strings,TooMuch)697 TEST(Strings, TooMuch) {
698   uint8_t data[] = { 0x5d, 0x31, 0x09, 0xa6, 0x2e, 0x2c, 0x83, 0xbb };
699   ByteBuffer buffer(data, sizeof(data));
700   ByteCursor cursor(&buffer);
701 
702   uint8_t received1[3];
703   uint8_t received2[3];
704   uint8_t received3[3];
705   EXPECT_FALSE(cursor
706                .Read(received1, 3)
707                .Read(received2, 3)
708                .Read(received3, 3));
709   uint8_t expected1[3] = { 0x5d, 0x31, 0x09 };
710   uint8_t expected2[3] = { 0xa6, 0x2e, 0x2c };
711 
712   EXPECT_TRUE(memcmp(received1, expected1, 3) == 0);
713   EXPECT_TRUE(memcmp(received2, expected2, 3) == 0);
714 }
715 
TEST(Strings,PointTo)716 TEST(Strings, PointTo) {
717   uint8_t data[] = { 0x83, 0x80, 0xb4, 0x38, 0x00, 0x2c, 0x0a, 0x27 };
718   ByteBuffer buffer(data, sizeof(data));
719   ByteCursor cursor(&buffer);
720 
721   const uint8_t *received1;
722   const uint8_t *received2;
723   const uint8_t *received3;
724   const uint8_t *received4;
725   EXPECT_FALSE(cursor
726                .PointTo(&received1, 3)
727                .PointTo(&received2, 3)
728                .PointTo(&received3)
729                .PointTo(&received4, 3));
730   EXPECT_EQ(data + 0, received1);
731   EXPECT_EQ(data + 3, received2);
732   EXPECT_EQ(data + 6, received3);
733   EXPECT_EQ(NULL, received4);
734 }
735 
TEST(Strings,CString)736 TEST(Strings, CString) {
737   uint8_t data[] = "abc\0\0foo";
738   ByteBuffer buffer(data, sizeof(data) - 1);  // don't include terminating '\0'
739   ByteCursor cursor(&buffer);
740 
741   string a, b, c;
742   EXPECT_TRUE(cursor.CString(&a).CString(&b));
743   EXPECT_EQ("abc", a);
744   EXPECT_EQ("", b);
745   EXPECT_FALSE(cursor.CString(&c));
746   EXPECT_EQ("", c);
747   EXPECT_TRUE(cursor.AtEnd());
748 }
749 
TEST(Strings,CStringLimit)750 TEST(Strings, CStringLimit) {
751   uint8_t data[] = "abcdef\0\0foobar";
752   ByteBuffer buffer(data, sizeof(data) - 1);  // don't include terminating '\0'
753   ByteCursor cursor(&buffer);
754 
755   string a, b, c, d, e;
756 
757   EXPECT_TRUE(cursor.CString(&a, 3));
758   EXPECT_EQ("abc", a);
759 
760   EXPECT_TRUE(cursor.CString(&b, 0));
761   EXPECT_EQ("", b);
762 
763   EXPECT_TRUE(cursor.CString(&c, 6));
764   EXPECT_EQ("def", c);
765 
766   EXPECT_TRUE(cursor.CString(&d, 4));
767   EXPECT_EQ("ooba", d);
768 
769   EXPECT_FALSE(cursor.CString(&e, 4));
770   EXPECT_EQ("", e);
771 
772   EXPECT_TRUE(cursor.AtEnd());
773 }
774 
775 //  uint8_t data[] = { 0xa6, 0x54, 0xdf, 0x67, 0x51, 0x43, 0xac, 0xf1 };
776 //  ByteBuffer buffer(data, sizeof(data));
777