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 "llstring.h"
00049 #include "lluri.h"
00050
00051
00052 static const int MAX_HDR_LEN = 20;
00053 static const char LEGACY_NON_HEADER[] = "<llsd>";
00054 const std::string LLSD_BINARY_HEADER("LLSD/Binary");
00055 const std::string LLSD_XML_HEADER("LLSD/XML");
00056
00061
00062 void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize type, U32 options)
00063 {
00064 LLPointer<LLSDFormatter> f = NULL;
00065
00066 switch (type)
00067 {
00068 case LLSD_BINARY:
00069 str << "<? " << LLSD_BINARY_HEADER << " ?>\n";
00070 f = new LLSDBinaryFormatter;
00071 break;
00072
00073 case LLSD_XML:
00074 str << "<? " << LLSD_XML_HEADER << " ?>\n";
00075 f = new LLSDXMLFormatter;
00076 break;
00077
00078 default:
00079 llwarns << "serialize request for unkown ELLSD_Serialize" << llendl;
00080 }
00081
00082 if (f.notNull())
00083 {
00084 f->format(sd, str, options);
00085 }
00086 }
00087
00088
00089 bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
00090 {
00091 LLPointer<LLSDParser> p = NULL;
00092 char hdr_buf[MAX_HDR_LEN + 1] = "";
00093 int i;
00094 int inbuf = 0;
00095 bool legacy_no_header = false;
00096 bool fail_if_not_legacy = false;
00097 std::string header;
00098
00099
00100
00101
00102 str.get(hdr_buf, MAX_HDR_LEN, '\n');
00103 if (str.fail())
00104 {
00105 str.clear();
00106 fail_if_not_legacy = true;
00107 }
00108
00109 if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER)))
00110 {
00111 legacy_no_header = true;
00112 inbuf = str.gcount();
00113 }
00114 else
00115 {
00116 if (fail_if_not_legacy)
00117 goto fail;
00118
00119
00120
00121 for (i = 0; i < MAX_HDR_LEN; i++)
00122 {
00123 if (hdr_buf[i] == 0 || hdr_buf[i] == '\r' ||
00124 hdr_buf[i] == '\n')
00125 {
00126 hdr_buf[i] = 0;
00127 break;
00128 }
00129 }
00130 header = hdr_buf;
00131
00132 std::string::size_type start = std::string::npos;
00133 std::string::size_type end = std::string::npos;
00134 start = header.find_first_not_of("<? ");
00135 if (start != std::string::npos)
00136 {
00137 end = header.find_first_of(" ?", start);
00138 }
00139 if ((start == std::string::npos) || (end == std::string::npos))
00140 goto fail;
00141
00142 header = header.substr(start, end - start);
00143 ws(str);
00144 }
00145
00146
00147
00148 if (legacy_no_header)
00149 {
00150 LLSDXMLParser* x = new LLSDXMLParser;
00151 x->parsePart(hdr_buf, inbuf);
00152 p = x;
00153 }
00154 else if (header == LLSD_BINARY_HEADER)
00155 {
00156 p = new LLSDBinaryParser;
00157 }
00158 else if (header == LLSD_XML_HEADER)
00159 {
00160 p = new LLSDXMLParser;
00161 }
00162 else
00163 {
00164 llwarns << "deserialize request for unknown ELLSD_Serialize" << llendl;
00165 }
00166
00167 if (p.notNull())
00168 {
00169 p->parse(str, sd, max_bytes);
00170 return true;
00171 }
00172
00173 fail:
00174 llwarns << "deserialize LLSD parse failure" << llendl;
00175 return false;
00176 }
00177
00181 #if LL_BIG_ENDIAN
00182 U64 ll_htonll(U64 hostlonglong) { return hostlonglong; }
00183 U64 ll_ntohll(U64 netlonglong) { return netlonglong; }
00184 F64 ll_htond(F64 hostlonglong) { return hostlonglong; }
00185 F64 ll_ntohd(F64 netlonglong) { return netlonglong; }
00186 #else
00187
00188
00189
00190
00191 U64 ll_htonll(U64 hostlonglong)
00192 {
00193 return ((U64)(htonl((U32)((hostlonglong >> 32) & 0xFFFFFFFF))) |
00194 ((U64)(htonl((U32)(hostlonglong & 0xFFFFFFFF))) << 32));
00195 }
00196 U64 ll_ntohll(U64 netlonglong)
00197 {
00198 return ((U64)(ntohl((U32)((netlonglong >> 32) & 0xFFFFFFFF))) |
00199 ((U64)(ntohl((U32)(netlonglong & 0xFFFFFFFF))) << 32));
00200 }
00201 union LLEndianSwapper
00202 {
00203 F64 d;
00204 U64 i;
00205 };
00206 F64 ll_htond(F64 hostdouble)
00207 {
00208 LLEndianSwapper tmp;
00209 tmp.d = hostdouble;
00210 tmp.i = ll_htonll(tmp.i);
00211 return tmp.d;
00212 }
00213 F64 ll_ntohd(F64 netdouble)
00214 {
00215 LLEndianSwapper tmp;
00216 tmp.d = netdouble;
00217 tmp.i = ll_ntohll(tmp.i);
00218 return tmp.d;
00219 }
00220 #endif
00221
00235 int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes);
00236
00246 int deserialize_string_delim(std::istream& istr, std::string& value, char d);
00247
00260 int deserialize_string_raw(
00261 std::istream& istr,
00262 std::string& value,
00263 S32 max_bytes);
00264
00275 int deserialize_boolean(
00276 std::istream& istr,
00277 LLSD& data,
00278 const std::string& compare,
00279 bool value);
00280
00287 void serialize_string(const std::string& value, std::ostream& str);
00288
00289
00293 static const std::string NOTATION_TRUE_SERIAL("true");
00294 static const std::string NOTATION_FALSE_SERIAL("false");
00295
00296 static const char BINARY_TRUE_SERIAL = '1';
00297 static const char BINARY_FALSE_SERIAL = '0';
00298
00299
00303 LLSDParser::LLSDParser() : mCheckLimits(true), mMaxBytesLeft(0)
00304 {
00305 }
00306
00307
00308 LLSDParser::~LLSDParser()
00309 { }
00310
00311 S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes)
00312 {
00313 mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true;
00314 mMaxBytesLeft = max_bytes;
00315 return doParse(istr, data);
00316 }
00317
00318
00319 int LLSDParser::get(std::istream& istr) const
00320 {
00321 if(mCheckLimits) --mMaxBytesLeft;
00322 return istr.get();
00323 }
00324
00325 std::istream& LLSDParser::get(
00326 std::istream& istr,
00327 char* s,
00328 std::streamsize n,
00329 char delim) const
00330 {
00331 istr.get(s, n, delim);
00332 if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
00333 return istr;
00334 }
00335
00336 std::istream& LLSDParser::get(
00337 std::istream& istr,
00338 std::streambuf& sb,
00339 char delim) const
00340 {
00341 istr.get(sb, delim);
00342 if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
00343 return istr;
00344 }
00345
00346 std::istream& LLSDParser::ignore(std::istream& istr) const
00347 {
00348 istr.ignore();
00349 if(mCheckLimits) --mMaxBytesLeft;
00350 return istr;
00351 }
00352
00353 std::istream& LLSDParser::putback(std::istream& istr, char c) const
00354 {
00355 istr.putback(c);
00356 if(mCheckLimits) ++mMaxBytesLeft;
00357 return istr;
00358 }
00359
00360 std::istream& LLSDParser::read(
00361 std::istream& istr,
00362 char* s,
00363 std::streamsize n) const
00364 {
00365 istr.read(s, n);
00366 if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
00367 return istr;
00368 }
00369
00370 void LLSDParser::account(S32 bytes) const
00371 {
00372 if(mCheckLimits) mMaxBytesLeft -= bytes;
00373 }
00374
00375
00379 LLSDNotationParser::LLSDNotationParser()
00380 {
00381 }
00382
00383
00384 LLSDNotationParser::~LLSDNotationParser()
00385 { }
00386
00387
00388 S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
00389 {
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 char c;
00402 c = istr.peek();
00403 while(isspace(c))
00404 {
00405
00406 c = get(istr);
00407 c = istr.peek();
00408 continue;
00409 }
00410 if(!istr.good())
00411 {
00412 return 0;
00413 }
00414 S32 parse_count = 1;
00415 switch(c)
00416 {
00417 case '{':
00418 {
00419 S32 child_count = parseMap(istr, data);
00420 if((child_count == PARSE_FAILURE) || data.isUndefined())
00421 {
00422 parse_count = PARSE_FAILURE;
00423 }
00424 else
00425 {
00426 parse_count += child_count;
00427 }
00428 if(istr.fail())
00429 {
00430 llinfos << "STREAM FAILURE reading map." << llendl;
00431 parse_count = PARSE_FAILURE;
00432 }
00433 break;
00434 }
00435
00436 case '[':
00437 {
00438 S32 child_count = parseArray(istr, data);
00439 if((child_count == PARSE_FAILURE) || data.isUndefined())
00440 {
00441 parse_count = PARSE_FAILURE;
00442 }
00443 else
00444 {
00445 parse_count += child_count;
00446 }
00447 if(istr.fail())
00448 {
00449 llinfos << "STREAM FAILURE reading array." << llendl;
00450 parse_count = PARSE_FAILURE;
00451 }
00452 break;
00453 }
00454
00455 case '!':
00456 c = get(istr);
00457 data.clear();
00458 break;
00459
00460 case '0':
00461 c = get(istr);
00462 data = false;
00463 break;
00464
00465 case 'F':
00466 case 'f':
00467 ignore(istr);
00468 c = istr.peek();
00469 if(isalpha(c))
00470 {
00471 int cnt = deserialize_boolean(
00472 istr,
00473 data,
00474 NOTATION_FALSE_SERIAL,
00475 false);
00476 if(PARSE_FAILURE == cnt) parse_count = cnt;
00477 else account(cnt);
00478 }
00479 else
00480 {
00481 data = false;
00482 }
00483 if(istr.fail())
00484 {
00485 llinfos << "STREAM FAILURE reading boolean." << llendl;
00486 parse_count = PARSE_FAILURE;
00487 }
00488 break;
00489
00490 case '1':
00491 c = get(istr);
00492 data = true;
00493 break;
00494
00495 case 'T':
00496 case 't':
00497 ignore(istr);
00498 c = istr.peek();
00499 if(isalpha(c))
00500 {
00501 int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true);
00502 if(PARSE_FAILURE == cnt) parse_count = cnt;
00503 else account(cnt);
00504 }
00505 else
00506 {
00507 data = true;
00508 }
00509 if(istr.fail())
00510 {
00511 llinfos << "STREAM FAILURE reading boolean." << llendl;
00512 parse_count = PARSE_FAILURE;
00513 }
00514 break;
00515
00516 case 'i':
00517 {
00518 c = get(istr);
00519 S32 integer = 0;
00520 istr >> integer;
00521 data = integer;
00522 if(istr.fail())
00523 {
00524 llinfos << "STREAM FAILURE reading integer." << llendl;
00525 parse_count = PARSE_FAILURE;
00526 }
00527 break;
00528 }
00529
00530 case 'r':
00531 {
00532 c = get(istr);
00533 F64 real = 0.0;
00534 istr >> real;
00535 data = real;
00536 if(istr.fail())
00537 {
00538 llinfos << "STREAM FAILURE reading real." << llendl;
00539 parse_count = PARSE_FAILURE;
00540 }
00541 break;
00542 }
00543
00544 case 'u':
00545 {
00546 c = get(istr);
00547 LLUUID id;
00548 istr >> id;
00549 data = id;
00550 if(istr.fail())
00551 {
00552 llinfos << "STREAM FAILURE reading uuid." << llendl;
00553 parse_count = PARSE_FAILURE;
00554 }
00555 break;
00556 }
00557
00558 case '\"':
00559 case '\'':
00560 case 's':
00561 if(!parseString(istr, data))
00562 {
00563 parse_count = PARSE_FAILURE;
00564 }
00565 if(istr.fail())
00566 {
00567 llinfos << "STREAM FAILURE reading string." << llendl;
00568 parse_count = PARSE_FAILURE;
00569 }
00570 break;
00571
00572 case 'l':
00573 {
00574 c = get(istr);
00575 c = get(istr);
00576 std::string str;
00577 int cnt = deserialize_string_delim(istr, str, c);
00578 if(PARSE_FAILURE == cnt)
00579 {
00580 parse_count = PARSE_FAILURE;
00581 }
00582 else
00583 {
00584 data = LLURI(str);
00585 account(cnt);
00586 }
00587 if(istr.fail())
00588 {
00589 llinfos << "STREAM FAILURE reading link." << llendl;
00590 parse_count = PARSE_FAILURE;
00591 }
00592 break;
00593 }
00594
00595 case 'd':
00596 {
00597 c = get(istr);
00598 c = get(istr);
00599 std::string str;
00600 int cnt = deserialize_string_delim(istr, str, c);
00601 if(PARSE_FAILURE == cnt)
00602 {
00603 parse_count = PARSE_FAILURE;
00604 }
00605 else
00606 {
00607 data = LLDate(str);
00608 account(cnt);
00609 }
00610 if(istr.fail())
00611 {
00612 llinfos << "STREAM FAILURE reading date." << llendl;
00613 parse_count = PARSE_FAILURE;
00614 }
00615 break;
00616 }
00617
00618 case 'b':
00619 if(!parseBinary(istr, data))
00620 {
00621 parse_count = PARSE_FAILURE;
00622 }
00623 if(istr.fail())
00624 {
00625 llinfos << "STREAM FAILURE reading data." << llendl;
00626 parse_count = PARSE_FAILURE;
00627 }
00628 break;
00629
00630 default:
00631 parse_count = PARSE_FAILURE;
00632 llinfos << "Unrecognized character while parsing: int(" << (int)c
00633 << ")" << llendl;
00634 break;
00635 }
00636 if(PARSE_FAILURE == parse_count)
00637 {
00638 data.clear();
00639 }
00640 return parse_count;
00641 }
00642
00643 S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
00644 {
00645
00646 map = LLSD::emptyMap();
00647 S32 parse_count = 0;
00648 char c = get(istr);
00649 if(c == '{')
00650 {
00651
00652 bool found_name = false;
00653 std::string name;
00654 c = get(istr);
00655 while(c != '}' && istr.good())
00656 {
00657 if(!found_name)
00658 {
00659 if((c == '\"') || (c == '\'') || (c == 's'))
00660 {
00661 putback(istr, c);
00662 found_name = true;
00663 int count = deserialize_string(istr, name, mMaxBytesLeft);
00664 if(PARSE_FAILURE == count) return PARSE_FAILURE;
00665 account(count);
00666 }
00667 c = get(istr);
00668 }
00669 else
00670 {
00671 if(isspace(c) || (c == ':'))
00672 {
00673 c = get(istr);
00674 continue;
00675 }
00676 putback(istr, c);
00677 LLSD child;
00678 S32 count = doParse(istr, child);
00679 if(count > 0)
00680 {
00681
00682
00683 parse_count += count;
00684 map.insert(name, child);
00685 }
00686 else
00687 {
00688 return PARSE_FAILURE;
00689 }
00690 found_name = false;
00691 c = get(istr);
00692 }
00693 }
00694 if(c != '}')
00695 {
00696 map.clear();
00697 return PARSE_FAILURE;
00698 }
00699 }
00700 return parse_count;
00701 }
00702
00703 S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const
00704 {
00705
00706 array = LLSD::emptyArray();
00707 S32 parse_count = 0;
00708 char c = get(istr);
00709 if(c == '[')
00710 {
00711
00712 c = get(istr);
00713 while((c != ']') && istr.good())
00714 {
00715 LLSD child;
00716 if(isspace(c) || (c == ','))
00717 {
00718 c = get(istr);
00719 continue;
00720 }
00721 putback(istr, c);
00722 S32 count = doParse(istr, child);
00723 if(PARSE_FAILURE == count)
00724 {
00725 return PARSE_FAILURE;
00726 }
00727 else
00728 {
00729 parse_count += count;
00730 array.append(child);
00731 }
00732 c = get(istr);
00733 }
00734 if(c != ']')
00735 {
00736 return PARSE_FAILURE;
00737 }
00738 }
00739 return parse_count;
00740 }
00741
00742 bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
00743 {
00744 std::string value;
00745 int count = deserialize_string(istr, value, mMaxBytesLeft);
00746 if(PARSE_FAILURE == count) return false;
00747 account(count);
00748 data = value;
00749 return true;
00750 }
00751
00752 bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
00753 {
00754
00755
00756
00757
00758
00759
00760 const U32 BINARY_BUFFER_SIZE = 256;
00761 const U32 STREAM_GET_COUNT = 255;
00762
00763
00764 char buf[BINARY_BUFFER_SIZE];
00765 get(istr, buf, STREAM_GET_COUNT, '"');
00766 char c = get(istr);
00767 if(c != '"') return false;
00768 if(0 == strncmp("b(", buf, 2))
00769 {
00770
00771
00772 S32 len = strtol(buf + 2, NULL, 0);
00773 if(mCheckLimits && (len > mMaxBytesLeft)) return false;
00774 std::vector<U8> value;
00775 if(len)
00776 {
00777 value.resize(len);
00778 account(fullread(istr, (char *)&value[0], len));
00779 }
00780 c = get(istr);
00781 data = value;
00782 }
00783 else if(0 == strncmp("b64", buf, 3))
00784 {
00785
00786
00787
00788 std::stringstream coded_stream;
00789 get(istr, *(coded_stream.rdbuf()), '\"');
00790 c = get(istr);
00791 std::string encoded(coded_stream.str());
00792 S32 len = apr_base64_decode_len(encoded.c_str());
00793 std::vector<U8> value;
00794 if(len)
00795 {
00796 value.resize(len);
00797 len = apr_base64_decode_binary(&value[0], encoded.c_str());
00798 value.resize(len);
00799 }
00800 data = value;
00801 }
00802 else if(0 == strncmp("b16", buf, 3))
00803 {
00804
00805
00806
00807
00808 char* read;
00809 U8 byte;
00810 U8 byte_buffer[BINARY_BUFFER_SIZE];
00811 U8* write;
00812 std::vector<U8> value;
00813 c = get(istr);
00814 while(c != '"')
00815 {
00816 putback(istr, c);
00817 read = buf;
00818 write = byte_buffer;
00819 get(istr, buf, STREAM_GET_COUNT, '"');
00820 c = get(istr);
00821 while(*read != '\0')
00822 {
00823 byte = hex_as_nybble(*read++);
00824 byte = byte << 4;
00825 byte |= hex_as_nybble(*read++);
00826 *write++ = byte;
00827 }
00828
00829 value.insert(value.end(), byte_buffer, write);
00830 }
00831 data = value;
00832 }
00833 else
00834 {
00835 return false;
00836 }
00837 return true;
00838 }
00839
00840
00844 LLSDBinaryParser::LLSDBinaryParser()
00845 {
00846 }
00847
00848
00849 LLSDBinaryParser::~LLSDBinaryParser()
00850 {
00851 }
00852
00853
00854 S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
00855 {
00872 char c;
00873 c = get(istr);
00874 if(!istr.good())
00875 {
00876 return 0;
00877 }
00878 S32 parse_count = 1;
00879 switch(c)
00880 {
00881 case '{':
00882 {
00883 S32 child_count = parseMap(istr, data);
00884 if((child_count == PARSE_FAILURE) || data.isUndefined())
00885 {
00886 parse_count = PARSE_FAILURE;
00887 }
00888 else
00889 {
00890 parse_count += child_count;
00891 }
00892 if(istr.fail())
00893 {
00894 llinfos << "STREAM FAILURE reading binary map." << llendl;
00895 parse_count = PARSE_FAILURE;
00896 }
00897 break;
00898 }
00899
00900 case '[':
00901 {
00902 S32 child_count = parseArray(istr, data);
00903 if((child_count == PARSE_FAILURE) || data.isUndefined())
00904 {
00905 parse_count = PARSE_FAILURE;
00906 }
00907 else
00908 {
00909 parse_count += child_count;
00910 }
00911 if(istr.fail())
00912 {
00913 llinfos << "STREAM FAILURE reading binary array." << llendl;
00914 parse_count = PARSE_FAILURE;
00915 }
00916 break;
00917 }
00918
00919 case '!':
00920 data.clear();
00921 break;
00922
00923 case '0':
00924 data = false;
00925 break;
00926
00927 case '1':
00928 data = true;
00929 break;
00930
00931 case 'i':
00932 {
00933 U32 value_nbo = 0;
00934 read(istr, (char*)&value_nbo, sizeof(U32));
00935 data = (S32)ntohl(value_nbo);
00936 if(istr.fail())
00937 {
00938 llinfos << "STREAM FAILURE reading binary integer." << llendl;
00939 }
00940 break;
00941 }
00942
00943 case 'r':
00944 {
00945 F64 real_nbo = 0.0;
00946 read(istr, (char*)&real_nbo, sizeof(F64));
00947 data = ll_ntohd(real_nbo);
00948 if(istr.fail())
00949 {
00950 llinfos << "STREAM FAILURE reading binary real." << llendl;
00951 }
00952 break;
00953 }
00954
00955 case 'u':
00956 {
00957 LLUUID id;
00958 read(istr, (char*)(&id.mData), UUID_BYTES);
00959 data = id;
00960 if(istr.fail())
00961 {
00962 llinfos << "STREAM FAILURE reading binary uuid." << llendl;
00963 }
00964 break;
00965 }
00966
00967 case '\'':
00968 case '"':
00969 {
00970 std::string value;
00971 int cnt = deserialize_string_delim(istr, value, c);
00972 if(PARSE_FAILURE == cnt)
00973 {
00974 parse_count = PARSE_FAILURE;
00975 }
00976 else
00977 {
00978 data = value;
00979 account(cnt);
00980 }
00981 if(istr.fail())
00982 {
00983 llinfos << "STREAM FAILURE reading binary (notation-style) string."
00984 << llendl;
00985 parse_count = PARSE_FAILURE;
00986 }
00987 break;
00988 }
00989
00990 case 's':
00991 {
00992 std::string value;
00993 if(parseString(istr, value))
00994 {
00995 data = value;
00996 }
00997 else
00998 {
00999 parse_count = PARSE_FAILURE;
01000 }
01001 if(istr.fail())
01002 {
01003 llinfos << "STREAM FAILURE reading binary string." << llendl;
01004 parse_count = PARSE_FAILURE;
01005 }
01006 break;
01007 }
01008
01009 case 'l':
01010 {
01011 std::string value;
01012 if(parseString(istr, value))
01013 {
01014 data = LLURI(value);
01015 }
01016 else
01017 {
01018 parse_count = PARSE_FAILURE;
01019 }
01020 if(istr.fail())
01021 {
01022 llinfos << "STREAM FAILURE reading binary link." << llendl;
01023 parse_count = PARSE_FAILURE;
01024 }
01025 break;
01026 }
01027
01028 case 'd':
01029 {
01030 F64 real = 0.0;
01031 read(istr, (char*)&real, sizeof(F64));
01032 data = LLDate(real);
01033 if(istr.fail())
01034 {
01035 llinfos << "STREAM FAILURE reading binary date." << llendl;
01036 parse_count = PARSE_FAILURE;
01037 }
01038 break;
01039 }
01040
01041 case 'b':
01042 {
01043
01044
01045 U32 size_nbo = 0;
01046 read(istr, (char*)&size_nbo, sizeof(U32));
01047 S32 size = (S32)ntohl(size_nbo);
01048 if(mCheckLimits && (size > mMaxBytesLeft))
01049 {
01050 parse_count = PARSE_FAILURE;
01051 }
01052 else
01053 {
01054 std::vector<U8> value;
01055 if(size > 0)
01056 {
01057 value.resize(size);
01058 account(fullread(istr, (char*)&value[0], size));
01059 }
01060 data = value;
01061 }
01062 if(istr.fail())
01063 {
01064 llinfos << "STREAM FAILURE reading binary." << llendl;
01065 parse_count = PARSE_FAILURE;
01066 }
01067 break;
01068 }
01069
01070 default:
01071 parse_count = PARSE_FAILURE;
01072 llinfos << "Unrecognized character while parsing: int(" << (int)c
01073 << ")" << llendl;
01074 break;
01075 }
01076 if(PARSE_FAILURE == parse_count)
01077 {
01078 data.clear();
01079 }
01080 return parse_count;
01081 }
01082
01083 S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
01084 {
01085 map = LLSD::emptyMap();
01086 U32 value_nbo = 0;
01087 read(istr, (char*)&value_nbo, sizeof(U32));
01088 S32 size = (S32)ntohl(value_nbo);
01089 S32 parse_count = 0;
01090 S32 count = 0;
01091 char c = get(istr);
01092 while(c != '}' && (count < size) && istr.good())
01093 {
01094 std::string name;
01095 switch(c)
01096 {
01097 case 'k':
01098 if(!parseString(istr, name))
01099 {
01100 return PARSE_FAILURE;
01101 }
01102 break;
01103 case '\'':
01104 case '"':
01105 {
01106 int cnt = deserialize_string_delim(istr, name, c);
01107 if(PARSE_FAILURE == cnt) return PARSE_FAILURE;
01108 account(cnt);
01109 break;
01110 }
01111 }
01112 LLSD child;
01113 S32 child_count = doParse(istr, child);
01114 if(child_count > 0)
01115 {
01116
01117
01118 parse_count += child_count;
01119 map.insert(name, child);
01120 }
01121 else
01122 {
01123 return PARSE_FAILURE;
01124 }
01125 ++count;
01126 c = get(istr);
01127 }
01128 if((c != '}') || (count < size))
01129 {
01130
01131
01132 return PARSE_FAILURE;
01133 }
01134 return parse_count;
01135 }
01136
01137 S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
01138 {
01139 array = LLSD::emptyArray();
01140 U32 value_nbo = 0;
01141 read(istr, (char*)&value_nbo, sizeof(U32));
01142 S32 size = (S32)ntohl(value_nbo);
01143
01144
01145
01146
01147 S32 parse_count = 0;
01148 S32 count = 0;
01149 char c = istr.peek();
01150 while((c != ']') && (count < size) && istr.good())
01151 {
01152 LLSD child;
01153 S32 child_count = doParse(istr, child);
01154 if(PARSE_FAILURE == child_count)
01155 {
01156 return PARSE_FAILURE;
01157 }
01158 if(child_count)
01159 {
01160 parse_count += child_count;
01161 array.append(child);
01162 }
01163 ++count;
01164 c = istr.peek();
01165 }
01166 c = get(istr);
01167 if((c != ']') || (count < size))
01168 {
01169
01170
01171 return PARSE_FAILURE;
01172 }
01173 return parse_count;
01174 }
01175
01176 bool LLSDBinaryParser::parseString(
01177 std::istream& istr,
01178 std::string& value) const
01179 {
01180
01181 U32 value_nbo = 0;
01182 read(istr, (char*)&value_nbo, sizeof(U32));
01183 S32 size = (S32)ntohl(value_nbo);
01184 if(mCheckLimits && (size > mMaxBytesLeft)) return false;
01185 std::vector<char> buf;
01186 if(size)
01187 {
01188 buf.resize(size);
01189 account(fullread(istr, &buf[0], size));
01190 value.assign(buf.begin(), buf.end());
01191 }
01192 return true;
01193 }
01194
01195
01199 LLSDFormatter::LLSDFormatter() :
01200 mBoolAlpha(false)
01201 {
01202 }
01203
01204
01205 LLSDFormatter::~LLSDFormatter()
01206 { }
01207
01208 void LLSDFormatter::boolalpha(bool alpha)
01209 {
01210 mBoolAlpha = alpha;
01211 }
01212
01213 void LLSDFormatter::realFormat(const std::string& format)
01214 {
01215 mRealFormat = format;
01216 }
01217
01218 void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const
01219 {
01220 char buffer[MAX_STRING];
01221 snprintf(buffer, MAX_STRING, mRealFormat.c_str(), real);
01222 ostr << buffer;
01223 }
01224
01228 LLSDNotationFormatter::LLSDNotationFormatter()
01229 {
01230 }
01231
01232
01233 LLSDNotationFormatter::~LLSDNotationFormatter()
01234 { }
01235
01236
01237 std::string LLSDNotationFormatter::escapeString(const std::string& in)
01238 {
01239 std::ostringstream ostr;
01240 serialize_string(in, ostr);
01241 return ostr.str();
01242 }
01243
01244
01245 S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
01246 {
01247 S32 format_count = 1;
01248 switch(data.type())
01249 {
01250 case LLSD::TypeMap:
01251 {
01252 ostr << "{";
01253 bool need_comma = false;
01254 LLSD::map_const_iterator iter = data.beginMap();
01255 LLSD::map_const_iterator end = data.endMap();
01256 for(; iter != end; ++iter)
01257 {
01258 if(need_comma) ostr << ",";
01259 need_comma = true;
01260 ostr << '\'';
01261 serialize_string((*iter).first, ostr);
01262 ostr << "':";
01263 format_count += format((*iter).second, ostr);
01264 }
01265 ostr << "}";
01266 break;
01267 }
01268
01269 case LLSD::TypeArray:
01270 {
01271 ostr << "[";
01272 bool need_comma = false;
01273 LLSD::array_const_iterator iter = data.beginArray();
01274 LLSD::array_const_iterator end = data.endArray();
01275 for(; iter != end; ++iter)
01276 {
01277 if(need_comma) ostr << ",";
01278 need_comma = true;
01279 format_count += format(*iter, ostr);
01280 }
01281 ostr << "]";
01282 break;
01283 }
01284
01285 case LLSD::TypeUndefined:
01286 ostr << "!";
01287 break;
01288
01289 case LLSD::TypeBoolean:
01290 if(mBoolAlpha ||
01291 #if( LL_WINDOWS || __GNUC__ > 2)
01292 (ostr.flags() & std::ios::boolalpha)
01293 #else
01294 (ostr.flags() & 0x0100)
01295 #endif
01296 )
01297 {
01298 ostr << (data.asBoolean()
01299 ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL);
01300 }
01301 else
01302 {
01303 ostr << (data.asBoolean() ? 1 : 0);
01304 }
01305 break;
01306
01307 case LLSD::TypeInteger:
01308 ostr << "i" << data.asInteger();
01309 break;
01310
01311 case LLSD::TypeReal:
01312 ostr << "r";
01313 if(mRealFormat.empty())
01314 {
01315 ostr << data.asReal();
01316 }
01317 else
01318 {
01319 formatReal(data.asReal(), ostr);
01320 }
01321 break;
01322
01323 case LLSD::TypeUUID:
01324 ostr << "u" << data.asUUID();
01325 break;
01326
01327 case LLSD::TypeString:
01328 ostr << '\'';
01329 serialize_string(data.asString(), ostr);
01330 ostr << '\'';
01331 break;
01332
01333 case LLSD::TypeDate:
01334 ostr << "d\"" << data.asDate() << "\"";
01335 break;
01336
01337 case LLSD::TypeURI:
01338 ostr << "l\"";
01339 serialize_string(data.asString(), ostr);
01340 ostr << "\"";
01341 break;
01342
01343 case LLSD::TypeBinary:
01344 {
01345
01346 std::vector<U8> buffer = data.asBinary();
01347 ostr << "b(" << buffer.size() << ")\"";
01348 if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
01349 ostr << "\"";
01350 break;
01351 }
01352
01353 default:
01354
01355 ostr << "!";
01356 break;
01357 }
01358 return format_count;
01359 }
01360
01361
01365 LLSDBinaryFormatter::LLSDBinaryFormatter()
01366 {
01367 }
01368
01369
01370 LLSDBinaryFormatter::~LLSDBinaryFormatter()
01371 { }
01372
01373
01374 S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
01375 {
01376 S32 format_count = 1;
01377 switch(data.type())
01378 {
01379 case LLSD::TypeMap:
01380 {
01381 ostr.put('{');
01382 U32 size_nbo = htonl(data.size());
01383 ostr.write((const char*)(&size_nbo), sizeof(U32));
01384 LLSD::map_const_iterator iter = data.beginMap();
01385 LLSD::map_const_iterator end = data.endMap();
01386 for(; iter != end; ++iter)
01387 {
01388 ostr.put('k');
01389 formatString((*iter).first, ostr);
01390 format_count += format((*iter).second, ostr);
01391 }
01392 ostr.put('}');
01393 break;
01394 }
01395
01396 case LLSD::TypeArray:
01397 {
01398 ostr.put('[');
01399 U32 size_nbo = htonl(data.size());
01400 ostr.write((const char*)(&size_nbo), sizeof(U32));
01401 LLSD::array_const_iterator iter = data.beginArray();
01402 LLSD::array_const_iterator end = data.endArray();
01403 for(; iter != end; ++iter)
01404 {
01405 format_count += format(*iter, ostr);
01406 }
01407 ostr.put(']');
01408 break;
01409 }
01410
01411 case LLSD::TypeUndefined:
01412 ostr.put('!');
01413 break;
01414
01415 case LLSD::TypeBoolean:
01416 if(data.asBoolean()) ostr.put(BINARY_TRUE_SERIAL);
01417 else ostr.put(BINARY_FALSE_SERIAL);
01418 break;
01419
01420 case LLSD::TypeInteger:
01421 {
01422 ostr.put('i');
01423 U32 value_nbo = htonl(data.asInteger());
01424 ostr.write((const char*)(&value_nbo), sizeof(U32));
01425 break;
01426 }
01427
01428 case LLSD::TypeReal:
01429 {
01430 ostr.put('r');
01431 F64 value_nbo = ll_htond(data.asReal());
01432 ostr.write((const char*)(&value_nbo), sizeof(F64));
01433 break;
01434 }
01435
01436 case LLSD::TypeUUID:
01437 ostr.put('u');
01438 ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES);
01439 break;
01440
01441 case LLSD::TypeString:
01442 ostr.put('s');
01443 formatString(data.asString(), ostr);
01444 break;
01445
01446 case LLSD::TypeDate:
01447 {
01448 ostr.put('d');
01449 F64 value = data.asReal();
01450 ostr.write((const char*)(&value), sizeof(F64));
01451 break;
01452 }
01453
01454 case LLSD::TypeURI:
01455 ostr.put('l');
01456 formatString(data.asString(), ostr);
01457 break;
01458
01459 case LLSD::TypeBinary:
01460 {
01461
01462 ostr.put('b');
01463 std::vector<U8> buffer = data.asBinary();
01464 U32 size_nbo = htonl(buffer.size());
01465 ostr.write((const char*)(&size_nbo), sizeof(U32));
01466 if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
01467 break;
01468 }
01469
01470 default:
01471
01472 ostr.put('!');
01473 break;
01474 }
01475 return format_count;
01476 }
01477
01478 void LLSDBinaryFormatter::formatString(
01479 const std::string& string,
01480 std::ostream& ostr) const
01481 {
01482 U32 size_nbo = htonl(string.size());
01483 ostr.write((const char*)(&size_nbo), sizeof(U32));
01484 ostr.write(string.c_str(), string.size());
01485 }
01486
01490 int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes)
01491 {
01492 char c = istr.get();
01493 if(istr.fail())
01494 {
01495
01496
01497 return LLSDParser::PARSE_FAILURE;
01498 }
01499
01500 int rv = LLSDParser::PARSE_FAILURE;
01501 switch(c)
01502 {
01503 case '\'':
01504 case '"':
01505 rv = deserialize_string_delim(istr, value, c);
01506 break;
01507 case 's':
01508
01509
01510
01511 rv = deserialize_string_raw(istr, value, max_bytes);
01512 break;
01513 default:
01514 break;
01515 }
01516 if(LLSDParser::PARSE_FAILURE == rv) return rv;
01517 return rv + 1;
01518 }
01519
01520 int deserialize_string_delim(
01521 std::istream& istr,
01522 std::string& value,
01523 char delim)
01524 {
01525 std::ostringstream write_buffer;
01526 bool found_escape = false;
01527 bool found_hex = false;
01528 bool found_digit = false;
01529 U8 byte = 0;
01530 int count = 0;
01531
01532 while (true)
01533 {
01534 char next_char = istr.get();
01535 ++count;
01536
01537 if(istr.fail())
01538 {
01539
01540 value = write_buffer.str();
01541 return LLSDParser::PARSE_FAILURE;
01542 }
01543
01544 if(found_escape)
01545 {
01546
01547 if(found_hex)
01548 {
01549 if(found_digit)
01550 {
01551 found_digit = false;
01552 found_hex = false;
01553 found_escape = false;
01554 byte = byte << 4;
01555 byte |= hex_as_nybble(next_char);
01556 write_buffer << byte;
01557 byte = 0;
01558 }
01559 else
01560 {
01561
01562
01563 found_digit = true;
01564 byte = hex_as_nybble(next_char);
01565 }
01566 }
01567 else if(next_char == 'x')
01568 {
01569 found_hex = true;
01570 }
01571 else
01572 {
01573 switch(next_char)
01574 {
01575 case 'a':
01576 write_buffer << '\a';
01577 break;
01578 case 'b':
01579 write_buffer << '\b';
01580 break;
01581 case 'f':
01582 write_buffer << '\f';
01583 break;
01584 case 'n':
01585 write_buffer << '\n';
01586 break;
01587 case 'r':
01588 write_buffer << '\r';
01589 break;
01590 case 't':
01591 write_buffer << '\t';
01592 break;
01593 case 'v':
01594 write_buffer << '\v';
01595 break;
01596 default:
01597 write_buffer << next_char;
01598 break;
01599 }
01600 found_escape = false;
01601 }
01602 }
01603 else if(next_char == '\\')
01604 {
01605 found_escape = true;
01606 }
01607 else if(next_char == delim)
01608 {
01609 break;
01610 }
01611 else
01612 {
01613 write_buffer << next_char;
01614 }
01615 }
01616
01617 value = write_buffer.str();
01618 return count;
01619 }
01620
01621 int deserialize_string_raw(
01622 std::istream& istr,
01623 std::string& value,
01624 S32 max_bytes)
01625 {
01626 int count = 0;
01627 const S32 BUF_LEN = 20;
01628 char buf[BUF_LEN];
01629 istr.get(buf, BUF_LEN - 1, ')');
01630 count += istr.gcount();
01631 char c = istr.get();
01632 c = istr.get();
01633 count += 2;
01634 if(((c == '"') || (c == '\'')) && (buf[0] == '('))
01635 {
01636
01637
01638
01639 S32 len = strtol(buf + 1, NULL, 0);
01640 if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE;
01641 std::vector<char> buf;
01642 if(len)
01643 {
01644 buf.resize(len);
01645 count += fullread(istr, (char *)&buf[0], len);
01646 value.assign(buf.begin(), buf.end());
01647 }
01648 c = istr.get();
01649 ++count;
01650 if(!((c == '"') || (c == '\'')))
01651 {
01652 return LLSDParser::PARSE_FAILURE;
01653 }
01654 }
01655 else
01656 {
01657 return LLSDParser::PARSE_FAILURE;
01658 }
01659 return count;
01660 }
01661
01662 static const char* NOTATION_STRING_CHARACTERS[256] =
01663 {
01664 "\\x00",
01665 "\\x01",
01666 "\\x02",
01667 "\\x03",
01668 "\\x04",
01669 "\\x05",
01670 "\\x06",
01671 "\\a",
01672 "\\b",
01673 "\\t",
01674 "\\n",
01675 "\\v",
01676 "\\f",
01677 "\\r",
01678 "\\x0e",
01679 "\\x0f",
01680 "\\x10",
01681 "\\x11",
01682 "\\x12",
01683 "\\x13",
01684 "\\x14",
01685 "\\x15",
01686 "\\x16",
01687 "\\x17",
01688 "\\x18",
01689 "\\x19",
01690 "\\x1a",
01691 "\\x1b",
01692 "\\x1c",
01693 "\\x1d",
01694 "\\x1e",
01695 "\\x1f",
01696 " ",
01697 "!",
01698 "\"",
01699 "#",
01700 "$",
01701 "%",
01702 "&",
01703 "\\'",
01704 "(",
01705 ")",
01706 "*",
01707 "+",
01708 ",",
01709 "-",
01710 ".",
01711 "/",
01712 "0",
01713 "1",
01714 "2",
01715 "3",
01716 "4",
01717 "5",
01718 "6",
01719 "7",
01720 "8",
01721 "9",
01722 ":",
01723 ";",
01724 "<",
01725 "=",
01726 ">",
01727 "?",
01728 "@",
01729 "A",
01730 "B",
01731 "C",
01732 "D",
01733 "E",
01734 "F",
01735 "G",
01736 "H",
01737 "I",
01738 "J",
01739 "K",
01740 "L",
01741 "M",
01742 "N",
01743 "O",
01744 "P",
01745 "Q",
01746 "R",
01747 "S",
01748 "T",
01749 "U",
01750 "V",
01751 "W",
01752 "X",
01753 "Y",
01754 "Z",
01755 "[",
01756 "\\\\",
01757 "]",
01758 "^",
01759 "_",
01760 "`",
01761 "a",
01762 "b",
01763 "c",
01764 "d",
01765 "e",
01766 "f",
01767 "g",
01768 "h",
01769 "i",
01770 "j",
01771 "k",
01772 "l",
01773 "m",
01774 "n",
01775 "o",
01776 "p",
01777 "q",
01778 "r",
01779 "s",
01780 "t",
01781 "u",
01782 "v",
01783 "w",
01784 "x",
01785 "y",
01786 "z",
01787 "{",
01788 "|",
01789 "}",
01790 "~",
01791 "\\x7f",
01792 "\\x80",
01793 "\\x81",
01794 "\\x82",
01795 "\\x83",
01796 "\\x84",
01797 "\\x85",
01798 "\\x86",
01799 "\\x87",
01800 "\\x88",
01801 "\\x89",
01802 "\\x8a",
01803 "\\x8b",
01804 "\\x8c",
01805 "\\x8d",
01806 "\\x8e",
01807 "\\x8f",
01808 "\\x90",
01809 "\\x91",
01810 "\\x92",
01811 "\\x93",
01812 "\\x94",
01813 "\\x95",
01814 "\\x96",
01815 "\\x97",
01816 "\\x98",
01817 "\\x99",
01818 "\\x9a",
01819 "\\x9b",
01820 "\\x9c",
01821 "\\x9d",
01822 "\\x9e",
01823 "\\x9f",
01824 "\\xa0",
01825 "\\xa1",
01826 "\\xa2",
01827 "\\xa3",
01828 "\\xa4",
01829 "\\xa5",
01830 "\\xa6",
01831 "\\xa7",
01832 "\\xa8",
01833 "\\xa9",
01834 "\\xaa",
01835 "\\xab",
01836 "\\xac",
01837 "\\xad",
01838 "\\xae",
01839 "\\xaf",
01840 "\\xb0",
01841 "\\xb1",
01842 "\\xb2",
01843 "\\xb3",
01844 "\\xb4",
01845 "\\xb5",
01846 "\\xb6",
01847 "\\xb7",
01848 "\\xb8",
01849 "\\xb9",
01850 "\\xba",
01851 "\\xbb",
01852 "\\xbc",
01853 "\\xbd",
01854 "\\xbe",
01855 "\\xbf",
01856 "\\xc0",
01857 "\\xc1",
01858 "\\xc2",
01859 "\\xc3",
01860 "\\xc4",
01861 "\\xc5",
01862 "\\xc6",
01863 "\\xc7",
01864 "\\xc8",
01865 "\\xc9",
01866 "\\xca",
01867 "\\xcb",
01868 "\\xcc",
01869 "\\xcd",
01870 "\\xce",
01871 "\\xcf",
01872 "\\xd0",
01873 "\\xd1",
01874 "\\xd2",
01875 "\\xd3",
01876 "\\xd4",
01877 "\\xd5",
01878 "\\xd6",
01879 "\\xd7",
01880 "\\xd8",
01881 "\\xd9",
01882 "\\xda",
01883 "\\xdb",
01884 "\\xdc",
01885 "\\xdd",
01886 "\\xde",
01887 "\\xdf",
01888 "\\xe0",
01889 "\\xe1",
01890 "\\xe2",
01891 "\\xe3",
01892 "\\xe4",
01893 "\\xe5",
01894 "\\xe6",
01895 "\\xe7",
01896 "\\xe8",
01897 "\\xe9",
01898 "\\xea",
01899 "\\xeb",
01900 "\\xec",
01901 "\\xed",
01902 "\\xee",
01903 "\\xef",
01904 "\\xf0",
01905 "\\xf1",
01906 "\\xf2",
01907 "\\xf3",
01908 "\\xf4",
01909 "\\xf5",
01910 "\\xf6",
01911 "\\xf7",
01912 "\\xf8",
01913 "\\xf9",
01914 "\\xfa",
01915 "\\xfb",
01916 "\\xfc",
01917 "\\xfd",
01918 "\\xfe",
01919 "\\xff"
01920 };
01921
01922 void serialize_string(const std::string& value, std::ostream& str)
01923 {
01924 std::string::const_iterator it = value.begin();
01925 std::string::const_iterator end = value.end();
01926 U8 c;
01927 for(; it != end; ++it)
01928 {
01929 c = (U8)(*it);
01930 str << NOTATION_STRING_CHARACTERS[c];
01931 }
01932 }
01933
01934 int deserialize_boolean(
01935 std::istream& istr,
01936 LLSD& data,
01937 const std::string& compare,
01938 bool value)
01939 {
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951 int bytes_read = 0;
01952 std::string::size_type ii = 0;
01953 char c = istr.peek();
01954 while((++ii < compare.size())
01955 && (tolower(c) == (int)compare[ii])
01956 && istr.good())
01957 {
01958 istr.ignore();
01959 ++bytes_read;
01960 c = istr.peek();
01961 }
01962 if(compare.size() != ii)
01963 {
01964 data.clear();
01965 return LLSDParser::PARSE_FAILURE;
01966 }
01967 data = value;
01968 return bytes_read;
01969 }
01970
01971 std::ostream& operator<<(std::ostream& s, const LLSD& llsd)
01972 {
01973 s << LLSDNotationStreamer(llsd);
01974 return s;
01975 }
01976