xref: /llvm-project/lldb/unittests/Utility/DataEncoderTest.cpp (revision 220854a47bdc0c281dbaafb54411ec65e76212b3)
1 //===-- DataEncoderTest.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 "gtest/gtest.h"
10 
11 #include "lldb/Utility/DataEncoder.h"
12 #include "llvm/ADT/ArrayRef.h"
13 #include <vector>
14 using namespace lldb_private;
15 using namespace llvm;
16 
TEST(DataEncoderTest,PutU8)17 TEST(DataEncoderTest, PutU8) {
18   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
19   const uint32_t addr_size = 4;
20 
21   uint32_t offset = 0;
22   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
23                       addr_size);
24   offset = encoder.PutU8(offset, 11);
25   ASSERT_EQ(offset, 1U);
26   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 2, 3, 4, 5, 6, 7, 8}));
27   offset = encoder.PutU8(offset, 12);
28   ASSERT_EQ(offset, 2U);
29   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 12, 3, 4, 5, 6, 7, 8}));
30   offset = encoder.PutU8(offset, 13);
31   ASSERT_EQ(offset, 3U);
32   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 12, 13, 4, 5, 6, 7, 8}));
33   offset = encoder.PutU8(offset, 14);
34   ASSERT_EQ(offset, 4U);
35   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 12, 13, 14, 5, 6, 7, 8}));
36   // Check that putting a number to an invalid offset doesn't work and returns
37   // an error offset and doesn't modify the buffer.
38   ASSERT_EQ(encoder.PutU8(init.size(), 15), UINT32_MAX);
39   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 12, 13, 14, 5, 6, 7, 8}));
40 }
41 
TEST(DataEncoderTest,AppendUnsignedLittle)42 TEST(DataEncoderTest, AppendUnsignedLittle) {
43   const uint32_t addr_size = 4;
44   std::vector<uint8_t> expected;
45   DataEncoder encoder(lldb::eByteOrderLittle, addr_size);
46   encoder.AppendU8(0x11);
47   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11}));
48   encoder.AppendU16(0x2233);
49   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x33, 0x22}));
50   encoder.AppendU32(0x44556677);
51   ASSERT_EQ(encoder.GetData(),
52             ArrayRef<uint8_t>({0x11, 0x33, 0x22, 0x77, 0x66, 0x55, 0x44}));
53   encoder.AppendU64(0x8899AABBCCDDEEFF);
54   ASSERT_EQ(encoder.GetData(),
55             ArrayRef<uint8_t>({0x11, 0x33, 0x22, 0x77, 0x66, 0x55, 0x44,
56                                0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88}));
57   encoder.AppendU64(0x8899AABBCCDDEEFF);
58 }
59 
TEST(DataEncoderTest,AppendUnsignedBig)60 TEST(DataEncoderTest, AppendUnsignedBig) {
61   const uint32_t addr_size = 4;
62   std::vector<uint8_t> expected;
63   DataEncoder encoder(lldb::eByteOrderBig, addr_size);
64   encoder.AppendU8(0x11);
65   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11}));
66   encoder.AppendU16(0x2233);
67   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x22, 0x33}));
68   encoder.AppendU32(0x44556677);
69   ASSERT_EQ(encoder.GetData(),
70             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}));
71   encoder.AppendU64(0x8899AABBCCDDEEFF);
72   ASSERT_EQ(encoder.GetData(),
73             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
74                                0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}));
75 }
76 
TEST(DataEncoderTest,AppendAddress4Little)77 TEST(DataEncoderTest, AppendAddress4Little) {
78   const uint32_t addr_size = 4;
79   std::vector<uint8_t> expected;
80   DataEncoder encoder(lldb::eByteOrderLittle, addr_size);
81   encoder.AppendAddress(0x11223344);
82   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11}));
83   encoder.AppendAddress(0x55);
84   ASSERT_EQ(encoder.GetData(),
85             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x55, 0x00, 0x00, 0x00}));
86 }
87 
TEST(DataEncoderTest,AppendAddress4Big)88 TEST(DataEncoderTest, AppendAddress4Big) {
89   const uint32_t addr_size = 4;
90   std::vector<uint8_t> expected;
91   DataEncoder encoder(lldb::eByteOrderBig, addr_size);
92   encoder.AppendAddress(0x11223344);
93   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44}));
94   encoder.AppendAddress(0x55);
95   ASSERT_EQ(encoder.GetData(),
96             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00, 0x55}));
97 }
98 
TEST(DataEncoderTest,AppendAddress8Little)99 TEST(DataEncoderTest, AppendAddress8Little) {
100   const uint32_t addr_size = 8;
101   std::vector<uint8_t> expected;
102   DataEncoder encoder(lldb::eByteOrderLittle, addr_size);
103   encoder.AppendAddress(0x11223344);
104   ASSERT_EQ(encoder.GetData(),
105             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
106   encoder.AppendAddress(0x5566778899AABBCC);
107   ASSERT_EQ(encoder.GetData(),
108             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00,
109                                0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55}));
110 }
111 
TEST(DataEncoderTest,AppendAddress8Big)112 TEST(DataEncoderTest, AppendAddress8Big) {
113   const uint32_t addr_size = 8;
114   std::vector<uint8_t> expected;
115   DataEncoder encoder(lldb::eByteOrderBig, addr_size);
116   encoder.AppendAddress(0x11223344);
117   ASSERT_EQ(encoder.GetData(),
118             ArrayRef<uint8_t>({0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44}));
119   encoder.AppendAddress(0x5566778899AABBCC);
120   ASSERT_EQ(encoder.GetData(),
121             ArrayRef<uint8_t>({0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44,
122                                0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}));
123 }
124 
TEST(DataEncoderTest,AppendData)125 TEST(DataEncoderTest, AppendData) {
126   const uint32_t addr_size = 4;
127   std::vector<uint8_t> expected;
128   DataEncoder encoder(lldb::eByteOrderBig, addr_size);
129   // Make sure default constructed StringRef appends nothing
130   encoder.AppendData(StringRef());
131   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({}));
132   // Make sure empty StringRef appends nothing
133   encoder.AppendData(StringRef(""));
134   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({}));
135   // Append some bytes that contains a NULL character
136   encoder.AppendData(StringRef("\x11\x00\x22", 3));
137   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x00, 0x22}));
138 }
139 
TEST(DataEncoderTest,AppendCString)140 TEST(DataEncoderTest, AppendCString) {
141   const uint32_t addr_size = 4;
142   std::vector<uint8_t> expected;
143   DataEncoder encoder(lldb::eByteOrderBig, addr_size);
144   // Make sure default constructed StringRef appends nothing
145   encoder.AppendCString(StringRef());
146   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({}));
147   // Make sure empty StringRef appends a NULL character since the StringRef
148   // doesn't contain a NULL in the referenced string.
149   encoder.AppendCString(StringRef(""));
150   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x00}));
151   // Make sure empty StringRef appends only one NULL character if StringRef
152   // does contain a NULL in the referenced string.
153   encoder.AppendCString(StringRef("\0", 1));
154   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x00, 0x00}));
155   // Append a string where the StringRef doesn't contain a NULL termination
156   // and verify the NULL terminate gets added
157   encoder.AppendCString(StringRef("hello"));
158   ASSERT_EQ(encoder.GetData(),
159             ArrayRef<uint8_t>({0x00, 0x00, 'h', 'e', 'l', 'l', 'o', 0x00}));
160   // Append a string where the StringRef does contain a NULL termination and
161   // verify only one NULL is added
162   encoder.AppendCString(StringRef("world", 6));
163   ASSERT_EQ(encoder.GetData(),
164             ArrayRef<uint8_t>({0x00, 0x00, 'h', 'e', 'l', 'l', 'o', 0x00,
165                                'w', 'o', 'r', 'l', 'd', '\0'}));
166 }
167 
TEST(DataEncoderTest,PutU16Little)168 TEST(DataEncoderTest, PutU16Little) {
169   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
170   const uint32_t addr_size = 4;
171   uint32_t offset = 0;
172   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
173                       addr_size);
174   offset = encoder.PutU16(offset, 11);
175   ASSERT_EQ(offset, 2U);
176   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 3, 4, 5, 6, 7, 8}));
177   offset = encoder.PutU16(offset, 12);
178   ASSERT_EQ(offset, 4U);
179   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 12, 0, 5, 6, 7, 8}));
180   offset = encoder.PutU16(offset, 13);
181   ASSERT_EQ(offset, 6U);
182   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 12, 0, 13, 0, 7, 8}));
183   offset = encoder.PutU16(offset, 14);
184   ASSERT_EQ(offset, 8U);
185   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 12, 0, 13, 0, 14, 0}));
186   // Check that putting a number to an invalid offset doesn't work and returns
187   // an error offset and doesn't modify the buffer.
188   ASSERT_EQ(encoder.PutU16(init.size(), 15), UINT32_MAX);
189   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 12, 0, 13, 0, 14, 0}));
190 }
191 
TEST(DataEncoderTest,PutU16Big)192 TEST(DataEncoderTest, PutU16Big) {
193   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
194   const uint32_t addr_size = 4;
195   uint32_t offset = 0;
196   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderBig,
197                       addr_size);
198   offset = encoder.PutU16(offset, 11);
199   ASSERT_EQ(offset, 2U);
200   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 11, 3, 4, 5, 6, 7, 8}));
201   offset = encoder.PutU16(offset, 12);
202   ASSERT_EQ(offset, 4U);
203   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 11, 0, 12, 5, 6, 7, 8}));
204   offset = encoder.PutU16(offset, 13);
205   ASSERT_EQ(offset, 6U);
206   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 11, 0, 12, 0, 13, 7, 8}));
207   offset = encoder.PutU16(offset, 14);
208   ASSERT_EQ(offset, 8U);
209   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 11, 0, 12, 0, 13, 0, 14}));
210   // Check that putting a number to an invalid offset doesn't work and returns
211   // an error offset and doesn't modify the buffer.
212   ASSERT_EQ(encoder.PutU16(init.size(), 15), UINT32_MAX);
213   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 11, 0, 12, 0, 13, 0, 14}));
214 }
215 
TEST(DataEncoderTest,PutU32Little)216 TEST(DataEncoderTest, PutU32Little) {
217   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
218   const uint32_t addr_size = 4;
219 
220   uint32_t offset = 0;
221   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
222                       addr_size);
223   offset = encoder.PutU32(offset, 11);
224   ASSERT_EQ(offset, 4U);
225   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 0, 0, 5, 6, 7, 8}));
226   offset = encoder.PutU32(offset, 12);
227   ASSERT_EQ(offset, 8u);
228   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 0, 0, 12, 0, 0, 0}));
229   // Check that putting a number to an invalid offset doesn't work and returns
230   // an error offset and doesn't modify the buffer.
231   ASSERT_EQ(encoder.PutU32(init.size(), 15), UINT32_MAX);
232   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 0, 0, 12, 0, 0, 0}));
233 }
234 
TEST(DataEncoderTest,PutU32Big)235 TEST(DataEncoderTest, PutU32Big) {
236   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
237   const uint32_t addr_size = 4;
238 
239   uint32_t offset = 0;
240   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderBig,
241                       addr_size);
242   offset = encoder.PutU32(offset, 11);
243   ASSERT_EQ(offset, 4U);
244   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 0, 0, 11, 5, 6, 7, 8}));
245   offset = encoder.PutU32(offset, 12);
246   ASSERT_EQ(offset, 8U);
247   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 0, 0, 11, 0, 0, 0, 12}));
248   // Check that putting a number to an invalid offset doesn't work and returns
249   // an error offset and doesn't modify the buffer.
250   ASSERT_EQ(encoder.PutU32(init.size(), 15), UINT32_MAX);
251   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 0, 0, 11, 0, 0, 0, 12}));
252 }
253 
TEST(DataEncoderTest,PutU64Little)254 TEST(DataEncoderTest, PutU64Little) {
255   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
256   const uint32_t addr_size = 4;
257   uint32_t offset = 0;
258   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
259                       addr_size);
260   offset = encoder.PutU64(offset, 11);
261   ASSERT_EQ(offset, 8U);
262   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 0, 0, 0, 0, 0, 0}));
263   // Check that putting a number to an invalid offset doesn't work and returns
264   // an error offset and doesn't modify the buffer.
265   ASSERT_EQ(encoder.PutU64(init.size(), 15), UINT32_MAX);
266   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 0, 0, 0, 0, 0, 0, 0}));
267 }
268 
TEST(DataEncoderTest,PutU64Big)269 TEST(DataEncoderTest, PutU64Big) {
270   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
271   const uint32_t addr_size = 4;
272   uint32_t offset = 0;
273   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderBig,
274                       addr_size);
275   offset = encoder.PutU64(offset, 11);
276   ASSERT_EQ(offset, 8U);
277   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 0, 0, 0, 0, 0, 0, 11}));
278   // Check that putting a number to an invalid offset doesn't work and returns
279   // an error offset and doesn't modify the buffer.
280   ASSERT_EQ(encoder.PutU64(init.size(), 15), UINT32_MAX);
281   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0, 0, 0, 0, 0, 0, 0, 11}));
282 }
283 
TEST(DataEncoderTest,PutUnsignedLittle)284 TEST(DataEncoderTest, PutUnsignedLittle) {
285   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
286   const uint32_t addr_size = 4;
287   uint32_t offset = 0;
288   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
289                       addr_size);
290   // Put only the least significant byte from the uint64_t into the encoder
291   offset = encoder.PutUnsigned(0, 1, 0x1122334455667788ULL);
292   ASSERT_EQ(offset, 1U);
293   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x88, 2, 3, 4, 5, 6, 7, 8}));
294 
295   // Put only the least significant 2 byte2 from the uint64_t into the encoder
296   offset = encoder.PutUnsigned(0, 2, 0x1122334455667788ULL);
297   ASSERT_EQ(offset, 2U);
298   ASSERT_EQ(encoder.GetData(),
299             ArrayRef<uint8_t>({0x88, 0x77, 3, 4, 5, 6, 7, 8}));
300 
301   // Put only the least significant 4 bytes from the uint64_t into the encoder
302   offset = encoder.PutUnsigned(0, 4, 0x1122334455667788ULL);
303   ASSERT_EQ(offset, 4U);
304   ASSERT_EQ(encoder.GetData(),
305             ArrayRef<uint8_t>({0x88, 0x77, 0x66, 0x55, 5, 6, 7, 8}));
306 
307   // Put the full uint64_t value into the encoder
308   offset = encoder.PutUnsigned(0, 8, 0x1122334455667788ULL);
309   ASSERT_EQ(offset, 8U);
310   ASSERT_EQ(encoder.GetData(),
311             ArrayRef<uint8_t>({0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11}));
312 }
313 
TEST(DataEncoderTest,PutUnsignedBig)314 TEST(DataEncoderTest, PutUnsignedBig) {
315   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
316   const uint32_t addr_size = 4;
317   uint32_t offset = 0;
318   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderBig,
319                       addr_size);
320   // Put only the least significant byte from the uint64_t into the encoder
321   offset = encoder.PutUnsigned(0, 1, 0x1122334455667788ULL);
322   ASSERT_EQ(offset, 1U);
323   ASSERT_EQ(encoder.GetData(),
324             ArrayRef<uint8_t>({0x88, 2, 3, 4, 5, 6, 7, 8}));
325 
326   // Put only the least significant 2 byte2 from the uint64_t into the encoder
327   offset = encoder.PutUnsigned(0, 2, 0x1122334455667788ULL);
328   ASSERT_EQ(offset, 2U);
329   ASSERT_EQ(encoder.GetData(),
330             ArrayRef<uint8_t>({0x77, 0x88, 3, 4, 5, 6, 7, 8}));
331 
332   // Put only the least significant 4 bytes from the uint64_t into the encoder
333   offset = encoder.PutUnsigned(0, 4, 0x1122334455667788ULL);
334   ASSERT_EQ(offset, 4U);
335   ASSERT_EQ(encoder.GetData(),
336             ArrayRef<uint8_t>({0x55, 0x66, 0x77, 0x88, 5, 6, 7, 8}));
337 
338   // Put the full uint64_t value into the encoder
339   offset = encoder.PutUnsigned(0, 8, 0x1122334455667788ULL);
340   ASSERT_EQ(offset, 8U);
341   ASSERT_EQ(encoder.GetData(),
342             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
343 }
344 
TEST(DataEncoderTest,PutData)345 TEST(DataEncoderTest, PutData) {
346   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
347   const uint32_t addr_size = 4;
348   char one_byte[] = {11};
349   char two_bytes[] = {12, 13};
350   char to_many_bytes[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
351   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
352                       addr_size);
353   uint32_t offset = 0;
354   // Test putting zero bytes from a invalid array (NULL)
355   offset = encoder.PutData(offset, nullptr, 0);
356   ASSERT_EQ(offset, 0U);
357   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>(init));
358   // Test putting zero bytes from a valid array
359   offset = encoder.PutData(offset, one_byte, 0);
360   ASSERT_EQ(offset, 0U);
361   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>(init));
362   // Test putting one byte from a valid array
363   offset = encoder.PutData(offset, one_byte, sizeof(one_byte));
364   ASSERT_EQ(offset, 1U);
365   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 2, 3, 4, 5, 6, 7, 8}));
366   offset = encoder.PutData(offset, two_bytes, sizeof(two_bytes));
367   ASSERT_EQ(offset, 3U);
368   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 12, 13, 4, 5, 6, 7, 8}));
369   offset = encoder.PutData(0, to_many_bytes, sizeof(to_many_bytes));
370   ASSERT_EQ(offset, UINT32_MAX);
371   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({11, 12, 13, 4, 5, 6, 7, 8}));
372 }
373 
TEST(DataEncoderTest,PutCString)374 TEST(DataEncoderTest, PutCString) {
375   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
376   const uint32_t addr_size = 4;
377   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
378                       addr_size);
379   // Test putting invalid string pointer
380   ASSERT_EQ(encoder.PutCString(0, nullptr), UINT32_MAX);
381   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>(init));
382   // Test putting an empty string
383   uint32_t offset = 0;
384   offset = encoder.PutCString(offset, "");
385   ASSERT_EQ(offset, 1U);
386   ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({'\0', 2, 3, 4, 5, 6, 7, 8}));
387   // Test putting valid C string
388   offset = encoder.PutCString(offset, "hello");
389   ASSERT_EQ(offset, 7U);
390   ASSERT_EQ(encoder.GetData(),
391             ArrayRef<uint8_t>({'\0', 'h', 'e', 'l', 'l', 'o', '\0', 8}));
392   // Test putting valid C string but where it won't fit in existing data and
393   // make sure data stay unchanged.
394   offset = encoder.PutCString(offset, "world");
395   ASSERT_EQ(offset, UINT32_MAX);
396   ASSERT_EQ(encoder.GetData(),
397             ArrayRef<uint8_t>({'\0', 'h', 'e', 'l', 'l', 'o', '\0', 8}));
398 }
399 
TEST(DataEncoderTest,PutAddressLittle4)400 TEST(DataEncoderTest, PutAddressLittle4) {
401   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
402   const uint32_t addr_size = 4;
403   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
404                       addr_size);
405   uint32_t offset = 0;
406   offset = encoder.PutAddress(offset, 0x11223344);
407   ASSERT_EQ(offset, addr_size);
408   ASSERT_EQ(encoder.GetData(),
409             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 5, 6, 7, 8}));
410   offset = encoder.PutAddress(offset, 0x55667788);
411   ASSERT_EQ(offset, addr_size*2);
412   ASSERT_EQ(encoder.GetData(),
413             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x88, 0x77, 0x66, 0x55}));
414   // Make sure we can put an address when it won't fit in the existing buffer
415   // and that the buffer doesn't get modified.
416   ASSERT_EQ(encoder.PutAddress(addr_size+1, 0x10203040), UINT32_MAX);
417   ASSERT_EQ(encoder.GetData(),
418             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x88, 0x77, 0x66, 0x55}));
419   ASSERT_EQ(encoder.PutAddress(addr_size+2, 0x10203040), UINT32_MAX);
420   ASSERT_EQ(encoder.GetData(),
421             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x88, 0x77, 0x66, 0x55}));
422   ASSERT_EQ(encoder.PutAddress(addr_size+3, 0x10203040), UINT32_MAX);
423   ASSERT_EQ(encoder.GetData(),
424             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x88, 0x77, 0x66, 0x55}));
425   ASSERT_EQ(encoder.PutAddress(addr_size+4, 0x10203040), UINT32_MAX);
426   ASSERT_EQ(encoder.GetData(),
427             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x88, 0x77, 0x66, 0x55}));
428 }
429 
TEST(DataEncoderTest,PutAddressBig4)430 TEST(DataEncoderTest, PutAddressBig4) {
431   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
432   const uint32_t addr_size = 4;
433   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderBig,
434                       addr_size);
435   uint32_t offset = 0;
436   offset = encoder.PutAddress(offset, 0x11223344);
437   ASSERT_EQ(offset, addr_size);
438   ASSERT_EQ(encoder.GetData(),
439             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 5, 6, 7, 8}));
440   offset = encoder.PutAddress(offset, 0x55667788);
441   ASSERT_EQ(offset, addr_size*2);
442   ASSERT_EQ(encoder.GetData(),
443             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
444   // Make sure we can put an address when it won't fit in the existing buffer
445   // and that the buffer doesn't get modified.
446   ASSERT_EQ(encoder.PutAddress(addr_size+1, 0x10203040), UINT32_MAX);
447   ASSERT_EQ(encoder.GetData(),
448             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
449   ASSERT_EQ(encoder.PutAddress(addr_size+2, 0x10203040), UINT32_MAX);
450   ASSERT_EQ(encoder.GetData(),
451             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
452   ASSERT_EQ(encoder.PutAddress(addr_size+3, 0x10203040), UINT32_MAX);
453   ASSERT_EQ(encoder.GetData(),
454             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
455   ASSERT_EQ(encoder.PutAddress(addr_size+4, 0x10203040), UINT32_MAX);
456   ASSERT_EQ(encoder.GetData(),
457             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
458 }
459 
TEST(DataEncoderTest,PutAddressLittle8)460 TEST(DataEncoderTest, PutAddressLittle8) {
461   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
462   const uint32_t addr_size = 8;
463   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderLittle,
464                       addr_size);
465   uint32_t offset = 0;
466   offset = encoder.PutAddress(offset, 0x11223344);
467   ASSERT_EQ(offset, addr_size);
468   ASSERT_EQ(encoder.GetData(),
469             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
470   // Make sure we can put an address when it won't fit in the existing buffer
471   // and that the buffer doesn't get modified.
472   ASSERT_EQ(encoder.PutAddress(1, 0x10203040), UINT32_MAX);
473   ASSERT_EQ(encoder.GetData(),
474             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
475   ASSERT_EQ(encoder.PutAddress(2, 0x10203040), UINT32_MAX);
476   ASSERT_EQ(encoder.GetData(),
477             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
478   ASSERT_EQ(encoder.PutAddress(3, 0x10203040), UINT32_MAX);
479   ASSERT_EQ(encoder.GetData(),
480             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
481   ASSERT_EQ(encoder.PutAddress(4, 0x10203040), UINT32_MAX);
482   ASSERT_EQ(encoder.GetData(),
483             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
484   ASSERT_EQ(encoder.PutAddress(5, 0x10203040), UINT32_MAX);
485   ASSERT_EQ(encoder.GetData(),
486             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
487   ASSERT_EQ(encoder.PutAddress(6, 0x10203040), UINT32_MAX);
488   ASSERT_EQ(encoder.GetData(),
489             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
490   ASSERT_EQ(encoder.PutAddress(7, 0x10203040), UINT32_MAX);
491   ASSERT_EQ(encoder.GetData(),
492             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
493   ASSERT_EQ(encoder.PutAddress(8, 0x10203040), UINT32_MAX);
494   ASSERT_EQ(encoder.GetData(),
495             ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
496 }
497 
TEST(DataEncoderTest,PutAddressBig8)498 TEST(DataEncoderTest, PutAddressBig8) {
499   const std::vector<uint8_t> init = {1, 2, 3, 4, 5, 6, 7, 8};
500   const uint32_t addr_size = 8;
501   DataEncoder encoder(init.data(), init.size(), lldb::eByteOrderBig,
502                       addr_size);
503   uint32_t offset = 0;
504   offset = encoder.PutAddress(offset, 0x1122334455667788);
505   ASSERT_EQ(offset, addr_size);
506   ASSERT_EQ(encoder.GetData(),
507             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
508   // Make sure we can put an address when it won't fit in the existing buffer
509   // and that the buffer doesn't get modified.
510   ASSERT_EQ(encoder.PutAddress(1, 0x10203040), UINT32_MAX);
511   ASSERT_EQ(encoder.GetData(),
512             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
513   ASSERT_EQ(encoder.PutAddress(2, 0x10203040), UINT32_MAX);
514   ASSERT_EQ(encoder.GetData(),
515             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
516   ASSERT_EQ(encoder.PutAddress(3, 0x10203040), UINT32_MAX);
517   ASSERT_EQ(encoder.GetData(),
518             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
519   ASSERT_EQ(encoder.PutAddress(4, 0x10203040), UINT32_MAX);
520   ASSERT_EQ(encoder.GetData(),
521             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
522   ASSERT_EQ(encoder.PutAddress(5, 0x10203040), UINT32_MAX);
523   ASSERT_EQ(encoder.GetData(),
524             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
525   ASSERT_EQ(encoder.PutAddress(6, 0x10203040), UINT32_MAX);
526   ASSERT_EQ(encoder.GetData(),
527             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
528   ASSERT_EQ(encoder.PutAddress(7, 0x10203040), UINT32_MAX);
529   ASSERT_EQ(encoder.GetData(),
530             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
531   ASSERT_EQ(encoder.PutAddress(8, 0x10203040), UINT32_MAX);
532   ASSERT_EQ(encoder.GetData(),
533             ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}));
534 }
535