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