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>
14using namespace lldb_private;
15using namespace llvm;
16
17TEST(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, value: 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, value: 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, value: 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, value: 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
42TEST(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(value: 0x11);
47 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11}));
48 encoder.AppendU16(value: 0x2233);
49 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x33, 0x22}));
50 encoder.AppendU32(value: 0x44556677);
51 ASSERT_EQ(encoder.GetData(),
52 ArrayRef<uint8_t>({0x11, 0x33, 0x22, 0x77, 0x66, 0x55, 0x44}));
53 encoder.AppendU64(value: 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(value: 0x8899AABBCCDDEEFF);
58}
59
60TEST(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(value: 0x11);
65 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11}));
66 encoder.AppendU16(value: 0x2233);
67 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x22, 0x33}));
68 encoder.AppendU32(value: 0x44556677);
69 ASSERT_EQ(encoder.GetData(),
70 ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}));
71 encoder.AppendU64(value: 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
77TEST(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(addr: 0x11223344);
82 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11}));
83 encoder.AppendAddress(addr: 0x55);
84 ASSERT_EQ(encoder.GetData(),
85 ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x55, 0x00, 0x00, 0x00}));
86}
87
88TEST(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(addr: 0x11223344);
93 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44}));
94 encoder.AppendAddress(addr: 0x55);
95 ASSERT_EQ(encoder.GetData(),
96 ArrayRef<uint8_t>({0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00, 0x55}));
97}
98
99TEST(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(addr: 0x11223344);
104 ASSERT_EQ(encoder.GetData(),
105 ArrayRef<uint8_t>({0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x00, 0x00}));
106 encoder.AppendAddress(addr: 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
112TEST(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(addr: 0x11223344);
117 ASSERT_EQ(encoder.GetData(),
118 ArrayRef<uint8_t>({0x00, 0x00, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44}));
119 encoder.AppendAddress(addr: 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
125TEST(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(data: StringRef());
131 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({}));
132 // Make sure empty StringRef appends nothing
133 encoder.AppendData(data: StringRef(""));
134 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({}));
135 // Append some bytes that contains a NULL character
136 encoder.AppendData(data: StringRef("\x11\x00\x22", 3));
137 ASSERT_EQ(encoder.GetData(), ArrayRef<uint8_t>({0x11, 0x00, 0x22}));
138}
139
140TEST(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(data: 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(data: 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(data: 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(data: 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(data: 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
168TEST(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, value: 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, value: 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, value: 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, value: 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
192TEST(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, value: 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, value: 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, value: 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, value: 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
216TEST(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, value: 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, value: 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
235TEST(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, value: 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, value: 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
254TEST(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, value: 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
269TEST(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, value: 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
284TEST(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(offset: 0, byte_size: 1, value: 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(offset: 0, byte_size: 2, value: 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(offset: 0, byte_size: 4, value: 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(offset: 0, byte_size: 8, value: 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
314TEST(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(offset: 0, byte_size: 1, value: 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(offset: 0, byte_size: 2, value: 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(offset: 0, byte_size: 4, value: 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(offset: 0, byte_size: 8, value: 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
345TEST(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, src: nullptr, src_len: 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, src: one_byte, src_len: 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, src: one_byte, src_len: 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, src: two_bytes, src_len: 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(offset: 0, src: to_many_bytes, src_len: 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
374TEST(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, cstr: "");
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, cstr: "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, cstr: "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
400TEST(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, addr: 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, addr: 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
430TEST(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, addr: 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, addr: 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
460TEST(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, addr: 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
498TEST(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, addr: 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

source code of lldb/unittests/Utility/DataEncoderTest.cpp