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