3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "util/string.h"
23 #include "util/serialize.h"
25 class TestSerialization : public TestBase {
27 TestSerialization() { TestManager::registerTestModule(this); }
28 const char *getName() { return "TestSerialization"; }
30 void runTests(IGameDef *gamedef);
31 void buildTestStrings();
33 void testSerializeString();
34 void testSerializeWideString();
35 void testSerializeLongString();
36 void testSerializeJsonString();
37 void testSerializeHex();
38 void testDeSerializeString();
39 void testDeSerializeWideString();
40 void testDeSerializeLongString();
41 void testStreamRead();
42 void testStreamWrite();
44 void testStringLengthLimits();
47 std::string teststring2;
48 std::wstring teststring2_w;
49 std::string teststring2_w_encoded;
51 static const u8 test_serialized_data[12 * 13];
54 static TestSerialization g_test_instance;
56 void TestSerialization::runTests(IGameDef *gamedef)
60 TEST(testSerializeString);
61 TEST(testDeSerializeString);
62 TEST(testSerializeWideString);
63 TEST(testDeSerializeWideString);
64 TEST(testSerializeLongString);
65 TEST(testDeSerializeLongString);
66 TEST(testSerializeJsonString);
67 TEST(testSerializeHex);
69 TEST(testStreamWrite);
71 TEST(testStringLengthLimits);
75 ////////////////////////////////////////////////////////////////////////////////
77 // To be used like this:
78 // mkstr("Some\0string\0with\0embedded\0nuls")
79 // since std::string("...") doesn't work as expected in that case.
80 template<size_t N> std::string mkstr(const char (&s)[N])
82 return std::string(s, N - 1);
85 void TestSerialization::buildTestStrings()
87 std::ostringstream tmp_os;
88 std::wostringstream tmp_os_w;
89 std::ostringstream tmp_os_w_encoded;
90 for (int i = 0; i < 256; i++) {
92 tmp_os_w << (wchar_t)i;
93 tmp_os_w_encoded << (char)0 << (char)i;
95 teststring2 = tmp_os.str();
96 teststring2_w = tmp_os_w.str();
97 teststring2_w_encoded = tmp_os_w_encoded.str();
100 void TestSerialization::testSerializeString()
103 UASSERT(serializeString("") == mkstr("\0\0"));
106 UASSERT(serializeString("Hello world!") == mkstr("\0\14Hello world!"));
108 // Test character range
109 UASSERT(serializeString(teststring2) == mkstr("\1\0") + teststring2);
112 void TestSerialization::testDeSerializeString()
116 std::istringstream is(serializeString(teststring2), std::ios::binary);
117 UASSERT(deSerializeString(is) == teststring2);
123 // Test deserialize an incomplete length specifier
125 std::istringstream is(mkstr("\x53"), std::ios::binary);
126 EXCEPTION_CHECK(SerializationError, deSerializeString(is));
129 // Test deserialize a string with incomplete data
131 std::istringstream is(mkstr("\x00\x55 abcdefg"), std::ios::binary);
132 EXCEPTION_CHECK(SerializationError, deSerializeString(is));
136 void TestSerialization::testSerializeWideString()
139 UASSERT(serializeWideString(L"") == mkstr("\0\0"));
142 UASSERT(serializeWideString(utf8_to_wide("Hello world!")) ==
143 mkstr("\0\14\0H\0e\0l\0l\0o\0 \0w\0o\0r\0l\0d\0!"));
145 // Test character range
146 UASSERT(serializeWideString(teststring2_w) ==
147 mkstr("\1\0") + teststring2_w_encoded);
150 void TestSerialization::testDeSerializeWideString()
154 std::istringstream is(serializeWideString(teststring2_w), std::ios::binary);
155 UASSERT(deSerializeWideString(is) == teststring2_w);
161 // Test deserialize an incomplete length specifier
163 std::istringstream is(mkstr("\x53"), std::ios::binary);
164 EXCEPTION_CHECK(SerializationError, deSerializeWideString(is));
167 // Test deserialize a string with an incomplete character
169 std::istringstream is(mkstr("\x00\x07\0a\0b\0c\0d\0e\0f\0"), std::ios::binary);
170 EXCEPTION_CHECK(SerializationError, deSerializeWideString(is));
173 // Test deserialize a string with incomplete data
175 std::istringstream is(mkstr("\x00\x08\0a\0b\0c\0d\0e\0f"), std::ios::binary);
176 EXCEPTION_CHECK(SerializationError, deSerializeWideString(is));
180 void TestSerialization::testSerializeLongString()
183 UASSERT(serializeLongString("") == mkstr("\0\0\0\0"));
186 UASSERT(serializeLongString("Hello world!") == mkstr("\0\0\0\14Hello world!"));
188 // Test character range
189 UASSERT(serializeLongString(teststring2) == mkstr("\0\0\1\0") + teststring2);
192 void TestSerialization::testDeSerializeLongString()
196 std::istringstream is(serializeLongString(teststring2), std::ios::binary);
197 UASSERT(deSerializeLongString(is) == teststring2);
203 // Test deserialize an incomplete length specifier
205 std::istringstream is(mkstr("\x53"), std::ios::binary);
206 EXCEPTION_CHECK(SerializationError, deSerializeLongString(is));
209 // Test deserialize a string with incomplete data
211 std::istringstream is(mkstr("\x00\x00\x00\x05 abc"), std::ios::binary);
212 EXCEPTION_CHECK(SerializationError, deSerializeLongString(is));
215 // Test deserialize a string with a length too large
217 std::istringstream is(mkstr("\xFF\xFF\xFF\xFF blah"), std::ios::binary);
218 EXCEPTION_CHECK(SerializationError, deSerializeLongString(is));
223 void TestSerialization::testSerializeJsonString()
226 UASSERT(serializeJsonString("") == "\"\"");
229 UASSERT(serializeJsonString("Hello world!") == "\"Hello world!\"");
231 // MSVC fails when directly using "\\\\"
232 std::string backslash = "\\";
233 UASSERT(serializeJsonString(teststring2) ==
235 "\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007" +
236 "\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f" +
237 "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" +
238 "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f" +
239 " !\\\"" + teststring2.substr(0x23, 0x2f-0x23) +
240 "\\/" + teststring2.substr(0x30, 0x5c-0x30) +
241 backslash + backslash + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" +
242 "\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087" +
243 "\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f" +
244 "\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" +
245 "\\u0098\\u0099\\u009a\\u009b\\u009c\\u009d\\u009e\\u009f" +
246 "\\u00a0\\u00a1\\u00a2\\u00a3\\u00a4\\u00a5\\u00a6\\u00a7" +
247 "\\u00a8\\u00a9\\u00aa\\u00ab\\u00ac\\u00ad\\u00ae\\u00af" +
248 "\\u00b0\\u00b1\\u00b2\\u00b3\\u00b4\\u00b5\\u00b6\\u00b7" +
249 "\\u00b8\\u00b9\\u00ba\\u00bb\\u00bc\\u00bd\\u00be\\u00bf" +
250 "\\u00c0\\u00c1\\u00c2\\u00c3\\u00c4\\u00c5\\u00c6\\u00c7" +
251 "\\u00c8\\u00c9\\u00ca\\u00cb\\u00cc\\u00cd\\u00ce\\u00cf" +
252 "\\u00d0\\u00d1\\u00d2\\u00d3\\u00d4\\u00d5\\u00d6\\u00d7" +
253 "\\u00d8\\u00d9\\u00da\\u00db\\u00dc\\u00dd\\u00de\\u00df" +
254 "\\u00e0\\u00e1\\u00e2\\u00e3\\u00e4\\u00e5\\u00e6\\u00e7" +
255 "\\u00e8\\u00e9\\u00ea\\u00eb\\u00ec\\u00ed\\u00ee\\u00ef" +
256 "\\u00f0\\u00f1\\u00f2\\u00f3\\u00f4\\u00f5\\u00f6\\u00f7" +
257 "\\u00f8\\u00f9\\u00fa\\u00fb\\u00fc\\u00fd\\u00fe\\u00ff" +
261 std::istringstream is(serializeJsonString(teststring2), std::ios::binary);
262 UASSERT(deSerializeJsonString(is) == teststring2);
268 void TestSerialization::testSerializeHex()
271 UASSERT(serializeHexString("") == "");
272 UASSERT(serializeHexString("", true) == "");
275 UASSERT(serializeHexString("Hello world!") ==
276 "48656c6c6f20776f726c6421");
277 UASSERT(serializeHexString("Hello world!", true) ==
278 "48 65 6c 6c 6f 20 77 6f 72 6c 64 21");
280 // Test binary string
281 UASSERT(serializeHexString(mkstr("\x00\x0a\xb0\x63\x1f\x00\xff")) ==
283 UASSERT(serializeHexString(mkstr("\x00\x0a\xb0\x63\x1f\x00\xff"), true) ==
284 "00 0a b0 63 1f 00 ff");
288 void TestSerialization::testStreamRead()
291 (const char *)test_serialized_data,
292 sizeof(test_serialized_data));
293 std::istringstream is(datastr, std::ios_base::binary);
295 UASSERT(readU8(is) == 0x11);
296 UASSERT(readU16(is) == 0x2233);
297 UASSERT(readU32(is) == 0x44556677);
298 UASSERT(readU64(is) == 0x8899AABBCCDDEEFF);
300 UASSERT(readS8(is) == -128);
301 UASSERT(readS16(is) == 30000);
302 UASSERT(readS32(is) == -6);
303 UASSERT(readS64(is) == -43);
305 UASSERT(readF1000(is) == 53.534f);
306 UASSERT(readF1000(is) == -300000.32f);
307 UASSERT(readF1000(is) == F1000_MIN);
308 UASSERT(readF1000(is) == F1000_MAX);
310 UASSERT(deSerializeString(is) == "foobar!");
312 UASSERT(readV2S16(is) == v2s16(500, 500));
313 UASSERT(readV3S16(is) == v3s16(4207, 604, -30));
314 UASSERT(readV2S32(is) == v2s32(1920, 1080));
315 UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855));
316 UASSERT(readV2F1000(is) == v2f(500.656f, 350.345f));
318 UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455");
320 UASSERT(readV3F1000(is) == v3f(500, 10024.2f, -192.54f));
321 UASSERT(readARGB8(is) == video::SColor(255, 128, 50, 128));
323 UASSERT(deSerializeLongString(is) == "some longer string here");
325 UASSERT(is.rdbuf()->in_avail() == 2);
326 UASSERT(readU16(is) == 0xF00D);
327 UASSERT(is.rdbuf()->in_avail() == 0);
331 void TestSerialization::testStreamWrite()
333 std::ostringstream os(std::ios_base::binary);
337 writeU16(os, 0x2233);
338 writeU32(os, 0x44556677);
339 writeU64(os, 0x8899AABBCCDDEEFF);
346 writeF1000(os, 53.53467f);
347 writeF1000(os, -300000.32f);
348 writeF1000(os, F1000_MIN);
349 writeF1000(os, F1000_MAX);
351 os << serializeString("foobar!");
354 UASSERT(data.size() < sizeof(test_serialized_data));
355 UASSERT(!memcmp(&data[0], test_serialized_data, data.size()));
357 writeV2S16(os, v2s16(500, 500));
358 writeV3S16(os, v3s16(4207, 604, -30));
359 writeV2S32(os, v2s32(1920, 1080));
360 writeV3S32(os, v3s32(-400, 6400054, 290549855));
361 writeV2F1000(os, v2f(500.65661f, 350.34567f));
363 os << serializeWideString(L"\x02~woof~\x5455");
365 writeV3F1000(os, v3f(500, 10024.2f, -192.54f));
366 writeARGB8(os, video::SColor(255, 128, 50, 128));
368 os << serializeLongString("some longer string here");
370 writeU16(os, 0xF00D);
373 UASSERT(data.size() == sizeof(test_serialized_data));
374 UASSERT(!memcmp(&data[0], test_serialized_data, sizeof(test_serialized_data)));
378 void TestSerialization::testVecPut()
383 putU16(&buf, 0x2233);
384 putU32(&buf, 0x44556677);
385 putU64(&buf, 0x8899AABBCCDDEEFF);
392 putF1000(&buf, 53.53467f);
393 putF1000(&buf, -300000.32f);
394 putF1000(&buf, F1000_MIN);
395 putF1000(&buf, F1000_MAX);
397 putString(&buf, "foobar!");
399 putV2S16(&buf, v2s16(500, 500));
400 putV3S16(&buf, v3s16(4207, 604, -30));
401 putV2S32(&buf, v2s32(1920, 1080));
402 putV3S32(&buf, v3s32(-400, 6400054, 290549855));
403 putV2F1000(&buf, v2f(500.65661f, 350.34567f));
405 putWideString(&buf, L"\x02~woof~\x5455");
407 putV3F1000(&buf, v3f(500, 10024.2f, -192.54f));
408 putARGB8(&buf, video::SColor(255, 128, 50, 128));
410 putLongString(&buf, "some longer string here");
412 putU16(&buf, 0xF00D);
414 UASSERT(buf.size() == sizeof(test_serialized_data));
415 UASSERT(!memcmp(&buf[0], test_serialized_data, sizeof(test_serialized_data)));
419 void TestSerialization::testStringLengthLimits()
422 std::string too_long(STRING_MAX_LEN + 1, 'A');
423 std::string way_too_large(LONG_STRING_MAX_LEN + 1, 'B');
424 std::wstring too_long_wide(WIDE_STRING_MAX_LEN + 1, L'C');
426 EXCEPTION_CHECK(SerializationError, putString(&buf, too_long));
428 putLongString(&buf, too_long);
429 too_long.resize(too_long.size() - 1);
430 putString(&buf, too_long);
432 EXCEPTION_CHECK(SerializationError, putWideString(&buf, too_long_wide));
433 too_long_wide.resize(too_long_wide.size() - 1);
434 putWideString(&buf, too_long_wide);
438 void TestSerialization::testBufReader()
448 f32 f32_data, f32_data2, f32_data3, f32_data4;
449 video::SColor scolor_data;
456 std::string string_data;
457 std::wstring widestring_data;
458 std::string longstring_data;
459 u8 raw_data[10] = {0};
461 BufReader buf(test_serialized_data, sizeof(test_serialized_data));
463 // Try reading data like normal
464 UASSERT(buf.getU8() == 0x11);
465 UASSERT(buf.getU16() == 0x2233);
466 UASSERT(buf.getU32() == 0x44556677);
467 UASSERT(buf.getU64() == 0x8899AABBCCDDEEFF);
468 UASSERT(buf.getS8() == -128);
469 UASSERT(buf.getS16() == 30000);
470 UASSERT(buf.getS32() == -6);
471 UASSERT(buf.getS64() == -43);
472 UASSERT(buf.getF1000() == 53.534f);
473 UASSERT(buf.getF1000() == -300000.32f);
474 UASSERT(buf.getF1000() == F1000_MIN);
475 UASSERT(buf.getF1000() == F1000_MAX);
476 UASSERT(buf.getString() == "foobar!");
477 UASSERT(buf.getV2S16() == v2s16(500, 500));
478 UASSERT(buf.getV3S16() == v3s16(4207, 604, -30));
479 UASSERT(buf.getV2S32() == v2s32(1920, 1080));
480 UASSERT(buf.getV3S32() == v3s32(-400, 6400054, 290549855));
481 UASSERT(buf.getV2F1000() == v2f(500.656f, 350.345f));
482 UASSERT(buf.getWideString() == L"\x02~woof~\x5455");
483 UASSERT(buf.getV3F1000() == v3f(500, 10024.2f, -192.54f));
484 UASSERT(buf.getARGB8() == video::SColor(255, 128, 50, 128));
485 UASSERT(buf.getLongString() == "some longer string here");
487 // Verify the offset and data is unchanged after a failed read
488 size_t orig_pos = buf.pos;
490 UASSERT(buf.getU32NoEx(&u32_data) == false);
491 UASSERT(buf.pos == orig_pos);
492 UASSERT(u32_data == 0);
494 // Now try the same for a failed string read
495 UASSERT(buf.getStringNoEx(&string_data) == false);
496 UASSERT(buf.pos == orig_pos);
497 UASSERT(string_data == "");
499 // Now try the same for a failed string read
500 UASSERT(buf.getWideStringNoEx(&widestring_data) == false);
501 UASSERT(buf.pos == orig_pos);
502 UASSERT(widestring_data == L"");
504 UASSERT(buf.getU16() == 0xF00D);
506 UASSERT(buf.remaining() == 0);
508 // Check to make sure these each blow exceptions as they're supposed to
509 EXCEPTION_CHECK(SerializationError, buf.getU8());
510 EXCEPTION_CHECK(SerializationError, buf.getU16());
511 EXCEPTION_CHECK(SerializationError, buf.getU32());
512 EXCEPTION_CHECK(SerializationError, buf.getU64());
514 EXCEPTION_CHECK(SerializationError, buf.getS8());
515 EXCEPTION_CHECK(SerializationError, buf.getS16());
516 EXCEPTION_CHECK(SerializationError, buf.getS32());
517 EXCEPTION_CHECK(SerializationError, buf.getS64());
519 EXCEPTION_CHECK(SerializationError, buf.getF1000());
520 EXCEPTION_CHECK(SerializationError, buf.getARGB8());
522 EXCEPTION_CHECK(SerializationError, buf.getV2S16());
523 EXCEPTION_CHECK(SerializationError, buf.getV3S16());
524 EXCEPTION_CHECK(SerializationError, buf.getV2S32());
525 EXCEPTION_CHECK(SerializationError, buf.getV3S32());
526 EXCEPTION_CHECK(SerializationError, buf.getV2F1000());
527 EXCEPTION_CHECK(SerializationError, buf.getV3F1000());
529 EXCEPTION_CHECK(SerializationError, buf.getString());
530 EXCEPTION_CHECK(SerializationError, buf.getWideString());
531 EXCEPTION_CHECK(SerializationError, buf.getLongString());
532 EXCEPTION_CHECK(SerializationError,
533 buf.getRawData(raw_data, sizeof(raw_data)));
535 // See if we can skip backwards
537 UASSERT(buf.getRawDataNoEx(raw_data, 3) == true);
538 UASSERT(raw_data[0] == 0x66);
539 UASSERT(raw_data[1] == 0x77);
540 UASSERT(raw_data[2] == 0x88);
542 UASSERT(buf.getU32() == 0x99AABBCC);
543 UASSERT(buf.pos == 12);
545 // Now let's try it all over again using the NoEx variants
548 UASSERT(buf.getU8NoEx(&u8_data));
549 UASSERT(buf.getU16NoEx(&u16_data));
550 UASSERT(buf.getU32NoEx(&u32_data));
551 UASSERT(buf.getU64NoEx(&u64_data));
553 UASSERT(buf.getS8NoEx(&s8_data));
554 UASSERT(buf.getS16NoEx(&s16_data));
555 UASSERT(buf.getS32NoEx(&s32_data));
556 UASSERT(buf.getS64NoEx(&s64_data));
558 UASSERT(buf.getF1000NoEx(&f32_data));
559 UASSERT(buf.getF1000NoEx(&f32_data2));
560 UASSERT(buf.getF1000NoEx(&f32_data3));
561 UASSERT(buf.getF1000NoEx(&f32_data4));
563 UASSERT(buf.getStringNoEx(&string_data));
564 UASSERT(buf.getV2S16NoEx(&v2s16_data));
565 UASSERT(buf.getV3S16NoEx(&v3s16_data));
566 UASSERT(buf.getV2S32NoEx(&v2s32_data));
567 UASSERT(buf.getV3S32NoEx(&v3s32_data));
568 UASSERT(buf.getV2F1000NoEx(&v2f_data));
569 UASSERT(buf.getWideStringNoEx(&widestring_data));
570 UASSERT(buf.getV3F1000NoEx(&v3f_data));
571 UASSERT(buf.getARGB8NoEx(&scolor_data));
573 UASSERT(buf.getLongStringNoEx(&longstring_data));
575 // and make sure we got the correct data
576 UASSERT(u8_data == 0x11);
577 UASSERT(u16_data == 0x2233);
578 UASSERT(u32_data == 0x44556677);
579 UASSERT(u64_data == 0x8899AABBCCDDEEFF);
580 UASSERT(s8_data == -128);
581 UASSERT(s16_data == 30000);
582 UASSERT(s32_data == -6);
583 UASSERT(s64_data == -43);
584 UASSERT(f32_data == 53.534f);
585 UASSERT(f32_data2 == -300000.32f);
586 UASSERT(f32_data3 == F1000_MIN);
587 UASSERT(f32_data4 == F1000_MAX);
588 UASSERT(string_data == "foobar!");
589 UASSERT(v2s16_data == v2s16(500, 500));
590 UASSERT(v3s16_data == v3s16(4207, 604, -30));
591 UASSERT(v2s32_data == v2s32(1920, 1080));
592 UASSERT(v3s32_data == v3s32(-400, 6400054, 290549855));
593 UASSERT(v2f_data == v2f(500.656f, 350.345f));
594 UASSERT(widestring_data == L"\x02~woof~\x5455");
595 UASSERT(v3f_data == v3f(500, 10024.2f, -192.54f));
596 UASSERT(scolor_data == video::SColor(255, 128, 50, 128));
597 UASSERT(longstring_data == "some longer string here");
599 UASSERT(buf.remaining() == 2);
600 UASSERT(buf.getRawDataNoEx(raw_data, 3) == false);
601 UASSERT(buf.remaining() == 2);
602 UASSERT(buf.getRawDataNoEx(raw_data, 2) == true);
603 UASSERT(raw_data[0] == 0xF0);
604 UASSERT(raw_data[1] == 0x0D);
605 UASSERT(buf.remaining() == 0);
607 // Make sure no more available data causes a failure
608 UASSERT(!buf.getU8NoEx(&u8_data));
609 UASSERT(!buf.getU16NoEx(&u16_data));
610 UASSERT(!buf.getU32NoEx(&u32_data));
611 UASSERT(!buf.getU64NoEx(&u64_data));
613 UASSERT(!buf.getS8NoEx(&s8_data));
614 UASSERT(!buf.getS16NoEx(&s16_data));
615 UASSERT(!buf.getS32NoEx(&s32_data));
616 UASSERT(!buf.getS64NoEx(&s64_data));
618 UASSERT(!buf.getF1000NoEx(&f32_data));
619 UASSERT(!buf.getARGB8NoEx(&scolor_data));
621 UASSERT(!buf.getV2S16NoEx(&v2s16_data));
622 UASSERT(!buf.getV3S16NoEx(&v3s16_data));
623 UASSERT(!buf.getV2S32NoEx(&v2s32_data));
624 UASSERT(!buf.getV3S32NoEx(&v3s32_data));
625 UASSERT(!buf.getV2F1000NoEx(&v2f_data));
626 UASSERT(!buf.getV3F1000NoEx(&v3f_data));
628 UASSERT(!buf.getStringNoEx(&string_data));
629 UASSERT(!buf.getWideStringNoEx(&widestring_data));
630 UASSERT(!buf.getLongStringNoEx(&longstring_data));
631 UASSERT(!buf.getRawDataNoEx(raw_data, sizeof(raw_data)));
635 const u8 TestSerialization::test_serialized_data[12 * 13] = {
636 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc,
637 0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff,
638 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e,
639 0x5b, 0xc0, 0x80, 0x00, 0x02, 0x80, 0x7F, 0xFF, 0xFD, 0x80, 0x00, 0x07,
640 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10,
641 0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04,
642 0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70,
643 0x5f, 0x00, 0x07, 0xa3, 0xb0, 0x00, 0x05, 0x58, 0x89, 0x00, 0x08, 0x00,
644 0x02, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x66, 0x00,
645 0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff,
646 0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73,
647 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73,
648 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0xF0, 0x0D,