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