00001
00034 #include "linden_common.h"
00035 #include "llsdserialize.h"
00036 #include "llmemory.h"
00037 #include "llstreamtools.h"
00038
00039 #include <iostream>
00040 #include "apr-1/apr_base64.h"
00041
00042 #if !LL_WINDOWS
00043 #include <netinet/in.h>
00044 #endif
00045
00046 #include "lldate.h"
00047 #include "llsd.h"
00048 #include "lluri.h"
00049
00050
00051 static const int MAX_HDR_LEN = 20;
00052 static const char LEGACY_NON_HEADER[] = "<llsd>";
00053
00054
00055 const char* LLSDSerialize::LLSDBinaryHeader = "LLSD/Binary";
00056
00057
00058 const char* LLSDSerialize::LLSDXMLHeader = "LLSD/XML";
00059
00060
00061 LLSDParser::~LLSDParser()
00062 { }
00063
00064
00065 LLSDNotationParser::~LLSDNotationParser()
00066 { }
00067
00068
00069
00070 void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize type, U32 options)
00071 {
00072 LLPointer<LLSDFormatter> f = NULL;
00073
00074 switch (type)
00075 {
00076 case LLSD_BINARY:
00077 str << "<? " << LLSDBinaryHeader << " ?>\n";
00078 f = new LLSDBinaryFormatter;
00079 break;
00080
00081 case LLSD_XML:
00082 str << "<? " << LLSDXMLHeader << " ?>\n";
00083 f = new LLSDXMLFormatter;
00084 break;
00085
00086 default:
00087 llwarns << "serialize request for unkown ELLSD_Serialize" << llendl;
00088 }
00089
00090 if (f.notNull())
00091 {
00092 f->format(sd, str, options);
00093 }
00094 }
00095
00096
00097 bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str)
00098 {
00099 LLPointer<LLSDParser> p = NULL;
00100 char hdr_buf[MAX_HDR_LEN + 1] = "";
00101 int i;
00102 int inbuf = 0;
00103 bool legacy_no_header = false;
00104 bool fail_if_not_legacy = false;
00105 std::string header = "";
00106
00107
00108
00109
00110 str.get(hdr_buf, MAX_HDR_LEN, '\n');
00111 if (str.fail())
00112 {
00113 str.clear();
00114 fail_if_not_legacy = true;
00115 }
00116
00117 if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER)))
00118 {
00119 legacy_no_header = true;
00120 inbuf = str.gcount();
00121 }
00122 else
00123 {
00124 if (fail_if_not_legacy)
00125 goto fail;
00126
00127
00128
00129 for (i = 0; i < MAX_HDR_LEN; i++)
00130 {
00131 if (hdr_buf[i] == 0 || hdr_buf[i] == '\r' ||
00132 hdr_buf[i] == '\n')
00133 {
00134 hdr_buf[i] = 0;
00135 break;
00136 }
00137 }
00138 header = hdr_buf;
00139
00140 std::string::size_type start = std::string::npos;
00141 std::string::size_type end = std::string::npos;
00142 start = header.find_first_not_of("<? ");
00143 if (start != std::string::npos)
00144 {
00145 end = header.find_first_of(" ?", start);
00146 }
00147 if ((start == std::string::npos) || (end == std::string::npos))
00148 goto fail;
00149
00150 header = header.substr(start, end - start);
00151 ws(str);
00152 }
00153
00154
00155
00156 if (legacy_no_header)
00157 {
00158 LLSDXMLParser *x = new LLSDXMLParser;
00159 x->parsePart(hdr_buf, inbuf);
00160 p = x;
00161 }
00162 else if (header == LLSDBinaryHeader)
00163 {
00164 p = new LLSDBinaryParser;
00165 }
00166 else if (header == LLSDXMLHeader)
00167 {
00168 p = new LLSDXMLParser;
00169 }
00170 else
00171 {
00172 llwarns << "deserialize request for unknown ELLSD_Serialize" << llendl;
00173 }
00174
00175 if (p.notNull())
00176 {
00177 p->parse(str, sd);
00178 return true;
00179 }
00180
00181 fail:
00182 llwarns << "deserialize LLSD parse failure" << llendl;
00183 return false;
00184 }
00185
00189 #if LL_BIG_ENDIAN
00190 U64 ll_htonll(U64 hostlonglong) { return hostlonglong; }
00191 U64 ll_ntohll(U64 netlonglong) { return netlonglong; }
00192 F64 ll_htond(F64 hostlonglong) { return hostlonglong; }
00193 F64 ll_ntohd(F64 netlonglong) { return netlonglong; }
00194 #else
00195
00196
00197
00198
00199 U64 ll_htonll(U64 hostlonglong)
00200 {
00201 return ((U64)(htonl((U32)((hostlonglong >> 32) & 0xFFFFFFFF))) |
00202 ((U64)(htonl((U32)(hostlonglong & 0xFFFFFFFF))) << 32));
00203 }
00204 U64 ll_ntohll(U64 netlonglong)
00205 {
00206 return ((U64)(ntohl((U32)((netlonglong >> 32) & 0xFFFFFFFF))) |
00207 ((U64)(ntohl((U32)(netlonglong & 0xFFFFFFFF))) << 32));
00208 }
00209 union LLEndianSwapper
00210 {
00211 F64 d;
00212 U64 i;
00213 };
00214 F64 ll_htond(F64 hostdouble)
00215 {
00216 LLEndianSwapper tmp;
00217 tmp.d = hostdouble;
00218 tmp.i = ll_htonll(tmp.i);
00219 return tmp.d;
00220 }
00221 F64 ll_ntohd(F64 netdouble)
00222 {
00223 LLEndianSwapper tmp;
00224 tmp.d = netdouble;
00225 tmp.i = ll_ntohll(tmp.i);
00226 return tmp.d;
00227 }
00228 #endif
00229
00233 bool deserialize_string(std::istream& str, std::string& value);
00234 bool deserialize_string_delim(std::istream& str, std::string& value, char d);
00235 bool deserialize_string_raw(std::istream& str, std::string& value);
00236 void serialize_string(const std::string& value, std::ostream& str);
00237
00241 static const std::string NOTATION_TRUE_SERIAL("true");
00242 static const std::string NOTATION_FALSE_SERIAL("false");
00243
00244 static const char BINARY_TRUE_SERIAL = '1';
00245 static const char BINARY_FALSE_SERIAL = '0';
00246
00247 static const S32 NOTATION_PARSE_FAILURE = -1;
00248
00252 LLSDParser::LLSDParser()
00253 {
00254 }
00255
00259
00260 S32 LLSDNotationParser::parse(std::istream& istr, LLSD& data) const
00261 {
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 char c;
00274 c = istr.peek();
00275 while(isspace(c))
00276 {
00277
00278 c = istr.get();
00279 c = istr.peek();
00280 continue;
00281 }
00282 if(!istr.good())
00283 {
00284 return 0;
00285 }
00286 S32 parse_count = 1;
00287 switch(c)
00288 {
00289 case '{':
00290 parse_count += parseMap(istr, data);
00291 if(istr.fail())
00292 {
00293 llinfos << "STREAM FAILURE reading map." << llendl;
00294 }
00295 if(data.isUndefined())
00296 {
00297 parse_count = NOTATION_PARSE_FAILURE;
00298 }
00299 break;
00300
00301 case '[':
00302 parse_count += parseArray(istr, data);
00303 if(istr.fail())
00304 {
00305 llinfos << "STREAM FAILURE reading array." << llendl;
00306 }
00307 if(data.isUndefined())
00308 {
00309 parse_count = NOTATION_PARSE_FAILURE;
00310 }
00311 break;
00312
00313 case '!':
00314 c = istr.get();
00315 data.clear();
00316 break;
00317
00318 case '0':
00319 c = istr.get();
00320 data = false;
00321 break;
00322
00323 case 'F':
00324 case 'f':
00325 do
00326 {
00327 istr.ignore();
00328 c = istr.peek();
00329 } while (isalpha(c));
00330 data = false;
00331 if(istr.fail())
00332 {
00333 llinfos << "STREAM FAILURE reading boolean." << llendl;
00334 }
00335 break;
00336
00337 case '1':
00338 c = istr.get();
00339 data = true;
00340 break;
00341
00342 case 'T':
00343 case 't':
00344 do
00345 {
00346 istr.ignore();
00347 c = istr.peek();
00348 } while (isalpha(c));
00349 data = true;
00350 if(istr.fail())
00351 {
00352 llinfos << "STREAM FAILURE reading boolean." << llendl;
00353 }
00354 break;
00355
00356 case 'i':
00357 {
00358 c = istr.get();
00359 S32 integer = 0;
00360 istr >> integer;
00361 data = integer;
00362 if(istr.fail())
00363 {
00364 llinfos << "STREAM FAILURE reading integer." << llendl;
00365 }
00366 break;
00367 }
00368
00369 case 'r':
00370 {
00371 c = istr.get();
00372 F64 real = 0.0;
00373 istr >> real;
00374 data = real;
00375 if(istr.fail())
00376 {
00377 llinfos << "STREAM FAILURE reading real." << llendl;
00378 }
00379 break;
00380 }
00381
00382 case 'u':
00383 {
00384 c = istr.get();
00385 LLUUID id;
00386 istr >> id;
00387 data = id;
00388 if(istr.fail())
00389 {
00390 llinfos << "STREAM FAILURE reading uuid." << llendl;
00391 }
00392 break;
00393 }
00394
00395 case '\"':
00396 case '\'':
00397 case 's':
00398 parseString(istr, data);
00399 if(istr.fail())
00400 {
00401 llinfos << "STREAM FAILURE reading string." << llendl;
00402 }
00403 if(data.isUndefined())
00404 {
00405 parse_count = NOTATION_PARSE_FAILURE;
00406 }
00407 break;
00408
00409 case 'l':
00410 {
00411 c = istr.get();
00412 c = istr.get();
00413 std::string str;
00414 deserialize_string_delim(istr, str, c);
00415 data = LLURI(str);
00416 if(istr.fail())
00417 {
00418 llinfos << "STREAM FAILURE reading link." << llendl;
00419 }
00420 break;
00421 }
00422
00423 case 'd':
00424 {
00425 c = istr.get();
00426 c = istr.get();
00427 std::string str;
00428 deserialize_string_delim(istr, str, c);
00429 data = LLDate(str);
00430 if(istr.fail())
00431 {
00432 llinfos << "STREAM FAILURE reading date." << llendl;
00433 }
00434 break;
00435 }
00436
00437 case 'b':
00438 parseBinary(istr, data);
00439 if(istr.fail())
00440 {
00441 llinfos << "STREAM FAILURE reading data." << llendl;
00442 }
00443 if(data.isUndefined())
00444 {
00445 parse_count = NOTATION_PARSE_FAILURE;
00446 }
00447 break;
00448
00449 default:
00450 data.clear();
00451 parse_count = NOTATION_PARSE_FAILURE;
00452 llinfos << "Unrecognized character while parsing: int(" << (int)c
00453 << ")" << llendl;
00454 break;
00455 }
00456 return parse_count;
00457 }
00458
00459
00460 LLSD LLSDNotationParser::parse(std::istream& istr)
00461 {
00462 LLSDNotationParser parser;
00463 LLSD rv;
00464 S32 count = parser.parse(istr, rv);
00465 lldebugs << "LLSDNotationParser::parse parsed " << count << " objects."
00466 << llendl;
00467 return rv;
00468 }
00469
00470 S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
00471 {
00472
00473 map = LLSD::emptyMap();
00474 S32 parse_count = 0;
00475 char c = istr.get();
00476 if(c == '{')
00477 {
00478
00479 bool found_name = false;
00480 std::string name;
00481 c = istr.get();
00482 while(c != '}' && istr.good())
00483 {
00484 if(!found_name)
00485 {
00486 if((c == '\"') || (c == '\'') || (c == 's'))
00487 {
00488 istr.putback(c);
00489 found_name = true;
00490 deserialize_string(istr, name);
00491 }
00492 c = istr.get();
00493 }
00494 else
00495 {
00496 if(isspace(c) || (c == ':'))
00497 {
00498 c = istr.get();
00499 continue;
00500 }
00501 istr.putback(c);
00502 LLSD child;
00503 S32 count = parse(istr, child);
00504 if(count > 0)
00505 {
00506 parse_count += count;
00507 map.insert(name, child);
00508 }
00509 else
00510 {
00511 map.clear();
00512 return NOTATION_PARSE_FAILURE;
00513 }
00514 found_name = false;
00515 c = istr.get();
00516 }
00517 }
00518 }
00519 return parse_count;
00520 }
00521
00522 S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const
00523 {
00524
00525 array = LLSD::emptyArray();
00526 S32 parse_count = 0;
00527 char c = istr.get();
00528 if(c == '[')
00529 {
00530
00531 c = istr.get();
00532 while((c != ']') && istr.good())
00533 {
00534 LLSD child;
00535 if(isspace(c) || (c == ','))
00536 {
00537 c = istr.get();
00538 continue;
00539 }
00540 istr.putback(c);
00541 S32 count = parse(istr, child);
00542 if(count > 0)
00543 {
00544 parse_count += count;
00545 array.append(child);
00546 }
00547 else
00548 {
00549 array.clear();
00550 return NOTATION_PARSE_FAILURE;
00551 }
00552 c = istr.get();
00553 }
00554 }
00555 return parse_count;
00556 }
00557
00558 void LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
00559 {
00560 std::string value;
00561 if(deserialize_string(istr, value))
00562 {
00563 data = value;
00564 }
00565 else
00566 {
00567
00568 data.clear();
00569 }
00570 }
00571
00572 void LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
00573 {
00574
00575
00576
00577
00578
00579
00580 const U32 BINARY_BUFFER_SIZE = 256;
00581 const U32 STREAM_GET_COUNT = 255;
00582
00583
00584 char buf[BINARY_BUFFER_SIZE];
00585 istr.get(buf, STREAM_GET_COUNT, '"');
00586 char c = istr.get();
00587 if((c == '"') && (0 == strncmp("b(", buf, 2)))
00588 {
00589
00590
00591
00592 S32 len = strtol(buf + 2, NULL, 0);
00593 std::vector<U8> value;
00594 if(len)
00595 {
00596 value.resize(len);
00597 fullread(istr, (char *)&value[0], len);
00598 }
00599 c = istr.get();
00600 data = value;
00601 }
00602 else if((c == '"') && (0 == strncmp("b64", buf, 3)))
00603 {
00604
00605
00606
00607 std::stringstream coded_stream;
00608 istr.get(*(coded_stream.rdbuf()), '\"');
00609 c = istr.get();
00610 std::string encoded(coded_stream.str());
00611 S32 len = apr_base64_decode_len(encoded.c_str());
00612 std::vector<U8> value;
00613 value.resize(len);
00614 len = apr_base64_decode_binary(&value[0], encoded.c_str());
00615 value.resize(len);
00616 data = value;
00617 }
00618 else if((c == '"') && (0 == strncmp("b16", buf, 3)))
00619 {
00620
00621
00622
00623
00624 char* read;
00625 U8 byte;
00626 U8 byte_buffer[BINARY_BUFFER_SIZE];
00627 U8* write;
00628 std::vector<U8> value;
00629 c = istr.get();
00630 while(c != '"')
00631 {
00632 istr.putback(c);
00633 read = buf;
00634 write = byte_buffer;
00635 istr.get(buf, STREAM_GET_COUNT, '"');
00636 c = istr.get();
00637 while(*read != '\0')
00638 {
00639 byte = hex_as_nybble(*read++);
00640 byte = byte << 4;
00641 byte |= hex_as_nybble(*read++);
00642 *write++ = byte;
00643 }
00644
00645 value.insert(value.end(), byte_buffer, write);
00646 }
00647 data = value;
00648 }
00649 else
00650 {
00651 data.clear();
00652 }
00653 }
00654
00655
00659 LLSDBinaryParser::LLSDBinaryParser()
00660 {
00661 }
00662
00663
00664 LLSDBinaryParser::~LLSDBinaryParser()
00665 {
00666 }
00667
00668
00669 S32 LLSDBinaryParser::parse(std::istream& istr, LLSD& data) const
00670 {
00687 char c;
00688 c = istr.get();
00689 if(!istr.good())
00690 {
00691 return 0;
00692 }
00693 S32 parse_count = 1;
00694 switch(c)
00695 {
00696 case '{':
00697 parse_count += parseMap(istr, data);
00698 if(istr.fail())
00699 {
00700 llinfos << "STREAM FAILURE reading binary map." << llendl;
00701 }
00702 break;
00703
00704 case '[':
00705 parse_count += parseArray(istr, data);
00706 if(istr.fail())
00707 {
00708 llinfos << "STREAM FAILURE reading binary array." << llendl;
00709 }
00710 break;
00711
00712 case '!':
00713 data.clear();
00714 break;
00715
00716 case '0':
00717 data = false;
00718 break;
00719
00720 case '1':
00721 data = true;
00722 break;
00723
00724 case 'i':
00725 {
00726 U32 value_nbo = 0;
00727 istr.read((char*)&value_nbo, sizeof(U32));
00728 data = (S32)ntohl(value_nbo);
00729 if(istr.fail())
00730 {
00731 llinfos << "STREAM FAILURE reading binary integer." << llendl;
00732 }
00733 break;
00734 }
00735
00736 case 'r':
00737 {
00738 F64 real_nbo = 0.0;
00739 istr.read((char*)&real_nbo, sizeof(F64));
00740 data = ll_ntohd(real_nbo);
00741 if(istr.fail())
00742 {
00743 llinfos << "STREAM FAILURE reading binary real." << llendl;
00744 }
00745 break;
00746 }
00747
00748 case 'u':
00749 {
00750 LLUUID id;
00751 istr.read((char*)(&id.mData), UUID_BYTES);
00752 data = id;
00753 if(istr.fail())
00754 {
00755 llinfos << "STREAM FAILURE reading binary uuid." << llendl;
00756 }
00757 break;
00758 }
00759
00760 case '\'':
00761 case '"':
00762 {
00763 std::string value;
00764 deserialize_string_delim(istr, value, c);
00765 data = value;
00766 break;
00767 }
00768
00769 case 's':
00770 {
00771 std::string value;
00772 parseString(istr, value);
00773 data = value;
00774 if(istr.fail())
00775 {
00776 llinfos << "STREAM FAILURE reading binary string." << llendl;
00777 }
00778 break;
00779 }
00780
00781 case 'l':
00782 {
00783 std::string value;
00784 parseString(istr, value);
00785 data = LLURI(value);
00786 if(istr.fail())
00787 {
00788 llinfos << "STREAM FAILURE reading binary link." << llendl;
00789 }
00790 break;
00791 }
00792
00793 case 'd':
00794 {
00795 F64 real = 0.0;
00796 istr.read((char*)&real, sizeof(F64));
00797 data = LLDate(real);
00798 if(istr.fail())
00799 {
00800 llinfos << "STREAM FAILURE reading binary date." << llendl;
00801 }
00802 break;
00803 }
00804
00805 case 'b':
00806 {
00807
00808
00809
00810 U32 size_nbo = 0;
00811 istr.read((char*)&size_nbo, sizeof(U32));
00812 S32 size = (S32)ntohl(size_nbo);
00813 std::vector<U8> value;
00814 if(size)
00815 {
00816 value.resize(size);
00817 istr.read((char*)&value[0], size);
00818 }
00819 data = value;
00820 if(istr.fail())
00821 {
00822 llinfos << "STREAM FAILURE reading binary." << llendl;
00823 }
00824 break;
00825 }
00826
00827 default:
00828 --parse_count;
00829 llinfos << "Unrecognized character while parsing: int(" << (int)c
00830 << ")" << llendl;
00831 break;
00832 }
00833 return parse_count;
00834 }
00835
00836
00837 LLSD LLSDBinaryParser::parse(std::istream& istr)
00838 {
00839 LLSDBinaryParser parser;
00840 LLSD rv;
00841 S32 count = parser.parse(istr, rv);
00842 lldebugs << "LLSDBinaryParser::parse parsed " << count << " objects."
00843 << llendl;
00844 return rv;
00845 }
00846
00847 S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
00848 {
00849 map = LLSD::emptyMap();
00850 U32 value_nbo = 0;
00851 istr.read((char*)&value_nbo, sizeof(U32));
00852 S32 size = (S32)ntohl(value_nbo);
00853 S32 parse_count = 0;
00854 S32 count = 0;
00855 char c = istr.get();
00856 while(c != '}' && (count < size) && istr.good())
00857 {
00858 std::string name;
00859 switch(c)
00860 {
00861 case 'k':
00862 parseString(istr, name);
00863 break;
00864 case '\'':
00865 case '"':
00866 deserialize_string_delim(istr, name, c);
00867 break;
00868 }
00869 LLSD child;
00870 S32 child_count = parse(istr, child);
00871 if(child_count)
00872 {
00873 parse_count += child_count;
00874 map.insert(name, child);
00875 }
00876 ++count;
00877 c = istr.get();
00878 }
00879 return parse_count;
00880 }
00881
00882 S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
00883 {
00884 array = LLSD::emptyArray();
00885 U32 value_nbo = 0;
00886 istr.read((char*)&value_nbo, sizeof(U32));
00887 S32 size = (S32)ntohl(value_nbo);
00888
00889
00890
00891
00892 S32 parse_count = 0;
00893 S32 count = 0;
00894 char c = istr.peek();
00895 while((c != ']') && (count < size) && istr.good())
00896 {
00897 LLSD child;
00898 S32 child_count = parse(istr, child);
00899 if(child_count)
00900 {
00901 parse_count += child_count;
00902 array.append(child);
00903 }
00904 ++count;
00905 c = istr.peek();
00906 }
00907 c = istr.get();
00908 return parse_count;
00909 }
00910
00911 void LLSDBinaryParser::parseString(
00912 std::istream& istr,
00913 std::string& value) const
00914 {
00915
00916 U32 value_nbo = 0;
00917 istr.read((char*)&value_nbo, sizeof(U32));
00918 S32 size = (S32)ntohl(value_nbo);
00919 std::vector<char> buf;
00920 buf.resize(size);
00921 istr.read(&buf[0], size);
00922 value.assign(buf.begin(), buf.end());
00923 }
00924
00925
00929 LLSDFormatter::LLSDFormatter() :
00930 mBoolAlpha(false)
00931 {
00932 }
00933
00934
00935 LLSDFormatter::~LLSDFormatter()
00936 { }
00937
00938 void LLSDFormatter::boolalpha(bool alpha)
00939 {
00940 mBoolAlpha = alpha;
00941 }
00942
00943 void LLSDFormatter::realFormat(const std::string& format)
00944 {
00945 mRealFormat = format;
00946 }
00947
00948 void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const
00949 {
00950 char buffer[MAX_STRING];
00951 snprintf(buffer, MAX_STRING, mRealFormat.c_str(), real);
00952 ostr << buffer;
00953 }
00954
00958 LLSDNotationFormatter::LLSDNotationFormatter()
00959 {
00960 }
00961
00962
00963 LLSDNotationFormatter::~LLSDNotationFormatter()
00964 { }
00965
00966
00967 std::string LLSDNotationFormatter::escapeString(const std::string& in)
00968 {
00969 std::ostringstream ostr;
00970 serialize_string(in, ostr);
00971 return ostr.str();
00972 }
00973
00974
00975 S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
00976 {
00977 S32 format_count = 1;
00978 switch(data.type())
00979 {
00980 case LLSD::TypeMap:
00981 {
00982 ostr << "{";
00983 bool need_comma = false;
00984 LLSD::map_const_iterator iter = data.beginMap();
00985 LLSD::map_const_iterator end = data.endMap();
00986 for(; iter != end; ++iter)
00987 {
00988 if(need_comma) ostr << ",";
00989 need_comma = true;
00990 ostr << '\'';
00991 serialize_string((*iter).first, ostr);
00992 ostr << "':";
00993 format_count += format((*iter).second, ostr);
00994 }
00995 ostr << "}";
00996 break;
00997 }
00998
00999 case LLSD::TypeArray:
01000 {
01001 ostr << "[";
01002 bool need_comma = false;
01003 LLSD::array_const_iterator iter = data.beginArray();
01004 LLSD::array_const_iterator end = data.endArray();
01005 for(; iter != end; ++iter)
01006 {
01007 if(need_comma) ostr << ",";
01008 need_comma = true;
01009 format_count += format(*iter, ostr);
01010 }
01011 ostr << "]";
01012 break;
01013 }
01014
01015 case LLSD::TypeUndefined:
01016 ostr << "!";
01017 break;
01018
01019 case LLSD::TypeBoolean:
01020 if(mBoolAlpha ||
01021 #if( LL_WINDOWS || __GNUC__ > 2)
01022 (ostr.flags() & std::ios::boolalpha)
01023 #else
01024 (ostr.flags() & 0x0100)
01025 #endif
01026 )
01027 {
01028 ostr << (data.asBoolean()
01029 ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL);
01030 }
01031 else
01032 {
01033 ostr << (data.asBoolean() ? 1 : 0);
01034 }
01035 break;
01036
01037 case LLSD::TypeInteger:
01038 ostr << "i" << data.asInteger();
01039 break;
01040
01041 case LLSD::TypeReal:
01042 ostr << "r";
01043 if(mRealFormat.empty())
01044 {
01045 ostr << data.asReal();
01046 }
01047 else
01048 {
01049 formatReal(data.asReal(), ostr);
01050 }
01051 break;
01052
01053 case LLSD::TypeUUID:
01054 ostr << "u" << data.asUUID();
01055 break;
01056
01057 case LLSD::TypeString:
01058 ostr << '\'';
01059 serialize_string(data.asString(), ostr);
01060 ostr << '\'';
01061 break;
01062
01063 case LLSD::TypeDate:
01064 ostr << "d\"" << data.asDate() << "\"";
01065 break;
01066
01067 case LLSD::TypeURI:
01068 ostr << "l\"";
01069 serialize_string(data.asString(), ostr);
01070 ostr << "\"";
01071 break;
01072
01073 case LLSD::TypeBinary:
01074 {
01075
01076 std::vector<U8> buffer = data.asBinary();
01077 ostr << "b(" << buffer.size() << ")\"";
01078 if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
01079 ostr << "\"";
01080 break;
01081 }
01082
01083 default:
01084
01085 ostr << "!";
01086 break;
01087 }
01088 return format_count;
01089 }
01090
01091
01095 LLSDBinaryFormatter::LLSDBinaryFormatter()
01096 {
01097 }
01098
01099
01100 LLSDBinaryFormatter::~LLSDBinaryFormatter()
01101 { }
01102
01103
01104 S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
01105 {
01106 S32 format_count = 1;
01107 switch(data.type())
01108 {
01109 case LLSD::TypeMap:
01110 {
01111 ostr.put('{');
01112 U32 size_nbo = htonl(data.size());
01113 ostr.write((const char*)(&size_nbo), sizeof(U32));
01114 LLSD::map_const_iterator iter = data.beginMap();
01115 LLSD::map_const_iterator end = data.endMap();
01116 for(; iter != end; ++iter)
01117 {
01118 ostr.put('k');
01119 formatString((*iter).first, ostr);
01120 format_count += format((*iter).second, ostr);
01121 }
01122 ostr.put('}');
01123 break;
01124 }
01125
01126 case LLSD::TypeArray:
01127 {
01128 ostr.put('[');
01129 U32 size_nbo = htonl(data.size());
01130 ostr.write((const char*)(&size_nbo), sizeof(U32));
01131 LLSD::array_const_iterator iter = data.beginArray();
01132 LLSD::array_const_iterator end = data.endArray();
01133 for(; iter != end; ++iter)
01134 {
01135 format_count += format(*iter, ostr);
01136 }
01137 ostr.put(']');
01138 break;
01139 }
01140
01141 case LLSD::TypeUndefined:
01142 ostr.put('!');
01143 break;
01144
01145 case LLSD::TypeBoolean:
01146 if(data.asBoolean()) ostr.put(BINARY_TRUE_SERIAL);
01147 else ostr.put(BINARY_FALSE_SERIAL);
01148 break;
01149
01150 case LLSD::TypeInteger:
01151 {
01152 ostr.put('i');
01153 U32 value_nbo = htonl(data.asInteger());
01154 ostr.write((const char*)(&value_nbo), sizeof(U32));
01155 break;
01156 }
01157
01158 case LLSD::TypeReal:
01159 {
01160 ostr.put('r');
01161 F64 value_nbo = ll_htond(data.asReal());
01162 ostr.write((const char*)(&value_nbo), sizeof(F64));
01163 break;
01164 }
01165
01166 case LLSD::TypeUUID:
01167 ostr.put('u');
01168 ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES);
01169 break;
01170
01171 case LLSD::TypeString:
01172 ostr.put('s');
01173 formatString(data.asString(), ostr);
01174 break;
01175
01176 case LLSD::TypeDate:
01177 {
01178 ostr.put('d');
01179 F64 value = data.asReal();
01180 ostr.write((const char*)(&value), sizeof(F64));
01181 break;
01182 }
01183
01184 case LLSD::TypeURI:
01185 ostr.put('l');
01186 formatString(data.asString(), ostr);
01187 break;
01188
01189 case LLSD::TypeBinary:
01190 {
01191
01192 ostr.put('b');
01193 std::vector<U8> buffer = data.asBinary();
01194 U32 size_nbo = htonl(buffer.size());
01195 ostr.write((const char*)(&size_nbo), sizeof(U32));
01196 if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
01197 break;
01198 }
01199
01200 default:
01201
01202 ostr.put('!');
01203 break;
01204 }
01205 return format_count;
01206 }
01207
01208 void LLSDBinaryFormatter::formatString(
01209 const std::string& string,
01210 std::ostream& ostr) const
01211 {
01212 U32 size_nbo = htonl(string.size());
01213 ostr.write((const char*)(&size_nbo), sizeof(U32));
01214 ostr.write(string.c_str(), string.size());
01215 }
01216
01220 bool deserialize_string(std::istream& str, std::string& value)
01221 {
01222 char c = str.get();
01223 if (str.fail())
01224 {
01225
01226 return false;
01227 }
01228
01229 bool rv = false;
01230 switch(c)
01231 {
01232 case '\'':
01233 case '"':
01234 rv = deserialize_string_delim(str, value, c);
01235 break;
01236 case 's':
01237 rv = deserialize_string_raw(str, value);
01238 break;
01239 default:
01240 break;
01241 }
01242 return rv;
01243 }
01244
01245 bool deserialize_string_delim(
01246 std::istream& str,
01247 std::string& value,
01248 char delim)
01249 {
01250 std::ostringstream write_buffer;
01251 bool found_escape = false;
01252 bool found_hex = false;
01253 bool found_digit = false;
01254 U8 byte = 0;
01255
01256 while (true)
01257 {
01258 char next_char = str.get();
01259
01260 if(str.fail())
01261 {
01262
01263 value = write_buffer.str();
01264 return false;
01265 }
01266
01267 if(found_escape)
01268 {
01269
01270 if(found_hex)
01271 {
01272 if(found_digit)
01273 {
01274 found_digit = false;
01275 found_hex = false;
01276 found_escape = false;
01277 byte = byte << 4;
01278 byte |= hex_as_nybble(next_char);
01279 write_buffer << byte;
01280 byte = 0;
01281 }
01282 else
01283 {
01284
01285
01286 found_digit = true;
01287 byte = hex_as_nybble(next_char);
01288 }
01289 }
01290 else if(next_char == 'x')
01291 {
01292 found_hex = true;
01293 }
01294 else
01295 {
01296 switch(next_char)
01297 {
01298 case 'a':
01299 write_buffer << '\a';
01300 break;
01301 case 'b':
01302 write_buffer << '\b';
01303 break;
01304 case 'f':
01305 write_buffer << '\f';
01306 break;
01307 case 'n':
01308 write_buffer << '\n';
01309 break;
01310 case 'r':
01311 write_buffer << '\r';
01312 break;
01313 case 't':
01314 write_buffer << '\t';
01315 break;
01316 case 'v':
01317 write_buffer << '\v';
01318 break;
01319 default:
01320 write_buffer << next_char;
01321 break;
01322 }
01323 found_escape = false;
01324 }
01325 }
01326 else if(next_char == '\\')
01327 {
01328 found_escape = true;
01329 }
01330 else if(next_char == delim)
01331 {
01332 break;
01333 }
01334 else
01335 {
01336 write_buffer << next_char;
01337 }
01338 }
01339
01340 value = write_buffer.str();
01341 return true;
01342 }
01343
01344 bool deserialize_string_raw(std::istream& str, std::string& value)
01345 {
01346 bool ok = false;
01347 const S32 BUF_LEN = 20;
01348 char buf[BUF_LEN];
01349 str.get(buf, BUF_LEN - 1, ')');
01350 char c = str.get();
01351 c = str.get();
01352 if(((c == '"') || (c == '\'')) && (buf[0] == '('))
01353 {
01354
01355
01356
01357
01358 S32 len = strtol(buf + 1, NULL, 0);
01359 std::vector<char> buf;
01360 buf.resize(len);
01361 str.read(&buf[0], len);
01362 value.assign(buf.begin(), buf.end());
01363 c = str.get();
01364 if((c == '"') || (c == '\''))
01365 {
01366 ok = true;
01367 }
01368 }
01369 return ok;
01370 }
01371
01372 static const char* NOTATION_STRING_CHARACTERS[256] =
01373 {
01374 "\\x00",
01375 "\\x01",
01376 "\\x02",
01377 "\\x03",
01378 "\\x04",
01379 "\\x05",
01380 "\\x06",
01381 "\\a",
01382 "\\b",
01383 "\\t",
01384 "\\n",
01385 "\\v",
01386 "\\f",
01387 "\\r",
01388 "\\x0e",
01389 "\\x0f",
01390 "\\x10",
01391 "\\x11",
01392 "\\x12",
01393 "\\x13",
01394 "\\x14",
01395 "\\x15",
01396 "\\x16",
01397 "\\x17",
01398 "\\x18",
01399 "\\x19",
01400 "\\x1a",
01401 "\\x1b",
01402 "\\x1c",
01403 "\\x1d",
01404 "\\x1e",
01405 "\\x1f",
01406 " ",
01407 "!",
01408 "\"",
01409 "#",
01410 "$",
01411 "%",
01412 "&",
01413 "\\'",
01414 "(",
01415 ")",
01416 "*",
01417 "+",
01418 ",",
01419 "-",
01420 ".",
01421 "/",
01422 "0",
01423 "1",
01424 "2",
01425 "3",
01426 "4",
01427 "5",
01428 "6",
01429 "7",
01430 "8",
01431 "9",
01432 ":",
01433 ";",
01434 "<",
01435 "=",
01436 ">",
01437 "?",
01438 "@",
01439 "A",
01440 "B",
01441 "C",
01442 "D",
01443 "E",
01444 "F",
01445 "G",
01446 "H",
01447 "I",
01448 "J",
01449 "K",
01450 "L",
01451 "M",
01452 "N",
01453 "O",
01454 "P",
01455 "Q",
01456 "R",
01457 "S",
01458 "T",
01459 "U",
01460 "V",
01461 "W",
01462 "X",
01463 "Y",
01464 "Z",
01465 "[",
01466 "\\\\",
01467 "]",
01468 "^",
01469 "_",
01470 "`",
01471 "a",
01472 "b",
01473 "c",
01474 "d",
01475 "e",
01476 "f",
01477 "g",
01478 "h",
01479 "i",
01480 "j",
01481 "k",
01482 "l",
01483 "m",
01484 "n",
01485 "o",
01486 "p",
01487 "q",
01488 "r",
01489 "s",
01490 "t",
01491 "u",
01492 "v",
01493 "w",
01494 "x",
01495 "y",
01496 "z",
01497 "{",
01498 "|",
01499 "}",
01500 "~",
01501 "\\x7f",
01502 "\\x80",
01503 "\\x81",
01504 "\\x82",
01505 "\\x83",
01506 "\\x84",
01507 "\\x85",
01508 "\\x86",
01509 "\\x87",
01510 "\\x88",
01511 "\\x89",
01512 "\\x8a",
01513 "\\x8b",
01514 "\\x8c",
01515 "\\x8d",
01516 "\\x8e",
01517 "\\x8f",
01518 "\\x90",
01519 "\\x91",
01520 "\\x92",
01521 "\\x93",
01522 "\\x94",
01523 "\\x95",
01524 "\\x96",
01525 "\\x97",
01526 "\\x98",
01527 "\\x99",
01528 "\\x9a",
01529 "\\x9b",
01530 "\\x9c",
01531 "\\x9d",
01532 "\\x9e",
01533 "\\x9f",
01534 "\\xa0",
01535 "\\xa1",
01536 "\\xa2",
01537 "\\xa3",
01538 "\\xa4",
01539 "\\xa5",
01540 "\\xa6",
01541 "\\xa7",
01542 "\\xa8",
01543 "\\xa9",
01544 "\\xaa",
01545 "\\xab",
01546 "\\xac",
01547 "\\xad",
01548 "\\xae",
01549 "\\xaf",
01550 "\\xb0",
01551 "\\xb1",
01552 "\\xb2",
01553 "\\xb3",
01554 "\\xb4",
01555 "\\xb5",
01556 "\\xb6",
01557 "\\xb7",
01558 "\\xb8",
01559 "\\xb9",
01560 "\\xba",
01561 "\\xbb",
01562 "\\xbc",
01563 "\\xbd",
01564 "\\xbe",
01565 "\\xbf",
01566 "\\xc0",
01567 "\\xc1",
01568 "\\xc2",
01569 "\\xc3",
01570 "\\xc4",
01571 "\\xc5",
01572 "\\xc6",
01573 "\\xc7",
01574 "\\xc8",
01575 "\\xc9",
01576 "\\xca",
01577 "\\xcb",
01578 "\\xcc",
01579 "\\xcd",
01580 "\\xce",
01581 "\\xcf",
01582 "\\xd0",
01583 "\\xd1",
01584 "\\xd2",
01585 "\\xd3",
01586 "\\xd4",
01587 "\\xd5",
01588 "\\xd6",
01589 "\\xd7",
01590 "\\xd8",
01591 "\\xd9",
01592 "\\xda",
01593 "\\xdb",
01594 "\\xdc",
01595 "\\xdd",
01596 "\\xde",
01597 "\\xdf",
01598 "\\xe0",
01599 "\\xe1",
01600 "\\xe2",
01601 "\\xe3",
01602 "\\xe4",
01603 "\\xe5",
01604 "\\xe6",
01605 "\\xe7",
01606 "\\xe8",
01607 "\\xe9",
01608 "\\xea",
01609 "\\xeb",
01610 "\\xec",
01611 "\\xed",
01612 "\\xee",
01613 "\\xef",
01614 "\\xf0",
01615 "\\xf1",
01616 "\\xf2",
01617 "\\xf3",
01618 "\\xf4",
01619 "\\xf5",
01620 "\\xf6",
01621 "\\xf7",
01622 "\\xf8",
01623 "\\xf9",
01624 "\\xfa",
01625 "\\xfb",
01626 "\\xfc",
01627 "\\xfd",
01628 "\\xfe",
01629 "\\xff"
01630 };
01631
01632 void serialize_string(const std::string& value, std::ostream& str)
01633 {
01634 std::string::const_iterator it = value.begin();
01635 std::string::const_iterator end = value.end();
01636 U8 c;
01637 for(; it != end; ++it)
01638 {
01639 c = (U8)(*it);
01640 str << NOTATION_STRING_CHARACTERS[c];
01641 }
01642 }
01643
01644