1 | #include "test.h" |
2 | #include <gtest/gtest.h> |
3 | |
4 | #include <base/system.h> |
5 | #include <engine/shared/packer.h> |
6 | |
7 | // pExpected is NULL if an error is expected |
8 | static void ExpectAddString5(const char *pString, int Limit, const char *pExpected) |
9 | { |
10 | static char ZEROS[CPacker::PACKER_BUFFER_SIZE] = {0}; |
11 | static const int OFFSET = CPacker::PACKER_BUFFER_SIZE - 5; |
12 | CPacker Packer; |
13 | Packer.Reset(); |
14 | Packer.AddRaw(pData: ZEROS, Size: OFFSET); |
15 | Packer.AddString(pStr: pString, Limit); |
16 | |
17 | EXPECT_EQ(pExpected == 0, Packer.Error()); |
18 | if(pExpected) |
19 | { |
20 | // Include null termination. |
21 | int ExpectedLength = str_length(str: pExpected) + 1; |
22 | EXPECT_EQ(ExpectedLength, Packer.Size() - OFFSET); |
23 | if(ExpectedLength == Packer.Size() - OFFSET) |
24 | { |
25 | EXPECT_STREQ(pExpected, (const char *)Packer.Data() + OFFSET); |
26 | } |
27 | } |
28 | } |
29 | |
30 | static void ExpectAddInt(int Input, int Expected) |
31 | { |
32 | CPacker Packer; |
33 | Packer.Reset(); |
34 | Packer.AddInt(i: Input); |
35 | EXPECT_EQ(Packer.Error(), false); |
36 | ASSERT_EQ(Packer.Size(), 1); |
37 | EXPECT_EQ(Packer.Data()[0], Expected); |
38 | } |
39 | |
40 | static void ExpectAddExtendedInt(int Input, unsigned char *pExpected, int Size) |
41 | { |
42 | CPacker Packer; |
43 | Packer.Reset(); |
44 | Packer.AddInt(i: Input); |
45 | EXPECT_EQ(Packer.Error(), false); |
46 | ASSERT_EQ(Packer.Size(), Size); |
47 | EXPECT_EQ(mem_comp(Packer.Data(), pExpected, Size), 0); |
48 | } |
49 | |
50 | TEST(Packer, AddInt) |
51 | { |
52 | ExpectAddInt(Input: 1, Expected: 0b0000'0001); |
53 | ExpectAddInt(Input: 2, Expected: 0b0000'0010); |
54 | // ^^^ ^ |
55 | // ||\ / |
56 | // Not extended| \ / |
57 | // | \ / |
58 | // |00'0010 => 2 |
59 | // | |
60 | // Positive |
61 | |
62 | // there is no -0 so 00 0000 |
63 | // plus the negative bit is -1 |
64 | ExpectAddInt(Input: -1, Expected: 0b0100'0000); |
65 | // ^^^ ^ |
66 | // ||\ / |
67 | // Not extended| \ / |
68 | // | \ / |
69 | // |00'0000 => 0 |
70 | // | |
71 | // Negative |
72 | ExpectAddInt(Input: -2, Expected: 0b0100'0001); |
73 | |
74 | // 0-63 packed ints |
75 | // are represented the same way |
76 | // C++ represents ints |
77 | // All other numbers differ due to packing shinanigans |
78 | for(int i = 0; i < 63; i++) |
79 | ExpectAddInt(Input: i, Expected: i); |
80 | } |
81 | |
82 | TEST(Packer, AddExtendedInt) |
83 | { |
84 | unsigned char pExpected64[] = { |
85 | 0b1000'0000, 0b0000'0001}; |
86 | ExpectAddExtendedInt(Input: 64, pExpected: pExpected64, Size: 2); |
87 | unsigned char pExpected65[] = { |
88 | 0b1000'0001, 0b0000'0001 |
89 | /*^^^ ^ ^^ ^ |
90 | ||\ / | \ / |
91 | || \ / | \ / |
92 | || \ / Not \/ |
93 | || \ Extended / |
94 | || \ / |
95 | || \ / |
96 | || \ / |
97 | || \ / |
98 | || \ / |
99 | || X |
100 | || / \ |
101 | || / \ |
102 | || / \ |
103 | || / \ |
104 | || 000'0001 00'0001 => 1000001 => 65 |
105 | || |
106 | |0 Not negative |
107 | | |
108 | 1 Extended (one more byte following) |
109 | */ |
110 | }; |
111 | ExpectAddExtendedInt(Input: 65, pExpected: pExpected65, Size: 2); |
112 | |
113 | unsigned char pExpected66[] = { |
114 | 0b1000'0010, 0b0000'0001 |
115 | /*^^^ ^ ^^ ^ |
116 | ||\ / | \ / |
117 | || \ / | \ / |
118 | || \ / Not \/ |
119 | || \ Extended / |
120 | || \ / |
121 | || \ / |
122 | || \ / |
123 | || \ / |
124 | || \ / |
125 | || X |
126 | || / \ |
127 | || / \ |
128 | || / \ |
129 | || / \ |
130 | || 000'0001 00'0010 => 1000010 => 66 |
131 | || |
132 | |0 Not negative |
133 | | |
134 | 1 Extended (one more byte following) |
135 | */ |
136 | }; |
137 | ExpectAddExtendedInt(Input: 66, pExpected: pExpected66, Size: 2); |
138 | |
139 | // there is no -0 so all negative numbers |
140 | // are one smaller |
141 | // So 64 + negative bit is -65 |
142 | unsigned char pExpectedNegative65[] = { |
143 | 0b1100'0000, 0b0000'0001 |
144 | /*^^^ ^ ^^ ^ |
145 | ||\ / | \ / |
146 | || \ / | \ / |
147 | || \ / Not \/ |
148 | || \ Extended / |
149 | || \ / |
150 | || \ / |
151 | || \ / |
152 | || \ / |
153 | || \ / |
154 | || X |
155 | || / \ |
156 | || / \ |
157 | || / \ |
158 | || / \ |
159 | || 000'0001 00'0000 => 1000000 => 64 |
160 | || |
161 | |1 Negative |
162 | | |
163 | 1 Extended (one more byte following) |
164 | */ |
165 | }; |
166 | ExpectAddExtendedInt(Input: -65, pExpected: pExpectedNegative65, Size: 2); |
167 | |
168 | unsigned char pExpectedNegative66[] = { |
169 | 0b1100'0001, 0b0000'0001 |
170 | /*^^^ ^ ^^ ^ |
171 | ||\ / | \ / |
172 | || \ / | \ / |
173 | || \ / Not \/ |
174 | || \ Extended / |
175 | || \ / |
176 | || \ / |
177 | || \ / |
178 | || \ / |
179 | || \ / |
180 | || X |
181 | || / \ |
182 | || / \ |
183 | || / \ |
184 | || / \ |
185 | || 000'0001 00'0001 => 1000001 => 65 |
186 | || |
187 | |1 Negative |
188 | | |
189 | 1 Extended (one more byte following) |
190 | */ |
191 | }; |
192 | ExpectAddExtendedInt(Input: -66, pExpected: pExpectedNegative66, Size: 2); |
193 | |
194 | unsigned char pExpectedNegative67[] = { |
195 | 0b1100'0010, 0b0000'0001}; |
196 | ExpectAddExtendedInt(Input: -67, pExpected: pExpectedNegative67, Size: 2); |
197 | unsigned char pExpectedNegative68[] = { |
198 | 0b1100'0011, 0b0000'0001}; |
199 | ExpectAddExtendedInt(Input: -68, pExpected: pExpectedNegative68, Size: 2); |
200 | unsigned char pExpectedNegative69[] = { |
201 | 0b1100'0100, 0b0000'0001}; |
202 | ExpectAddExtendedInt(Input: -69, pExpected: pExpectedNegative69, Size: 2); |
203 | unsigned char pExpectedNegative70[] = { |
204 | 0b1100'0101, 0b0000'0001}; |
205 | ExpectAddExtendedInt(Input: -70, pExpected: pExpectedNegative70, Size: 2); |
206 | } |
207 | |
208 | TEST(Packer, AddString) |
209 | { |
210 | ExpectAddString5(pString: "" , Limit: 0, pExpected: "" ); |
211 | ExpectAddString5(pString: "a" , Limit: 0, pExpected: "a" ); |
212 | ExpectAddString5(pString: "abcd" , Limit: 0, pExpected: "abcd" ); |
213 | ExpectAddString5(pString: "abcde" , Limit: 0, pExpected: 0); |
214 | } |
215 | |
216 | TEST(Packer, AddStringLimit) |
217 | { |
218 | ExpectAddString5(pString: "" , Limit: 1, pExpected: "" ); |
219 | ExpectAddString5(pString: "a" , Limit: 1, pExpected: "a" ); |
220 | ExpectAddString5(pString: "aa" , Limit: 1, pExpected: "a" ); |
221 | ExpectAddString5(pString: "ä" , Limit: 1, pExpected: "" ); |
222 | |
223 | ExpectAddString5(pString: "" , Limit: 10, pExpected: "" ); |
224 | ExpectAddString5(pString: "a" , Limit: 10, pExpected: "a" ); |
225 | ExpectAddString5(pString: "abcd" , Limit: 10, pExpected: "abcd" ); |
226 | ExpectAddString5(pString: "abcde" , Limit: 10, pExpected: 0); |
227 | |
228 | ExpectAddString5(pString: "äöü" , Limit: 5, pExpected: "äö" ); |
229 | ExpectAddString5(pString: "äöü" , Limit: 6, pExpected: 0); |
230 | } |
231 | |
232 | TEST(Packer, AddStringBroken) |
233 | { |
234 | ExpectAddString5(pString: "\x80" , Limit: 0, pExpected: "�" ); |
235 | ExpectAddString5(pString: "\x80\x80" , Limit: 0, pExpected: 0); |
236 | ExpectAddString5(pString: "a\x80" , Limit: 0, pExpected: "a�" ); |
237 | ExpectAddString5(pString: "\x80" |
238 | "a" , |
239 | Limit: 0, pExpected: "�a" ); |
240 | ExpectAddString5(pString: "\x80" , Limit: 1, pExpected: "" ); |
241 | ExpectAddString5(pString: "\x80\x80" , Limit: 3, pExpected: "�" ); |
242 | ExpectAddString5(pString: "\x80\x80" , Limit: 5, pExpected: "�" ); |
243 | ExpectAddString5(pString: "\x80\x80" , Limit: 6, pExpected: 0); |
244 | } |
245 | |
246 | TEST(Packer, Error) |
247 | { |
248 | char aData[CPacker::PACKER_BUFFER_SIZE]; |
249 | mem_zero(block: aData, size: sizeof(aData)); |
250 | |
251 | { |
252 | CPacker Packer; |
253 | Packer.Reset(); |
254 | EXPECT_EQ(Packer.Error(), false); |
255 | Packer.AddRaw(pData: aData, Size: sizeof(aData) - 1); |
256 | EXPECT_EQ(Packer.Error(), false); |
257 | EXPECT_EQ(Packer.Size(), sizeof(aData) - 1); |
258 | Packer.AddInt(i: 1); |
259 | EXPECT_EQ(Packer.Error(), false); |
260 | EXPECT_EQ(Packer.Size(), sizeof(aData)); |
261 | Packer.AddInt(i: 2); |
262 | EXPECT_EQ(Packer.Error(), true); |
263 | Packer.AddInt(i: 3); |
264 | EXPECT_EQ(Packer.Error(), true); |
265 | } |
266 | |
267 | { |
268 | CPacker Packer; |
269 | Packer.Reset(); |
270 | EXPECT_EQ(Packer.Error(), false); |
271 | Packer.AddRaw(pData: aData, Size: sizeof(aData) - 1); |
272 | EXPECT_EQ(Packer.Error(), false); |
273 | EXPECT_EQ(Packer.Size(), sizeof(aData) - 1); |
274 | Packer.AddRaw(pData: aData, Size: 1); |
275 | EXPECT_EQ(Packer.Error(), false); |
276 | EXPECT_EQ(Packer.Size(), sizeof(aData)); |
277 | Packer.AddRaw(pData: aData, Size: 1); |
278 | EXPECT_EQ(Packer.Error(), true); |
279 | Packer.AddRaw(pData: aData, Size: 1); |
280 | EXPECT_EQ(Packer.Error(), true); |
281 | } |
282 | |
283 | { |
284 | CPacker Packer; |
285 | Packer.Reset(); |
286 | EXPECT_EQ(Packer.Error(), false); |
287 | Packer.AddRaw(pData: aData, Size: sizeof(aData) - 5); |
288 | EXPECT_EQ(Packer.Error(), false); |
289 | EXPECT_EQ(Packer.Size(), sizeof(aData) - 5); |
290 | Packer.AddString(pStr: "test" ); |
291 | EXPECT_EQ(Packer.Error(), false); |
292 | EXPECT_EQ(Packer.Size(), sizeof(aData)); |
293 | Packer.AddString(pStr: "test" ); |
294 | EXPECT_EQ(Packer.Error(), true); |
295 | Packer.AddString(pStr: "test" ); |
296 | EXPECT_EQ(Packer.Error(), true); |
297 | } |
298 | } |
299 | |