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 | 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 | |
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(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 | |
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(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 | |
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(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 | |
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(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 | |
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(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 | |
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(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 | |
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(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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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(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 | |
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(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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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, 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 | |
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, 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 | |