1 //===-- StreamTest.cpp ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Utility/StreamString.h"
10 #include "gtest/gtest.h"
11 
12 using namespace lldb_private;
13 
14 namespace {
15 struct StreamTest : ::testing::Test {
16   // Note: Stream is an abstract class, so we use StreamString to test it. To
17   // make it easier to change this later, only methods in this class explicitly
18   // refer to the StringStream class.
19   StreamString s;
20   // We return here a std::string because that way gtest can print better
21   // assertion messages.
22   std::string TakeValue() {
23     std::string result = s.GetString().str();
24     s.Clear();
25     return result;
26   }
27 };
28 }
29 
30 namespace {
31 // A StreamTest where we expect the Stream output to be binary.
32 struct BinaryStreamTest : StreamTest {
33   void SetUp() override {
34     s.GetFlags().Set(Stream::eBinary);
35   }
36 };
37 }
38 
39 TEST_F(StreamTest, AddressPrefix) {
40   DumpAddress(s.AsRawOstream(), 0x1, 1, "foo");
41   EXPECT_EQ("foo0x01", TakeValue());
42 }
43 
44 TEST_F(StreamTest, AddressEmptyPrefix) {
45   DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr);
46   EXPECT_EQ("0x01", TakeValue());
47   DumpAddress(s.AsRawOstream(), 0x1, 1, "");
48   EXPECT_EQ("0x01", TakeValue());
49 }
50 
51 TEST_F(StreamTest, AddressSuffix) {
52   DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr, "foo");
53   EXPECT_EQ("0x01foo", TakeValue());
54 }
55 
56 TEST_F(StreamTest, AddressNoSuffix) {
57   DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr, nullptr);
58   EXPECT_EQ("0x01", TakeValue());
59   DumpAddress(s.AsRawOstream(), 0x1, 1, nullptr, "");
60   EXPECT_EQ("0x01", TakeValue());
61 }
62 
63 TEST_F(StreamTest, AddressPrefixAndSuffix) {
64   DumpAddress(s.AsRawOstream(), 0x1, 1, "foo", "bar");
65   EXPECT_EQ("foo0x01bar", TakeValue());
66 }
67 
68 TEST_F(StreamTest, AddressSize) {
69   DumpAddress(s.AsRawOstream(), 0x0, 0);
70   EXPECT_EQ("0x0", TakeValue());
71   DumpAddress(s.AsRawOstream(), 0x1, 0);
72   EXPECT_EQ("0x1", TakeValue());
73 
74   DumpAddress(s.AsRawOstream(), 0x1, 1);
75   EXPECT_EQ("0x01", TakeValue());
76   DumpAddress(s.AsRawOstream(), 0xf1, 1);
77   EXPECT_EQ("0xf1", TakeValue());
78   DumpAddress(s.AsRawOstream(), 0xff, 1);
79   EXPECT_EQ("0xff", TakeValue());
80   DumpAddress(s.AsRawOstream(), 0x100, 1);
81   EXPECT_EQ("0x100", TakeValue());
82 
83   DumpAddress(s.AsRawOstream(), 0xf00, 4);
84   EXPECT_EQ("0x00000f00", TakeValue());
85   DumpAddress(s.AsRawOstream(), 0x100, 8);
86   EXPECT_EQ("0x0000000000000100", TakeValue());
87 }
88 
89 TEST_F(StreamTest, AddressRange) {
90   DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 2);
91   EXPECT_EQ("[0x0100-0x0101)", TakeValue());
92 }
93 
94 TEST_F(StreamTest, AddressRangeEmptyRange) {
95   DumpAddressRange(s.AsRawOstream(), 0x100, 0x100, 2);
96   EXPECT_EQ("[0x0100-0x0100)", TakeValue());
97   DumpAddressRange(s.AsRawOstream(), 0x0, 0x0, 2);
98   EXPECT_EQ("[0x0000-0x0000)", TakeValue());
99 }
100 
101 TEST_F(StreamTest, AddressRangeInvalidRange) {
102   DumpAddressRange(s.AsRawOstream(), 0x100, 0x0FF, 2);
103   EXPECT_EQ("[0x0100-0x00ff)", TakeValue());
104   DumpAddressRange(s.AsRawOstream(), 0x100, 0x0, 2);
105   EXPECT_EQ("[0x0100-0x0000)", TakeValue());
106 }
107 
108 TEST_F(StreamTest, AddressRangeSize) {
109   DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 0);
110   EXPECT_EQ("[0x100-0x101)", TakeValue());
111   DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 2);
112   EXPECT_EQ("[0x0100-0x0101)", TakeValue());
113   DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 4);
114   EXPECT_EQ("[0x00000100-0x00000101)", TakeValue());
115 
116   DumpAddressRange(s.AsRawOstream(), 0x100, 0x101, 4);
117   EXPECT_EQ("[0x00000100-0x00000101)", TakeValue());
118   DumpAddressRange(s.AsRawOstream(), 0x1, 0x101, 4);
119   EXPECT_EQ("[0x00000001-0x00000101)", TakeValue());
120   DumpAddressRange(s.AsRawOstream(), 0x101, 0x1, 4);
121   EXPECT_EQ("[0x00000101-0x00000001)", TakeValue());
122 
123   DumpAddressRange(s.AsRawOstream(), 0x1, 0x101, 1);
124   EXPECT_EQ("[0x01-0x101)", TakeValue());
125 }
126 
127 TEST_F(StreamTest, ChangingByteOrder) {
128   s.SetByteOrder(lldb::eByteOrderPDP);
129   EXPECT_EQ(lldb::eByteOrderPDP, s.GetByteOrder());
130 }
131 
132 TEST_F(StreamTest, PutChar) {
133   s.PutChar('a');
134   EXPECT_EQ(1U, s.GetWrittenBytes());
135   EXPECT_EQ("a", TakeValue());
136 
137   s.PutChar('1');
138   EXPECT_EQ(1U, s.GetWrittenBytes());
139   EXPECT_EQ("1", TakeValue());
140 }
141 
142 TEST_F(StreamTest, PutCharWhitespace) {
143   s.PutChar(' ');
144   EXPECT_EQ(1U, s.GetWrittenBytes());
145   EXPECT_EQ(" ", TakeValue());
146 
147   s.PutChar('\n');
148   EXPECT_EQ(1U, s.GetWrittenBytes());
149   EXPECT_EQ("\n", TakeValue());
150 
151   s.PutChar('\r');
152   EXPECT_EQ(1U, s.GetWrittenBytes());
153   EXPECT_EQ("\r", TakeValue());
154 
155   s.PutChar('\t');
156   EXPECT_EQ(1U, s.GetWrittenBytes());
157   EXPECT_EQ("\t", TakeValue());
158 }
159 
160 TEST_F(StreamTest, PutCString) {
161   s.PutCString("");
162   EXPECT_EQ(0U, s.GetWrittenBytes());
163   EXPECT_EQ("", TakeValue());
164 
165   s.PutCString("foobar");
166   EXPECT_EQ(6U, s.GetWrittenBytes());
167   EXPECT_EQ("foobar", TakeValue());
168 
169   s.PutCString(" ");
170   EXPECT_EQ(1U, s.GetWrittenBytes());
171   EXPECT_EQ(" ", TakeValue());
172 }
173 
174 TEST_F(StreamTest, PutCStringWithStringRef) {
175   s.PutCString(llvm::StringRef(""));
176   EXPECT_EQ(0U, s.GetWrittenBytes());
177   EXPECT_EQ("", TakeValue());
178 
179   s.PutCString(llvm::StringRef("foobar"));
180   EXPECT_EQ(6U, s.GetWrittenBytes());
181   EXPECT_EQ("foobar", TakeValue());
182 
183   s.PutCString(llvm::StringRef(" "));
184   EXPECT_EQ(1U, s.GetWrittenBytes());
185   EXPECT_EQ(" ", TakeValue());
186 }
187 
188 TEST_F(StreamTest, QuotedCString) {
189   s.QuotedCString("foo");
190   EXPECT_EQ(5U, s.GetWrittenBytes());
191   EXPECT_EQ(R"("foo")", TakeValue());
192 
193   s.QuotedCString("ba r");
194   EXPECT_EQ(6U, s.GetWrittenBytes());
195   EXPECT_EQ(R"("ba r")", TakeValue());
196 
197   s.QuotedCString(" ");
198   EXPECT_EQ(3U, s.GetWrittenBytes());
199   EXPECT_EQ(R"(" ")", TakeValue());
200 }
201 
202 TEST_F(StreamTest, PutCharNull) {
203   s.PutChar('\0');
204   EXPECT_EQ(1U, s.GetWrittenBytes());
205   EXPECT_EQ(std::string("\0", 1), TakeValue());
206 
207   s.PutChar('a');
208   EXPECT_EQ(1U, s.GetWrittenBytes());
209   EXPECT_EQ(std::string("a", 1), TakeValue());
210 }
211 
212 TEST_F(StreamTest, PutStringAsRawHex8) {
213   s.PutStringAsRawHex8("");
214   EXPECT_EQ(0U, s.GetWrittenBytes());
215   EXPECT_EQ("", TakeValue());
216 
217   s.PutStringAsRawHex8("foobar");
218   EXPECT_EQ(12U, s.GetWrittenBytes());
219   EXPECT_EQ("666f6f626172", TakeValue());
220 
221   s.PutStringAsRawHex8(" ");
222   EXPECT_EQ(2U, s.GetWrittenBytes());
223   EXPECT_EQ("20", TakeValue());
224 }
225 
226 TEST_F(StreamTest, PutHex8) {
227   s.PutHex8((uint8_t)55);
228   EXPECT_EQ(2U, s.GetWrittenBytes());
229   EXPECT_EQ("37", TakeValue());
230 
231   s.PutHex8(std::numeric_limits<uint8_t>::max());
232   EXPECT_EQ(2U, s.GetWrittenBytes());
233   EXPECT_EQ("ff", TakeValue());
234 
235   s.PutHex8((uint8_t)0);
236   EXPECT_EQ(2U, s.GetWrittenBytes());
237   EXPECT_EQ("00", TakeValue());
238 }
239 
240 TEST_F(StreamTest, PutNHex8) {
241   s.PutNHex8(0, (uint8_t)55);
242   EXPECT_EQ(0U, s.GetWrittenBytes());
243   EXPECT_EQ("", TakeValue());
244 
245   s.PutNHex8(1, (uint8_t)55);
246   EXPECT_EQ(2U, s.GetWrittenBytes());
247   EXPECT_EQ("37", TakeValue());
248 
249   s.PutNHex8(2, (uint8_t)55);
250   EXPECT_EQ(4U, s.GetWrittenBytes());
251   EXPECT_EQ("3737", TakeValue());
252 
253   s.PutNHex8(1, (uint8_t)56);
254   EXPECT_EQ(2U, s.GetWrittenBytes());
255   EXPECT_EQ("38", TakeValue());
256 }
257 
258 TEST_F(StreamTest, PutHex16ByteOrderLittle) {
259   s.PutHex16(0x1234U, lldb::eByteOrderLittle);
260   EXPECT_EQ(4U, s.GetWrittenBytes());
261   EXPECT_EQ("3412", TakeValue());
262 
263   s.PutHex16(std::numeric_limits<uint16_t>::max(), lldb::eByteOrderLittle);
264   EXPECT_EQ(4U, s.GetWrittenBytes());
265   EXPECT_EQ("ffff", TakeValue());
266 
267   s.PutHex16(0U, lldb::eByteOrderLittle);
268   EXPECT_EQ(4U, s.GetWrittenBytes());
269   EXPECT_EQ("0000", TakeValue());
270 }
271 
272 TEST_F(StreamTest, PutHex16ByteOrderBig) {
273   s.PutHex16(0x1234U, lldb::eByteOrderBig);
274   EXPECT_EQ(4U, s.GetWrittenBytes());
275   EXPECT_EQ("1234", TakeValue());
276 
277   s.PutHex16(std::numeric_limits<uint16_t>::max(), lldb::eByteOrderBig);
278   EXPECT_EQ(4U, s.GetWrittenBytes());
279   EXPECT_EQ("ffff", TakeValue());
280 
281   s.PutHex16(0U, lldb::eByteOrderBig);
282   EXPECT_EQ(4U, s.GetWrittenBytes());
283   EXPECT_EQ("0000", TakeValue());
284 }
285 
286 TEST_F(StreamTest, PutHex32ByteOrderLittle) {
287   s.PutHex32(0x12345678U, lldb::eByteOrderLittle);
288   EXPECT_EQ(8U, s.GetWrittenBytes());
289   EXPECT_EQ("78563412", TakeValue());
290 
291   s.PutHex32(std::numeric_limits<uint32_t>::max(), lldb::eByteOrderLittle);
292   EXPECT_EQ(8U, s.GetWrittenBytes());
293   EXPECT_EQ("ffffffff", TakeValue());
294 
295   s.PutHex32(0U, lldb::eByteOrderLittle);
296   EXPECT_EQ(8U, s.GetWrittenBytes());
297   EXPECT_EQ("00000000", TakeValue());
298 }
299 
300 TEST_F(StreamTest, PutHex32ByteOrderBig) {
301   s.PutHex32(0x12345678U, lldb::eByteOrderBig);
302   EXPECT_EQ(8U, s.GetWrittenBytes());
303   EXPECT_EQ("12345678", TakeValue());
304 
305   s.PutHex32(std::numeric_limits<uint32_t>::max(), lldb::eByteOrderBig);
306   EXPECT_EQ(8U, s.GetWrittenBytes());
307   EXPECT_EQ("ffffffff", TakeValue());
308 
309   s.PutHex32(0U, lldb::eByteOrderBig);
310   EXPECT_EQ(8U, s.GetWrittenBytes());
311   EXPECT_EQ("00000000", TakeValue());
312 }
313 
314 TEST_F(StreamTest, PutHex64ByteOrderLittle) {
315   s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderLittle);
316   EXPECT_EQ(16U, s.GetWrittenBytes());
317   EXPECT_EQ("efcdab9078563412", TakeValue());
318 
319   s.PutHex64(std::numeric_limits<uint64_t>::max(), lldb::eByteOrderLittle);
320   EXPECT_EQ(16U, s.GetWrittenBytes());
321   EXPECT_EQ("ffffffffffffffff", TakeValue());
322 
323   s.PutHex64(0U, lldb::eByteOrderLittle);
324   EXPECT_EQ(16U, s.GetWrittenBytes());
325   EXPECT_EQ("0000000000000000", TakeValue());
326 }
327 
328 TEST_F(StreamTest, PutHex64ByteOrderBig) {
329   s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderBig);
330   EXPECT_EQ(16U, s.GetWrittenBytes());
331   EXPECT_EQ("1234567890abcdef", TakeValue());
332 
333   s.PutHex64(std::numeric_limits<uint64_t>::max(), lldb::eByteOrderBig);
334   EXPECT_EQ(16U, s.GetWrittenBytes());
335   EXPECT_EQ("ffffffffffffffff", TakeValue());
336 
337   s.PutHex64(0U, lldb::eByteOrderBig);
338   EXPECT_EQ(16U, s.GetWrittenBytes());
339   EXPECT_EQ("0000000000000000", TakeValue());
340 }
341 
342 TEST_F(StreamTest, PutMaxHex64ByteOrderBig) {
343   std::size_t bytes;
344   bytes = s.PutMaxHex64(0x12U, 1, lldb::eByteOrderBig);
345   EXPECT_EQ(2U, bytes);
346   bytes = s.PutMaxHex64(0x1234U, 2, lldb::eByteOrderBig);
347   EXPECT_EQ(4U, bytes);
348   bytes = s.PutMaxHex64(0x12345678U, 4, lldb::eByteOrderBig);
349   EXPECT_EQ(8U, bytes);
350   bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderBig);
351   EXPECT_EQ(16U, bytes);
352   EXPECT_EQ(30U, s.GetWrittenBytes());
353   EXPECT_EQ("121234123456781234567890abcdef", TakeValue());
354 }
355 
356 TEST_F(StreamTest, PutMaxHex64ByteOrderLittle) {
357   std::size_t bytes;
358   bytes = s.PutMaxHex64(0x12U, 1, lldb::eByteOrderLittle);
359   EXPECT_EQ(2U, bytes);
360   bytes = s.PutMaxHex64(0x1234U, 2, lldb::eByteOrderLittle);
361   EXPECT_EQ(4U, bytes);
362   bytes = s.PutMaxHex64(0x12345678U, 4, lldb::eByteOrderLittle);
363   EXPECT_EQ(8U, bytes);
364   bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderLittle);
365   EXPECT_EQ(16U, bytes);
366   EXPECT_EQ(30U, s.GetWrittenBytes());
367   EXPECT_EQ("12341278563412efcdab9078563412", TakeValue());
368 }
369 
370 // Shift operator tests.
371 
372 TEST_F(StreamTest, ShiftOperatorChars) {
373   s << 'a' << 'b';
374   EXPECT_EQ(2U, s.GetWrittenBytes());
375   EXPECT_EQ("ab", TakeValue());
376 }
377 
378 TEST_F(StreamTest, ShiftOperatorStrings) {
379   s << "cstring\n";
380   EXPECT_EQ(8U, s.GetWrittenBytes());
381   s << llvm::StringRef("llvm::StringRef\n");
382   EXPECT_EQ(24U, s.GetWrittenBytes());
383   EXPECT_EQ("cstring\nllvm::StringRef\n", TakeValue());
384 }
385 
386 TEST_F(StreamTest, ShiftOperatorPtr) {
387   // This test is a bit tricky because pretty much everything related to
388   // pointer printing seems to lead to UB or IB. So let's make the most basic
389   // test that just checks that we print *something*. This way we at least know
390   // that pointer printing doesn't do really bad things (e.g. crashing, reading
391   // OOB/uninitialized memory which the sanitizers would spot).
392 
393   // Shift our own pointer to the output.
394   int i = 3;
395   int *ptr = &i;
396   s << ptr;
397 
398   EXPECT_NE(0U, s.GetWrittenBytes());
399   EXPECT_TRUE(!TakeValue().empty());
400 }
401 
402 TEST_F(StreamTest, PutPtr) {
403   // See the ShiftOperatorPtr test for the rationale.
404   int i = 3;
405   int *ptr = &i;
406   s.PutPointer(ptr);
407 
408   EXPECT_NE(0U, s.GetWrittenBytes());
409   EXPECT_TRUE(!TakeValue().empty());
410 }
411 
412 // Alias to make it more clear that 'invalid' means for the Stream interface
413 // that it should use the host byte order.
414 const static auto hostByteOrder = lldb::eByteOrderInvalid;
415 
416 // PutRawBytes/PutBytesAsRawHex tests.
417 
418 TEST_F(StreamTest, PutBytesAsRawHex8ToBigEndian) {
419   uint32_t value = 0x12345678;
420   s.PutBytesAsRawHex8(static_cast<void*>(&value), sizeof(value),
421                       hostByteOrder, lldb::eByteOrderBig);
422   EXPECT_EQ(8U, s.GetWrittenBytes());
423   EXPECT_EQ("78563412", TakeValue());
424 }
425 
426 TEST_F(StreamTest, PutRawBytesToBigEndian) {
427   uint32_t value = 0x12345678;
428   s.PutRawBytes(static_cast<void*>(&value), sizeof(value),
429                       hostByteOrder, lldb::eByteOrderBig);
430   EXPECT_EQ(4U, s.GetWrittenBytes());
431   EXPECT_EQ("\x78\x56\x34\x12", TakeValue());
432 }
433 
434 TEST_F(StreamTest, PutBytesAsRawHex8ToLittleEndian) {
435   uint32_t value = 0x12345678;
436   s.PutBytesAsRawHex8(static_cast<void*>(&value), sizeof(value),
437                       hostByteOrder, lldb::eByteOrderLittle);
438   EXPECT_EQ(8U, s.GetWrittenBytes());
439   EXPECT_EQ("12345678", TakeValue());
440 }
441 
442 TEST_F(StreamTest, PutRawBytesToLittleEndian) {
443   uint32_t value = 0x12345678;
444   s.PutRawBytes(static_cast<void*>(&value), sizeof(value),
445                       hostByteOrder, lldb::eByteOrderLittle);
446   EXPECT_EQ(4U, s.GetWrittenBytes());
447   EXPECT_EQ("\x12\x34\x56\x78", TakeValue());
448 }
449 
450 TEST_F(StreamTest, PutBytesAsRawHex8ToMixedEndian) {
451   uint32_t value = 0x12345678;
452   s.PutBytesAsRawHex8(static_cast<void*>(&value), sizeof(value),
453                       hostByteOrder, lldb::eByteOrderPDP);
454 
455   // FIXME: PDP byte order is not actually implemented but Stream just silently
456   // prints the value in some random byte order...
457 #if 0
458   EXPECT_EQ("34127856", TakeValue());
459 #endif
460 }
461 
462 TEST_F(StreamTest, PutRawBytesToMixedEndian) {
463   uint32_t value = 0x12345678;
464   s.PutRawBytes(static_cast<void*>(&value), sizeof(value),
465                       lldb::eByteOrderInvalid, lldb::eByteOrderPDP);
466 
467   // FIXME: PDP byte order is not actually implemented but Stream just silently
468   // prints the value in some random byte order...
469 #if 0
470   EXPECT_EQ("\x34\x12\x78\x56", TakeValue());
471 #endif
472 }
473 
474 // ULEB128 support for binary streams.
475 
476 TEST_F(BinaryStreamTest, PutULEB128OneByte) {
477   auto bytes = s.PutULEB128(0x74ULL);
478   EXPECT_EQ(1U, s.GetWrittenBytes());
479   EXPECT_EQ("\x74", TakeValue());
480   EXPECT_EQ(1U, bytes);
481 }
482 
483 TEST_F(BinaryStreamTest, PutULEB128TwoBytes) {
484   auto bytes = s.PutULEB128(0x1985ULL);
485   EXPECT_EQ(2U, s.GetWrittenBytes());
486   EXPECT_EQ("\x85\x33", TakeValue());
487   EXPECT_EQ(2U, bytes);
488 }
489 
490 TEST_F(BinaryStreamTest, PutULEB128ThreeBytes) {
491   auto bytes = s.PutULEB128(0x5023ULL);
492   EXPECT_EQ(3U, s.GetWrittenBytes());
493   EXPECT_EQ("\xA3\xA0\x1", TakeValue());
494   EXPECT_EQ(3U, bytes);
495 }
496 
497 TEST_F(BinaryStreamTest, PutULEB128FourBytes) {
498   auto bytes = s.PutULEB128(0xA48032ULL);
499   EXPECT_EQ(4U, s.GetWrittenBytes());
500   EXPECT_EQ("\xB2\x80\x92\x5", TakeValue());
501   EXPECT_EQ(4U, bytes);
502 }
503 
504 TEST_F(BinaryStreamTest, PutULEB128FiveBytes) {
505   auto bytes = s.PutULEB128(0x12345678ULL);
506   EXPECT_EQ(5U, s.GetWrittenBytes());
507   EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue());
508   EXPECT_EQ(5U, bytes);
509 }
510 
511 TEST_F(BinaryStreamTest, PutULEB128SixBytes) {
512   auto bytes = s.PutULEB128(0xABFE3FAFDFULL);
513   EXPECT_EQ(6U, s.GetWrittenBytes());
514   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue());
515   EXPECT_EQ(6U, bytes);
516 }
517 
518 TEST_F(BinaryStreamTest, PutULEB128SevenBytes) {
519   auto bytes = s.PutULEB128(0xDABFE3FAFDFULL);
520   EXPECT_EQ(7U, s.GetWrittenBytes());
521   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue());
522   EXPECT_EQ(7U, bytes);
523 }
524 
525 TEST_F(BinaryStreamTest, PutULEB128EightBytes) {
526   auto bytes = s.PutULEB128(0x7CDABFE3FAFDFULL);
527   EXPECT_EQ(8U, s.GetWrittenBytes());
528   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue());
529   EXPECT_EQ(8U, bytes);
530 }
531 
532 TEST_F(BinaryStreamTest, PutULEB128NineBytes) {
533   auto bytes = s.PutULEB128(0x327CDABFE3FAFDFULL);
534   EXPECT_EQ(9U, s.GetWrittenBytes());
535   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue());
536   EXPECT_EQ(9U, bytes);
537 }
538 
539 TEST_F(BinaryStreamTest, PutULEB128MaxValue) {
540   auto bytes = s.PutULEB128(std::numeric_limits<uint64_t>::max());
541   EXPECT_EQ(10U, s.GetWrittenBytes());
542   EXPECT_EQ("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1", TakeValue());
543   EXPECT_EQ(10U, bytes);
544 }
545 
546 TEST_F(BinaryStreamTest, PutULEB128Zero) {
547   auto bytes = s.PutULEB128(0x0U);
548   EXPECT_EQ(1U, s.GetWrittenBytes());
549   EXPECT_EQ(std::string("\0", 1), TakeValue());
550   EXPECT_EQ(1U, bytes);
551 }
552 
553 TEST_F(BinaryStreamTest, PutULEB128One) {
554   auto bytes = s.PutULEB128(0x1U);
555   EXPECT_EQ(1U, s.GetWrittenBytes());
556   EXPECT_EQ("\x1", TakeValue());
557   EXPECT_EQ(1U, bytes);
558 }
559 
560 // SLEB128 support for binary streams.
561 
562 TEST_F(BinaryStreamTest, PutSLEB128OneByte) {
563   auto bytes = s.PutSLEB128(0x74LL);
564   EXPECT_EQ(2U, s.GetWrittenBytes());
565   EXPECT_EQ(std::string("\xF4\0", 2), TakeValue());
566   EXPECT_EQ(2U, bytes);
567 }
568 
569 TEST_F(BinaryStreamTest, PutSLEB128TwoBytes) {
570   auto bytes = s.PutSLEB128(0x1985LL);
571   EXPECT_EQ(2U, s.GetWrittenBytes());
572   EXPECT_EQ("\x85\x33", TakeValue());
573   EXPECT_EQ(2U, bytes);
574 }
575 
576 TEST_F(BinaryStreamTest, PutSLEB128ThreeBytes) {
577   auto bytes = s.PutSLEB128(0x5023LL);
578   EXPECT_EQ(3U, s.GetWrittenBytes());
579   EXPECT_EQ("\xA3\xA0\x1", TakeValue());
580   EXPECT_EQ(3U, bytes);
581 }
582 
583 TEST_F(BinaryStreamTest, PutSLEB128FourBytes) {
584   auto bytes = s.PutSLEB128(0xA48032LL);
585   EXPECT_EQ(4U, s.GetWrittenBytes());
586   EXPECT_EQ("\xB2\x80\x92\x5", TakeValue());
587   EXPECT_EQ(4U, bytes);
588 }
589 
590 TEST_F(BinaryStreamTest, PutSLEB128FiveBytes) {
591   auto bytes = s.PutSLEB128(0x12345678LL);
592   EXPECT_EQ(5U, s.GetWrittenBytes());
593   EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue());
594   EXPECT_EQ(5U, bytes);
595 }
596 
597 TEST_F(BinaryStreamTest, PutSLEB128SixBytes) {
598   auto bytes = s.PutSLEB128(0xABFE3FAFDFLL);
599   EXPECT_EQ(6U, s.GetWrittenBytes());
600   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue());
601   EXPECT_EQ(6U, bytes);
602 }
603 
604 TEST_F(BinaryStreamTest, PutSLEB128SevenBytes) {
605   auto bytes = s.PutSLEB128(0xDABFE3FAFDFLL);
606   EXPECT_EQ(7U, s.GetWrittenBytes());
607   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue());
608   EXPECT_EQ(7U, bytes);
609 }
610 
611 TEST_F(BinaryStreamTest, PutSLEB128EightBytes) {
612   auto bytes = s.PutSLEB128(0x7CDABFE3FAFDFLL);
613   EXPECT_EQ(8U, s.GetWrittenBytes());
614   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue());
615   EXPECT_EQ(8U, bytes);
616 }
617 
618 TEST_F(BinaryStreamTest, PutSLEB128NineBytes) {
619   auto bytes = s.PutSLEB128(0x327CDABFE3FAFDFLL);
620   EXPECT_EQ(9U, s.GetWrittenBytes());
621   EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue());
622   EXPECT_EQ(9U, bytes);
623 }
624 
625 TEST_F(BinaryStreamTest, PutSLEB128MaxValue) {
626   auto bytes = s.PutSLEB128(std::numeric_limits<int64_t>::max());
627   EXPECT_EQ(10U, s.GetWrittenBytes());
628   EXPECT_EQ(std::string("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0", 10), TakeValue());
629   EXPECT_EQ(10U, bytes);
630 }
631 
632 TEST_F(BinaryStreamTest, PutSLEB128Zero) {
633   auto bytes = s.PutSLEB128(0x0);
634   EXPECT_EQ(1U, s.GetWrittenBytes());
635   EXPECT_EQ(std::string("\0", 1), TakeValue());
636   EXPECT_EQ(1U, bytes);
637 }
638 
639 TEST_F(BinaryStreamTest, PutSLEB128One) {
640   auto bytes = s.PutSLEB128(0x1);
641   EXPECT_EQ(1U, s.GetWrittenBytes());
642   EXPECT_EQ(std::string("\x1", 1), TakeValue());
643   EXPECT_EQ(1U, bytes);
644 }
645 
646 // SLEB128/ULEB128 support for non-binary streams.
647 
648 // The logic for this is very simple, so it should be enough to test some basic
649 // use cases.
650 
651 TEST_F(StreamTest, PutULEB128) {
652   auto bytes = s.PutULEB128(0x74ULL);
653   EXPECT_EQ(4U, s.GetWrittenBytes());
654   EXPECT_EQ("0x74", TakeValue());
655   EXPECT_EQ(4U, bytes);
656 }
657 
658 TEST_F(StreamTest, PutSLEB128) {
659   auto bytes = s.PutSLEB128(0x1985LL);
660   EXPECT_EQ(6U, s.GetWrittenBytes());
661   EXPECT_EQ("0x6533", TakeValue());
662   EXPECT_EQ(6U, bytes);
663 }
664