00001
00033 #include <tut/tut.h>
00034
00035 #if !LL_WINDOWS
00036 #include <netinet/in.h>
00037 #endif
00038
00039 #include "linden_common.h"
00040 #include "llsd.h"
00041 #include "llsdserialize.h"
00042 #include "lltut.h"
00043 #include "llformat.h"
00044
00045
00046
00047 #if !LL_WINDOWS
00048
00049 namespace tut
00050 {
00051 struct sd_xml_data
00052 {
00053 sd_xml_data()
00054 {
00055 mFormatter = new LLSDXMLFormatter;
00056 }
00057 LLSD mSD;
00058 LLPointer<LLSDXMLFormatter> mFormatter;
00059 void xml_test(const char* name, const std::string& expected)
00060 {
00061 std::ostringstream ostr;
00062 mFormatter->format(mSD, ostr);
00063 ensure_equals(name, ostr.str(), expected);
00064 }
00065 };
00066
00067 typedef test_group<sd_xml_data> sd_xml_test;
00068 typedef sd_xml_test::object sd_xml_object;
00069 tut::sd_xml_test sd_xml_stream("sd_xml_serialization");
00070
00071 template<> template<>
00072 void sd_xml_object::test<1>()
00073 {
00074
00075 std::string expected;
00076
00077 expected = "<llsd><undef /></llsd>\n";
00078 xml_test("undef", expected);
00079
00080 mSD = 3463;
00081 expected = "<llsd><integer>3463</integer></llsd>\n";
00082 xml_test("integer", expected);
00083
00084 mSD = "";
00085 expected = "<llsd><string /></llsd>\n";
00086 xml_test("empty string", expected);
00087
00088 mSD = "foobar";
00089 expected = "<llsd><string>foobar</string></llsd>\n";
00090 xml_test("string", expected);
00091
00092 mSD = LLUUID::null;
00093 expected = "<llsd><uuid /></llsd>\n";
00094 xml_test("null uuid", expected);
00095
00096 mSD = LLUUID("c96f9b1e-f589-4100-9774-d98643ce0bed");
00097 expected = "<llsd><uuid>c96f9b1e-f589-4100-9774-d98643ce0bed</uuid></llsd>\n";
00098 xml_test("uuid", expected);
00099
00100 mSD = LLURI("https://secondlife.com/login");
00101 expected = "<llsd><uri>https://secondlife.com/login</uri></llsd>\n";
00102 xml_test("uri", expected);
00103
00104 mSD = LLDate("2006-04-24T16:11:33Z");
00105 expected = "<llsd><date>2006-04-24T16:11:33Z</date></llsd>\n";
00106 xml_test("date", expected);
00107
00108
00109 }
00110
00111 template<> template<>
00112 void sd_xml_object::test<2>()
00113 {
00114
00115 std::string expected;
00116
00117 mFormatter->boolalpha(true);
00118 mSD = true;
00119 expected = "<llsd><boolean>true</boolean></llsd>\n";
00120 xml_test("bool alpha true", expected);
00121 mSD = false;
00122 expected = "<llsd><boolean>false</boolean></llsd>\n";
00123 xml_test("bool alpha false", expected);
00124
00125 mFormatter->boolalpha(false);
00126 mSD = true;
00127 expected = "<llsd><boolean>1</boolean></llsd>\n";
00128 xml_test("bool true", expected);
00129 mSD = false;
00130 expected = "<llsd><boolean>0</boolean></llsd>\n";
00131 xml_test("bool false", expected);
00132 }
00133
00134
00135 template<> template<>
00136 void sd_xml_object::test<3>()
00137 {
00138
00139 std::string expected;
00140
00141 mFormatter->realFormat("%.2f");
00142 mSD = 1.0;
00143 expected = "<llsd><real>1.00</real></llsd>\n";
00144 xml_test("real 1", expected);
00145
00146 mSD = -34379.0438;
00147 expected = "<llsd><real>-34379.04</real></llsd>\n";
00148 xml_test("real reduced precision", expected);
00149 mFormatter->realFormat("%.4f");
00150 expected = "<llsd><real>-34379.0438</real></llsd>\n";
00151 xml_test("higher precision", expected);
00152
00153 mFormatter->realFormat("%.0f");
00154 mSD = 0.0;
00155 expected = "<llsd><real>0</real></llsd>\n";
00156 xml_test("no decimal 0", expected);
00157 mSD = 3287.4387;
00158 expected = "<llsd><real>3287</real></llsd>\n";
00159 xml_test("no decimal real number", expected);
00160 }
00161
00162 template<> template<>
00163 void sd_xml_object::test<4>()
00164 {
00165
00166 std::string expected;
00167
00168 mSD = LLSD::emptyArray();
00169 expected = "<llsd><array /></llsd>\n";
00170 xml_test("empty array", expected);
00171
00172 mSD.append(LLSD());
00173 expected = "<llsd><array><undef /></array></llsd>\n";
00174 xml_test("1 element array", expected);
00175
00176 mSD.append(1);
00177 expected = "<llsd><array><undef /><integer>1</integer></array></llsd>\n";
00178 xml_test("2 element array", expected);
00179 }
00180
00181 template<> template<>
00182 void sd_xml_object::test<5>()
00183 {
00184
00185 std::string expected;
00186
00187 mSD = LLSD::emptyMap();
00188 expected = "<llsd><map /></llsd>\n";
00189 xml_test("empty map", expected);
00190
00191 mSD["foo"] = "bar";
00192 expected = "<llsd><map><key>foo</key><string>bar</string></map></llsd>\n";
00193 xml_test("1 element map", expected);
00194
00195 mSD["baz"] = LLSD();
00196 expected = "<llsd><map><key>baz</key><undef /><key>foo</key><string>bar</string></map></llsd>\n";
00197 xml_test("2 element map", expected);
00198 }
00199
00200
00201 class TestLLSDSerializeData
00202 {
00203 public:
00204 TestLLSDSerializeData();
00205 ~TestLLSDSerializeData();
00206
00207 void doRoundTripTests(const std::string&);
00208 void checkRoundTrip(const std::string&, const LLSD& v);
00209
00210 LLPointer<LLSDFormatter> mFormatter;
00211 LLPointer<LLSDParser> mParser;
00212 };
00213
00214 TestLLSDSerializeData::TestLLSDSerializeData()
00215 {
00216 }
00217
00218 TestLLSDSerializeData::~TestLLSDSerializeData()
00219 {
00220 }
00221
00222 void TestLLSDSerializeData::checkRoundTrip(const std::string& msg, const LLSD& v)
00223 {
00224 std::stringstream stream;
00225 mFormatter->format(v, stream);
00226
00227 LLSD w;
00228 mParser->parse(stream, w, stream.str().size());
00229
00230 try
00231 {
00232 ensure_equals(msg, w, v);
00233 }
00234 catch (...)
00235 {
00236 std::cerr << "the serialized string was:" << std::endl;
00237 std::cerr << stream.str() << std::endl;
00238 throw;
00239 }
00240 }
00241
00242 static void fillmap(LLSD& root, U32 width, U32 depth)
00243 {
00244 if(depth == 0)
00245 {
00246 root["foo"] = "bar";
00247 return;
00248 }
00249
00250 for(U32 i = 0; i < width; ++i)
00251 {
00252 std::string key = llformat("child %d", i);
00253 root[key] = LLSD::emptyMap();
00254 fillmap(root[key], width, depth - 1);
00255 }
00256 }
00257
00258 void TestLLSDSerializeData::doRoundTripTests(const std::string& msg)
00259 {
00260 LLSD v;
00261 checkRoundTrip(msg + " undefined", v);
00262
00263 v = true;
00264 checkRoundTrip(msg + " true bool", v);
00265
00266 v = false;
00267 checkRoundTrip(msg + " false bool", v);
00268
00269 v = 1;
00270 checkRoundTrip(msg + " positive int", v);
00271
00272 v = 0;
00273 checkRoundTrip(msg + " zero int", v);
00274
00275 v = -1;
00276 checkRoundTrip(msg + " negative int", v);
00277
00278 v = 1234.5f;
00279 checkRoundTrip(msg + " positive float", v);
00280
00281 v = 0.0f;
00282 checkRoundTrip(msg + " zero float", v);
00283
00284 v = -1234.5f;
00285 checkRoundTrip(msg + " negative float", v);
00286
00287
00288
00289 v = LLUUID::null;
00290 checkRoundTrip(msg + " null uuid", v);
00291
00292 LLUUID newUUID;
00293 newUUID.generate();
00294 v = newUUID;
00295 checkRoundTrip(msg + " new uuid", v);
00296
00297 v = "";
00298 checkRoundTrip(msg + " empty string", v);
00299
00300 v = "some string";
00301 checkRoundTrip(msg + " non-empty string", v);
00302
00303 v =
00304 "Second Life is a 3-D virtual world entirely built and owned by its residents. "
00305 "Since opening to the public in 2003, it has grown explosively and today is "
00306 "inhabited by nearly 100,000 people from around the globe.\n"
00307 "\n"
00308 "From the moment you enter the World you'll discover a vast digital continent, "
00309 "teeming with people, entertainment, experiences and opportunity. Once you've "
00310 "explored a bit, perhaps you'll find a perfect parcel of land to build your "
00311 "house or business.\n"
00312 "\n"
00313 "You'll also be surrounded by the Creations of your fellow residents. Because "
00314 "residents retain the rights to their digital creations, they can buy, sell "
00315 "and trade with other residents.\n"
00316 "\n"
00317 "The Marketplace currently supports millions of US dollars in monthly "
00318 "transactions. This commerce is handled with the in-world currency, the Linden "
00319 "dollar, which can be converted to US dollars at several thriving online "
00320 "currency exchanges.\n"
00321 "\n"
00322 "Welcome to Second Life. We look forward to seeing you in-world!\n"
00323 ;
00324 checkRoundTrip(msg + " long string", v);
00325
00326 static const U32 block_size = 0x000020;
00327 for (U32 block = 0x000000; block <= 0x10ffff; block += block_size)
00328 {
00329 std::ostringstream out;
00330
00331 for (U32 c = block; c < block + block_size; ++c)
00332 {
00333 if (c <= 0x000001f
00334 && c != 0x000009
00335 && c != 0x00000a)
00336 {
00337
00338 continue;
00339 }
00340 if (0x00d800 <= c && c <= 0x00dfff) { continue; }
00341 if (0x00fdd0 <= c && c <= 0x00fdef) { continue; }
00342 if ((c & 0x00fffe) == 0x00fffe) { continue; }
00343
00344
00345 if (c <= 0x00007f)
00346 {
00347 out << (char)(c & 0x7f);
00348 }
00349 else if (c <= 0x0007ff)
00350 {
00351 out << (char)(0xc0 | ((c >> 6) & 0x1f));
00352 out << (char)(0x80 | ((c >> 0) & 0x3f));
00353 }
00354 else if (c <= 0x00ffff)
00355 {
00356 out << (char)(0xe0 | ((c >> 12) & 0x0f));
00357 out << (char)(0x80 | ((c >> 6) & 0x3f));
00358 out << (char)(0x80 | ((c >> 0) & 0x3f));
00359 }
00360 else
00361 {
00362 out << (char)(0xf0 | ((c >> 18) & 0x07));
00363 out << (char)(0x80 | ((c >> 12) & 0x3f));
00364 out << (char)(0x80 | ((c >> 6) & 0x3f));
00365 out << (char)(0x80 | ((c >> 0) & 0x3f));
00366 }
00367 }
00368
00369 v = out.str();
00370
00371 std::ostringstream blockmsg;
00372 blockmsg << msg << " unicode string block 0x" << std::hex << block;
00373 checkRoundTrip(blockmsg.str(), v);
00374 }
00375
00376 LLDate epoch;
00377 v = epoch;
00378 checkRoundTrip(msg + " epoch date", v);
00379
00380 LLDate aDay("2002-12-07T05:07:15.00Z");
00381 v = aDay;
00382 checkRoundTrip(msg + " date", v);
00383
00384 LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
00385 v = path;
00386 checkRoundTrip(msg + " url", v);
00387
00388 const char source[] = "it must be a blue moon again";
00389 std::vector<U8> data;
00390 copy(&source[0], &source[sizeof(source)], back_inserter(data));
00391
00392 v = data;
00393 checkRoundTrip(msg + " binary", v);
00394
00395 v = LLSD::emptyMap();
00396 checkRoundTrip(msg + " empty map", v);
00397
00398 v = LLSD::emptyMap();
00399 v["name"] = "luke";
00400 v["age"] = 3;
00401 checkRoundTrip(msg + " map", v);
00402
00403 v.clear();
00404 v["a"]["1"] = true;
00405 v["b"]["0"] = false;
00406 checkRoundTrip(msg + " nested maps", v);
00407
00408 v = LLSD::emptyArray();
00409 checkRoundTrip(msg + " empty array", v);
00410
00411 v = LLSD::emptyArray();
00412 v.append("ali");
00413 v.append(28);
00414 checkRoundTrip(msg + " array", v);
00415
00416 v.clear();
00417 v[0][0] = true;
00418 v[1][0] = false;
00419 checkRoundTrip(msg + " nested arrays", v);
00420
00421 v = LLSD::emptyMap();
00422 fillmap(v, 10, 6);
00423 checkRoundTrip(msg + " many nested maps", v);
00424 }
00425
00426 typedef tut::test_group<TestLLSDSerializeData> TestLLSDSerialzeGroup;
00427 typedef TestLLSDSerialzeGroup::object TestLLSDSerializeObject;
00428 TestLLSDSerialzeGroup gTestLLSDSerializeGroup("llsd serialization");
00429
00430 template<> template<>
00431 void TestLLSDSerializeObject::test<1>()
00432 {
00433 mFormatter = new LLSDNotationFormatter();
00434 mParser = new LLSDNotationParser();
00435 doRoundTripTests("notation serialization");
00436 }
00437
00438 template<> template<>
00439 void TestLLSDSerializeObject::test<2>()
00440 {
00441 mFormatter = new LLSDXMLFormatter();
00442 mParser = new LLSDXMLParser();
00443 doRoundTripTests("xml serialization");
00444 }
00445
00446 template<> template<>
00447 void TestLLSDSerializeObject::test<3>()
00448 {
00449 mFormatter = new LLSDBinaryFormatter();
00450 mParser = new LLSDBinaryParser();
00451 doRoundTripTests("binary serialization");
00452 }
00453
00454
00459 template <class parser_t>
00460 class TestLLSDParsing
00461 {
00462 public:
00463 TestLLSDParsing()
00464 {
00465 mParser = new parser_t;
00466 }
00467
00468 void ensureParse(
00469 const std::string& msg,
00470 const std::string& in,
00471 const LLSD& expected_value,
00472 S32 expected_count)
00473 {
00474 std::stringstream input;
00475 input.str(in);
00476
00477 LLSD parsed_result;
00478 S32 parsed_count = mParser->parse(input, parsed_result, in.size());
00479 ensure_equals(msg, parsed_result, expected_value);
00480
00481
00482
00483
00484 std::string count_msg(msg);
00485 count_msg += " (count)";
00486 ensure_equals(count_msg, parsed_count, expected_count);
00487 }
00488
00489 LLPointer<parser_t> mParser;
00490 };
00491
00492
00497 class TestLLSDXMLParsing : public TestLLSDParsing<LLSDXMLParser>
00498 {
00499 public:
00500 TestLLSDXMLParsing() {}
00501 };
00502
00503 typedef tut::test_group<TestLLSDXMLParsing> TestLLSDXMLParsingGroup;
00504 typedef TestLLSDXMLParsingGroup::object TestLLSDXMLParsingObject;
00505 TestLLSDXMLParsingGroup gTestLLSDXMLParsingGroup("llsd XML parsing");
00506
00507 template<> template<>
00508 void TestLLSDXMLParsingObject::test<1>()
00509 {
00510
00511
00512 ensureParse(
00513 "malformed xml",
00514 "<llsd><string>ha ha</string>",
00515 LLSD(),
00516 LLSDParser::PARSE_FAILURE);
00517 ensureParse(
00518 "not llsd",
00519 "<html><body><p>ha ha</p></body></html>",
00520 LLSD(),
00521 LLSDParser::PARSE_FAILURE);
00522 ensureParse(
00523 "value without llsd",
00524 "<string>ha ha</string>",
00525 LLSD(),
00526 LLSDParser::PARSE_FAILURE);
00527 ensureParse(
00528 "key without llsd",
00529 "<key>ha ha</key>",
00530 LLSD(),
00531 LLSDParser::PARSE_FAILURE);
00532 }
00533
00534
00535 template<> template<>
00536 void TestLLSDXMLParsingObject::test<2>()
00537 {
00538
00539 LLSD v;
00540 v["amy"] = 23;
00541 v["bob"] = LLSD();
00542 v["cam"] = 1.23;
00543
00544 ensureParse(
00545 "unknown data type",
00546 "<llsd><map>"
00547 "<key>amy</key><integer>23</integer>"
00548 "<key>bob</key><bigint>99999999999999999</bigint>"
00549 "<key>cam</key><real>1.23</real>"
00550 "</map></llsd>",
00551 v,
00552 v.size() + 1);
00553 }
00554
00555 template<> template<>
00556 void TestLLSDXMLParsingObject::test<3>()
00557 {
00558
00559
00560 LLSD v;
00561 v["amy"] = 23;
00562 v["cam"] = 1.23;
00563
00564 ensureParse(
00565 "map with html",
00566 "<llsd><map>"
00567 "<key>amy</key><integer>23</integer>"
00568 "<html><body>ha ha</body></html>"
00569 "<key>cam</key><real>1.23</real>"
00570 "</map></llsd>",
00571 v,
00572 v.size() + 1);
00573
00574 v.clear();
00575 v["amy"] = 23;
00576 v["cam"] = 1.23;
00577 ensureParse(
00578 "map with value for key",
00579 "<llsd><map>"
00580 "<key>amy</key><integer>23</integer>"
00581 "<string>ha ha</string>"
00582 "<key>cam</key><real>1.23</real>"
00583 "</map></llsd>",
00584 v,
00585 v.size() + 1);
00586
00587 v.clear();
00588 v["amy"] = 23;
00589 v["bob"] = LLSD::emptyMap();
00590 v["cam"] = 1.23;
00591 ensureParse(
00592 "map with map of html",
00593 "<llsd><map>"
00594 "<key>amy</key><integer>23</integer>"
00595 "<key>bob</key>"
00596 "<map>"
00597 "<html><body>ha ha</body></html>"
00598 "</map>"
00599 "<key>cam</key><real>1.23</real>"
00600 "</map></llsd>",
00601 v,
00602 v.size() + 1);
00603
00604 v.clear();
00605 v[0] = 23;
00606 v[1] = LLSD();
00607 v[2] = 1.23;
00608
00609 ensureParse(
00610 "array value of html",
00611 "<llsd><array>"
00612 "<integer>23</integer>"
00613 "<html><body>ha ha</body></html>"
00614 "<real>1.23</real>"
00615 "</array></llsd>",
00616 v,
00617 v.size() + 1);
00618
00619 v.clear();
00620 v[0] = 23;
00621 v[1] = LLSD::emptyMap();
00622 v[2] = 1.23;
00623 ensureParse(
00624 "array with map of html",
00625 "<llsd><array>"
00626 "<integer>23</integer>"
00627 "<map>"
00628 "<html><body>ha ha</body></html>"
00629 "</map>"
00630 "<real>1.23</real>"
00631 "</array></llsd>",
00632 v,
00633 v.size() + 1);
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00649 class TestLLSDNotationParsing : public TestLLSDParsing<LLSDNotationParser>
00650 {
00651 public:
00652 TestLLSDNotationParsing() {}
00653 };
00654
00655 typedef tut::test_group<TestLLSDNotationParsing> TestLLSDNotationParsingGroup;
00656 typedef TestLLSDNotationParsingGroup::object TestLLSDNotationParsingObject;
00657 TestLLSDNotationParsingGroup gTestLLSDNotationParsingGroup(
00658 "llsd notation parsing");
00659
00660 template<> template<>
00661 void TestLLSDNotationParsingObject::test<1>()
00662 {
00663
00664
00665 ensureParse(
00666 "malformed notation map",
00667 "{'ha ha'",
00668 LLSD(),
00669 LLSDParser::PARSE_FAILURE);
00670 ensureParse(
00671 "malformed notation array",
00672 "['ha ha'",
00673 LLSD(),
00674 LLSDParser::PARSE_FAILURE);
00675 ensureParse(
00676 "malformed notation string",
00677 "'ha ha",
00678 LLSD(),
00679 LLSDParser::PARSE_FAILURE);
00680 ensureParse(
00681 "bad notation noise",
00682 "g48ejlnfr",
00683 LLSD(),
00684 LLSDParser::PARSE_FAILURE);
00685 }
00686
00687 template<> template<>
00688 void TestLLSDNotationParsingObject::test<2>()
00689 {
00690 ensureParse("valid undef", "!", LLSD(), 1);
00691 }
00692
00693 template<> template<>
00694 void TestLLSDNotationParsingObject::test<3>()
00695 {
00696 LLSD val = false;
00697 ensureParse("valid boolean false 0", "false", val, 1);
00698 ensureParse("valid boolean false 1", "f", val, 1);
00699 ensureParse("valid boolean false 2", "0", val, 1);
00700 ensureParse("valid boolean false 3", "F", val, 1);
00701 ensureParse("valid boolean false 4", "FALSE", val, 1);
00702 val = true;
00703 ensureParse("valid boolean true 0", "true", val, 1);
00704 ensureParse("valid boolean true 1", "t", val, 1);
00705 ensureParse("valid boolean true 2", "1", val, 1);
00706 ensureParse("valid boolean true 3", "T", val, 1);
00707 ensureParse("valid boolean true 4", "TRUE", val, 1);
00708
00709 val.clear();
00710 ensureParse("invalid true", "TR", val, LLSDParser::PARSE_FAILURE);
00711 ensureParse("invalid false", "FAL", val, LLSDParser::PARSE_FAILURE);
00712 }
00713
00714 template<> template<>
00715 void TestLLSDNotationParsingObject::test<4>()
00716 {
00717 LLSD val = 123;
00718 ensureParse("valid integer", "i123", val, 1);
00719 val.clear();
00720 ensureParse("invalid integer", "421", val, LLSDParser::PARSE_FAILURE);
00721 }
00722
00723 template<> template<>
00724 void TestLLSDNotationParsingObject::test<5>()
00725 {
00726 LLSD val = 456.7;
00727 ensureParse("valid real", "r456.7", val, 1);
00728 val.clear();
00729 ensureParse("invalid real", "456.7", val, LLSDParser::PARSE_FAILURE);
00730 }
00731
00732 template<> template<>
00733 void TestLLSDNotationParsingObject::test<6>()
00734 {
00735 LLUUID id;
00736 LLSD val = id;
00737 ensureParse(
00738 "unparseable uuid",
00739 "u123",
00740 LLSD(),
00741 LLSDParser::PARSE_FAILURE);
00742 id.generate();
00743 val = id;
00744 std::string uuid_str("u");
00745 uuid_str += id.asString();
00746 ensureParse("valid uuid", uuid_str.c_str(), val, 1);
00747 }
00748
00749 template<> template<>
00750 void TestLLSDNotationParsingObject::test<7>()
00751 {
00752 LLSD val = std::string("foolish");
00753 ensureParse("valid string 1", "\"foolish\"", val, 1);
00754 val = std::string("g'day");
00755 ensureParse("valid string 2", "\"g'day\"", val, 1);
00756 val = std::string("have a \"nice\" day");
00757 ensureParse("valid string 3", "'have a \"nice\" day'", val, 1);
00758 val = std::string("whatever");
00759 ensureParse("valid string 4", "s(8)\"whatever\"", val, 1);
00760 }
00761
00762 template<> template<>
00763 void TestLLSDNotationParsingObject::test<8>()
00764 {
00765 ensureParse(
00766 "invalid string 1",
00767 "s(7)\"whatever\"",
00768 LLSD(),
00769 LLSDParser::PARSE_FAILURE);
00770 ensureParse(
00771 "invalid string 2",
00772 "s(9)\"whatever\"",
00773 LLSD(),
00774 LLSDParser::PARSE_FAILURE);
00775 }
00776
00777 template<> template<>
00778 void TestLLSDNotationParsingObject::test<9>()
00779 {
00780 LLSD val = LLURI("http://www.google.com");
00781 ensureParse("valid uri", "l\"http://www.google.com\"", val, 1);
00782 }
00783
00784 template<> template<>
00785 void TestLLSDNotationParsingObject::test<10>()
00786 {
00787 LLSD val = LLDate("2007-12-28T09:22:53.10Z");
00788 ensureParse("valid date", "d\"2007-12-28T09:22:53.10Z\"", val, 1);
00789 }
00790
00791 template<> template<>
00792 void TestLLSDNotationParsingObject::test<11>()
00793 {
00794 std::vector<U8> vec;
00795 vec.push_back((U8)'a'); vec.push_back((U8)'b'); vec.push_back((U8)'c');
00796 vec.push_back((U8)'3'); vec.push_back((U8)'2'); vec.push_back((U8)'1');
00797 LLSD val = vec;
00798 ensureParse("valid binary b64", "b64\"YWJjMzIx\"", val, 1);
00799 ensureParse("valid bainry b16", "b16\"616263333231\"", val, 1);
00800 ensureParse("valid bainry raw", "b(6)\"abc321\"", val, 1);
00801 }
00802
00803 template<> template<>
00804 void TestLLSDNotationParsingObject::test<12>()
00805 {
00806 ensureParse(
00807 "invalid -- binary length specified too long",
00808 "b(7)\"abc321\"",
00809 LLSD(),
00810 LLSDParser::PARSE_FAILURE);
00811 ensureParse(
00812 "invalid -- binary length specified way too long",
00813 "b(1000000)\"abc321\"",
00814 LLSD(),
00815 LLSDParser::PARSE_FAILURE);
00816 }
00817
00818 template<> template<>
00819 void TestLLSDNotationParsingObject::test<13>()
00820 {
00821 LLSD val;
00822 val["amy"] = 23;
00823 val["bob"] = LLSD();
00824 val["cam"] = 1.23;
00825 ensureParse("simple map", "{'amy':i23,'bob':!,'cam':r1.23}", val, 4);
00826
00827 val["bob"] = LLSD::emptyMap();
00828 val["bob"]["vehicle"] = std::string("bicycle");
00829 ensureParse(
00830 "nested map",
00831 "{'amy':i23,'bob':{'vehicle':'bicycle'},'cam':r1.23}",
00832 val,
00833 5);
00834 }
00835
00836 template<> template<>
00837 void TestLLSDNotationParsingObject::test<14>()
00838 {
00839 LLSD val;
00840 val.append(23);
00841 val.append(LLSD());
00842 val.append(1.23);
00843 ensureParse("simple array", "[i23,!,r1.23]", val, 4);
00844 val[1] = LLSD::emptyArray();
00845 val[1].append("bicycle");
00846 ensureParse("nested array", "[i23,['bicycle'],r1.23]", val, 5);
00847 }
00848
00849 template<> template<>
00850 void TestLLSDNotationParsingObject::test<15>()
00851 {
00852 LLSD val;
00853 val["amy"] = 23;
00854 val["bob"]["dogs"] = LLSD::emptyArray();
00855 val["bob"]["dogs"].append(LLSD::emptyMap());
00856 val["bob"]["dogs"][0]["name"] = std::string("groove");
00857 val["bob"]["dogs"][0]["breed"] = std::string("samoyed");
00858 val["bob"]["dogs"].append(LLSD::emptyMap());
00859 val["bob"]["dogs"][1]["name"] = std::string("greyley");
00860 val["bob"]["dogs"][1]["breed"] = std::string("chow/husky");
00861 val["cam"] = 1.23;
00862 ensureParse(
00863 "nested notation",
00864 "{'amy':i23,"
00865 " 'bob':{'dogs':["
00866 "{'name':'groove', 'breed':'samoyed'},"
00867 "{'name':'greyley', 'breed':'chow/husky'}]},"
00868 " 'cam':r1.23}",
00869 val,
00870 11);
00871 }
00872
00873 template<> template<>
00874 void TestLLSDNotationParsingObject::test<16>()
00875 {
00876
00877 std::string bad_str("s(5)\"hi\"");
00878 ensureParse(
00879 "size longer than bytes left",
00880 bad_str,
00881 LLSD(),
00882 LLSDParser::PARSE_FAILURE);
00883 }
00884
00885 template<> template<>
00886 void TestLLSDNotationParsingObject::test<17>()
00887 {
00888
00889 std::string bad_bin("b(5)\"hi\"");
00890 ensureParse(
00891 "size longer than bytes left",
00892 bad_bin,
00893 LLSD(),
00894 LLSDParser::PARSE_FAILURE);
00895 }
00896
00901 class TestLLSDBinaryParsing : public TestLLSDParsing<LLSDBinaryParser>
00902 {
00903 public:
00904 TestLLSDBinaryParsing() {}
00905 };
00906
00907 typedef tut::test_group<TestLLSDBinaryParsing> TestLLSDBinaryParsingGroup;
00908 typedef TestLLSDBinaryParsingGroup::object TestLLSDBinaryParsingObject;
00909 TestLLSDBinaryParsingGroup gTestLLSDBinaryParsingGroup(
00910 "llsd binary parsing");
00911
00912 template<> template<>
00913 void TestLLSDBinaryParsingObject::test<1>()
00914 {
00915 std::vector<U8> vec;
00916 vec.resize(6);
00917 vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c';
00918 vec[3] = '3'; vec[4] = '2'; vec[5] = '1';
00919 std::string string_expected((char*)&vec[0], vec.size());
00920 LLSD value = string_expected;
00921
00922 vec.resize(11);
00923 vec[0] = 's';
00924 vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c';
00925 vec[8] = '3'; vec[9] = '2'; vec[10] = '1';
00926
00927 uint32_t size = htonl(6);
00928 memcpy(&vec[1], &size, sizeof(uint32_t));
00929 std::string str_good((char*)&vec[0], vec.size());
00930 ensureParse("correct string parse", str_good, value, 1);
00931
00932 size = htonl(7);
00933 memcpy(&vec[1], &size, sizeof(uint32_t));
00934 std::string str_bad_1((char*)&vec[0], vec.size());
00935 ensureParse(
00936 "incorrect size string parse",
00937 str_bad_1,
00938 LLSD(),
00939 LLSDParser::PARSE_FAILURE);
00940
00941 size = htonl(100000);
00942 memcpy(&vec[1], &size, sizeof(uint32_t));
00943 std::string str_bad_2((char*)&vec[0], vec.size());
00944 ensureParse(
00945 "incorrect size string parse",
00946 str_bad_2,
00947 LLSD(),
00948 LLSDParser::PARSE_FAILURE);
00949 }
00950
00951 template<> template<>
00952 void TestLLSDBinaryParsingObject::test<2>()
00953 {
00954 std::vector<U8> vec;
00955 vec.resize(6);
00956 vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c';
00957 vec[3] = '3'; vec[4] = '2'; vec[5] = '1';
00958 LLSD value = vec;
00959
00960 vec.resize(11);
00961 vec[0] = 'b';
00962 vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c';
00963 vec[8] = '3'; vec[9] = '2'; vec[10] = '1';
00964
00965 uint32_t size = htonl(6);
00966 memcpy(&vec[1], &size, sizeof(uint32_t));
00967 std::string str_good((char*)&vec[0], vec.size());
00968 ensureParse("correct binary parse", str_good, value, 1);
00969
00970 size = htonl(7);
00971 memcpy(&vec[1], &size, sizeof(uint32_t));
00972 std::string str_bad_1((char*)&vec[0], vec.size());
00973 ensureParse(
00974 "incorrect size binary parse 1",
00975 str_bad_1,
00976 LLSD(),
00977 LLSDParser::PARSE_FAILURE);
00978
00979 size = htonl(100000);
00980 memcpy(&vec[1], &size, sizeof(uint32_t));
00981 std::string str_bad_2((char*)&vec[0], vec.size());
00982 ensureParse(
00983 "incorrect size binary parse 2",
00984 str_bad_2,
00985 LLSD(),
00986 LLSDParser::PARSE_FAILURE);
00987 }
00988
00989 template<> template<>
00990 void TestLLSDBinaryParsingObject::test<3>()
00991 {
00992
00993
00994 ensureParse(
00995 "malformed binary map",
00996 "{'ha ha'",
00997 LLSD(),
00998 LLSDParser::PARSE_FAILURE);
00999 ensureParse(
01000 "malformed binary array",
01001 "['ha ha'",
01002 LLSD(),
01003 LLSDParser::PARSE_FAILURE);
01004 ensureParse(
01005 "malformed binary string",
01006 "'ha ha",
01007 LLSD(),
01008 LLSDParser::PARSE_FAILURE);
01009 ensureParse(
01010 "bad noise",
01011 "g48ejlnfr",
01012 LLSD(),
01013 LLSDParser::PARSE_FAILURE);
01014 }
01015 template<> template<>
01016 void TestLLSDBinaryParsingObject::test<4>()
01017 {
01018 ensureParse("valid undef", "!", LLSD(), 1);
01019 }
01020
01021 template<> template<>
01022 void TestLLSDBinaryParsingObject::test<5>()
01023 {
01024 LLSD val = false;
01025 ensureParse("valid boolean false 2", "0", val, 1);
01026 val = true;
01027 ensureParse("valid boolean true 2", "1", val, 1);
01028
01029 val.clear();
01030 ensureParse("invalid true", "t", val, LLSDParser::PARSE_FAILURE);
01031 ensureParse("invalid false", "f", val, LLSDParser::PARSE_FAILURE);
01032 }
01033
01034 template<> template<>
01035 void TestLLSDBinaryParsingObject::test<6>()
01036 {
01037 std::vector<U8> vec;
01038 vec.push_back('{');
01039 vec.resize(vec.size() + 4);
01040 uint32_t size = htonl(1);
01041 memcpy(&vec[1], &size, sizeof(uint32_t));
01042 vec.push_back('k');
01043 int key_size_loc = vec.size();
01044 size = htonl(1);
01045 vec.resize(vec.size() + 4);
01046 memcpy(&vec[key_size_loc], &size, sizeof(uint32_t));
01047 vec.push_back('a'); vec.push_back('m'); vec.push_back('y');
01048 vec.push_back('i');
01049 int integer_loc = vec.size();
01050 vec.resize(vec.size() + 4);
01051 uint32_t val_int = htonl(23);
01052 memcpy(&vec[integer_loc], &val_int, sizeof(uint32_t));
01053 std::string str_bad_1((char*)&vec[0], vec.size());
01054 ensureParse(
01055 "invalid key size",
01056 str_bad_1,
01057 LLSD(),
01058 LLSDParser::PARSE_FAILURE);
01059
01060
01061 size = htonl(3);
01062 memcpy(&vec[key_size_loc], &size, sizeof(uint32_t));
01063 std::string str_bad_2((char*)&vec[0], vec.size());
01064 ensureParse(
01065 "valid key size, unterminated map",
01066 str_bad_2,
01067 LLSD(),
01068 LLSDParser::PARSE_FAILURE);
01069
01070
01071 LLSD val;
01072 val["amy"] = 23;
01073 vec.push_back('}');
01074 std::string str_good((char*)&vec[0], vec.size());
01075 ensureParse(
01076 "valid map",
01077 str_good,
01078 val,
01079 2);
01080
01081
01082 size = htonl(0);
01083 memcpy(&vec[1], &size, sizeof(uint32_t));
01084 std::string str_bad_3((char*)&vec[0], vec.size());
01085 ensureParse(
01086 "invalid map too long",
01087 str_bad_3,
01088 LLSD(),
01089 LLSDParser::PARSE_FAILURE);
01090
01091 size = htonl(2);
01092 memcpy(&vec[1], &size, sizeof(uint32_t));
01093 std::string str_bad_4((char*)&vec[0], vec.size());
01094 ensureParse(
01095 "invalid map too short",
01096 str_bad_4,
01097 LLSD(),
01098 LLSDParser::PARSE_FAILURE);
01099 }
01100
01101 template<> template<>
01102 void TestLLSDBinaryParsingObject::test<7>()
01103 {
01104 std::vector<U8> vec;
01105 vec.push_back('[');
01106 vec.resize(vec.size() + 4);
01107 uint32_t size = htonl(1);
01108 memcpy(&vec[1], &size, sizeof(uint32_t));
01109 vec.push_back('"'); vec.push_back('a'); vec.push_back('m');
01110 vec.push_back('y'); vec.push_back('"'); vec.push_back('i');
01111 int integer_loc = vec.size();
01112 vec.resize(vec.size() + 4);
01113 uint32_t val_int = htonl(23);
01114 memcpy(&vec[integer_loc], &val_int, sizeof(uint32_t));
01115
01116 std::string str_bad_1((char*)&vec[0], vec.size());
01117 ensureParse(
01118 "invalid array size",
01119 str_bad_1,
01120 LLSD(),
01121 LLSDParser::PARSE_FAILURE);
01122
01123
01124 size = htonl(2);
01125 memcpy(&vec[1], &size, sizeof(uint32_t));
01126 std::string str_bad_2((char*)&vec[0], vec.size());
01127 ensureParse(
01128 "unterminated array",
01129 str_bad_2,
01130 LLSD(),
01131 LLSDParser::PARSE_FAILURE);
01132
01133
01134 LLSD val;
01135 val.append("amy");
01136 val.append(23);
01137 vec.push_back(']');
01138 std::string str_good((char*)&vec[0], vec.size());
01139 ensureParse(
01140 "valid array",
01141 str_good,
01142 val,
01143 3);
01144
01145
01146 size = htonl(3);
01147 memcpy(&vec[1], &size, sizeof(uint32_t));
01148 std::string str_bad_3((char*)&vec[0], vec.size());
01149 ensureParse(
01150 "array too short",
01151 str_bad_3,
01152 LLSD(),
01153 LLSDParser::PARSE_FAILURE);
01154 }
01155
01156 template<> template<>
01157 void TestLLSDBinaryParsingObject::test<8>()
01158 {
01159 std::vector<U8> vec;
01160 vec.push_back('{');
01161 vec.resize(vec.size() + 4);
01162 memset(&vec[1], 0, 4);
01163 vec.push_back('}');
01164 std::string str_good((char*)&vec[0], vec.size());
01165 LLSD val = LLSD::emptyMap();
01166 ensureParse(
01167 "empty map",
01168 str_good,
01169 val,
01170 1);
01171 }
01172
01173 template<> template<>
01174 void TestLLSDBinaryParsingObject::test<9>()
01175 {
01176 std::vector<U8> vec;
01177 vec.push_back('[');
01178 vec.resize(vec.size() + 4);
01179 memset(&vec[1], 0, 4);
01180 vec.push_back(']');
01181 std::string str_good((char*)&vec[0], vec.size());
01182 LLSD val = LLSD::emptyArray();
01183 ensureParse(
01184 "empty array",
01185 str_good,
01186 val,
01187 1);
01188 }
01189
01190 template<> template<>
01191 void TestLLSDBinaryParsingObject::test<10>()
01192 {
01193 std::vector<U8> vec;
01194 vec.push_back('l');
01195 vec.resize(vec.size() + 4);
01196 uint32_t size = htonl(14);
01197 memcpy(&vec[1], &size, sizeof(uint32_t));
01198 vec.push_back('h'); vec.push_back('t'); vec.push_back('t');
01199 vec.push_back('p'); vec.push_back(':'); vec.push_back('/');
01200 vec.push_back('/'); vec.push_back('s'); vec.push_back('l');
01201 vec.push_back('.'); vec.push_back('c'); vec.push_back('o');
01202 vec.push_back('m');
01203 std::string str_bad((char*)&vec[0], vec.size());
01204 ensureParse(
01205 "invalid uri length size",
01206 str_bad,
01207 LLSD(),
01208 LLSDParser::PARSE_FAILURE);
01209
01210 LLSD val;
01211 val = LLURI("http://sl.com");
01212 size = htonl(13);
01213 memcpy(&vec[1], &size, sizeof(uint32_t));
01214 std::string str_good((char*)&vec[0], vec.size());
01215 ensureParse(
01216 "valid key size",
01217 str_good,
01218 val,
01219 1);
01220 }
01221
01222
01223
01224
01225
01226
01227
01228
01233 class TestLLSDCrossCompatible
01234 {
01235 public:
01236 TestLLSDCrossCompatible() {}
01237
01238 void ensureBinaryAndNotation(
01239 const std::string& msg,
01240 const LLSD& input)
01241 {
01242
01243 std::stringstream str1;
01244 S32 count1 = LLSDSerialize::toBinary(input, str1);
01245 LLSD actual_value_bin;
01246 S32 count2 = LLSDSerialize::fromBinary(
01247 actual_value_bin,
01248 str1,
01249 LLSDSerialize::SIZE_UNLIMITED);
01250 ensure_equals(
01251 "ensureBinaryAndNotation binary count",
01252 count2,
01253 count1);
01254
01255
01256 std::stringstream str2;
01257 S32 count3 = LLSDSerialize::toNotation(actual_value_bin, str2);
01258 ensure_equals(
01259 "ensureBinaryAndNotation notation count1",
01260 count3,
01261 count2);
01262 LLSD actual_value_notation;
01263 S32 count4 = LLSDSerialize::fromNotation(
01264 actual_value_notation,
01265 str2,
01266 LLSDSerialize::SIZE_UNLIMITED);
01267 ensure_equals(
01268 "ensureBinaryAndNotation notation count2",
01269 count4,
01270 count3);
01271 ensure_equals(
01272 msg + " (binaryandnotation)",
01273 actual_value_notation,
01274 input);
01275 }
01276
01277 void ensureBinaryAndXML(
01278 const std::string& msg,
01279 const LLSD& input)
01280 {
01281
01282 std::stringstream str1;
01283 S32 count1 = LLSDSerialize::toBinary(input, str1);
01284 LLSD actual_value_bin;
01285 S32 count2 = LLSDSerialize::fromBinary(
01286 actual_value_bin,
01287 str1,
01288 LLSDSerialize::SIZE_UNLIMITED);
01289 ensure_equals(
01290 "ensureBinaryAndXML binary count",
01291 count2,
01292 count1);
01293
01294
01295 std::stringstream str2;
01296 S32 count3 = LLSDSerialize::toXML(actual_value_bin, str2);
01297 ensure_equals(
01298 "ensureBinaryAndXML xml count1",
01299 count3,
01300 count2);
01301 LLSD actual_value_xml;
01302 S32 count4 = LLSDSerialize::fromXML(actual_value_xml, str2);
01303 ensure_equals(
01304 "ensureBinaryAndXML xml count2",
01305 count4,
01306 count3);
01307 ensure_equals(msg + " (binaryandxml)", actual_value_xml, input);
01308 }
01309 };
01310
01311 typedef tut::test_group<TestLLSDCrossCompatible> TestLLSDCompatibleGroup;
01312 typedef TestLLSDCompatibleGroup::object TestLLSDCompatibleObject;
01313 TestLLSDCompatibleGroup gTestLLSDCompatibleGroup(
01314 "llsd serialize compatible");
01315
01316 template<> template<>
01317 void TestLLSDCompatibleObject::test<1>()
01318 {
01319 LLSD test;
01320 ensureBinaryAndNotation("undef", test);
01321 ensureBinaryAndXML("undef", test);
01322 test = true;
01323 ensureBinaryAndNotation("boolean true", test);
01324 ensureBinaryAndXML("boolean true", test);
01325 test = false;
01326 ensureBinaryAndNotation("boolean false", test);
01327 ensureBinaryAndXML("boolean false", test);
01328 test = 0;
01329 ensureBinaryAndNotation("integer zero", test);
01330 ensureBinaryAndXML("integer zero", test);
01331 test = 1;
01332 ensureBinaryAndNotation("integer positive", test);
01333 ensureBinaryAndXML("integer positive", test);
01334 test = -234567;
01335 ensureBinaryAndNotation("integer negative", test);
01336 ensureBinaryAndXML("integer negative", test);
01337 test = 0.0;
01338 ensureBinaryAndNotation("real zero", test);
01339 ensureBinaryAndXML("real zero", test);
01340 test = 1.0;
01341 ensureBinaryAndNotation("real positive", test);
01342 ensureBinaryAndXML("real positive", test);
01343 test = -1.0;
01344 ensureBinaryAndNotation("real negative", test);
01345 ensureBinaryAndXML("real negative", test);
01346 }
01347
01348 template<> template<>
01349 void TestLLSDCompatibleObject::test<2>()
01350 {
01351 LLSD test;
01352 test = "foobar";
01353 ensureBinaryAndNotation("string", test);
01354 ensureBinaryAndXML("string", test);
01355 }
01356
01357 template<> template<>
01358 void TestLLSDCompatibleObject::test<3>()
01359 {
01360 LLSD test;
01361 LLUUID id;
01362 id.generate();
01363 test = id;
01364 ensureBinaryAndNotation("uuid", test);
01365 ensureBinaryAndXML("uuid", test);
01366 }
01367
01368 template<> template<>
01369 void TestLLSDCompatibleObject::test<4>()
01370 {
01371 LLSD test;
01372 test = LLDate(12345.0);
01373 ensureBinaryAndNotation("date", test);
01374 ensureBinaryAndXML("date", test);
01375 }
01376
01377 template<> template<>
01378 void TestLLSDCompatibleObject::test<5>()
01379 {
01380 LLSD test;
01381 test = LLURI("http://www.secondlife.com/");
01382 ensureBinaryAndNotation("uri", test);
01383 ensureBinaryAndXML("uri", test);
01384 }
01385
01386 template<> template<>
01387 void TestLLSDCompatibleObject::test<6>()
01388 {
01389 LLSD test;
01390 typedef std::vector<U8> buf_t;
01391 buf_t val;
01392 for(int ii = 0; ii < 100; ++ii)
01393 {
01394 srand(ii);
01395 S32 size = rand() % 100 + 10;
01396 std::generate_n(
01397 std::back_insert_iterator<buf_t>(val),
01398 size,
01399 rand);
01400 }
01401 test = val;
01402 ensureBinaryAndNotation("binary", test);
01403 ensureBinaryAndXML("binary", test);
01404 }
01405
01406 template<> template<>
01407 void TestLLSDCompatibleObject::test<7>()
01408 {
01409 LLSD test;
01410 test = LLSD::emptyArray();
01411 test.append(1);
01412 test.append("hello");
01413 ensureBinaryAndNotation("array", test);
01414 ensureBinaryAndXML("array", test);
01415 }
01416
01417 template<> template<>
01418 void TestLLSDCompatibleObject::test<8>()
01419 {
01420 LLSD test;
01421 test = LLSD::emptyArray();
01422 test["foo"] = "bar";
01423 test["baz"] = 100;
01424 ensureBinaryAndNotation("map", test);
01425 ensureBinaryAndXML("map", test);
01426 }
01427 }
01428
01429 #endif