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