// virtual S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const { S32 format_count = 1; switch(data.type()) { case LLSD::TypeMap: { ostr << "{"; bool need_comma = false; LLSD::map_const_iterator iter = data.beginMap(); LLSD::map_const_iterator end = data.endMap(); for(; iter != end; ++iter) { if(need_comma) ostr << ","; need_comma = true; ostr << '\''; serialize_string((*iter).first, ostr); ostr << "':"; format_count += format((*iter).second, ostr); } ostr << "}"; break; } case LLSD::TypeArray: { ostr << "["; bool need_comma = false; LLSD::array_const_iterator iter = data.beginArray(); LLSD::array_const_iterator end = data.endArray(); for(; iter != end; ++iter) { if(need_comma) ostr << ","; need_comma = true; format_count += format(*iter, ostr); } ostr << "]"; break; } case LLSD::TypeUndefined: ostr << "!"; break; case LLSD::TypeBoolean: if(mBoolAlpha || #if( LL_WINDOWS || __GNUC__ > 2) (ostr.flags() & std::ios::boolalpha) #else (ostr.flags() & 0x0100) #endif ) { ostr << (data.asBoolean() ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL); } else { ostr << (data.asBoolean() ? 1 : 0); } break; case LLSD::TypeInteger: ostr << "i" << data.asInteger(); break; case LLSD::TypeReal: ostr << "r"; if(mRealFormat.empty()) { ostr << data.asReal(); } else { formatReal(data.asReal(), ostr); } break; case LLSD::TypeUUID: ostr << "u" << data.asUUID(); break; case LLSD::TypeString: ostr << '\''; serialize_string(data.asString(), ostr); ostr << '\''; break; case LLSD::TypeDate: ostr << "d\"" << data.asDate() << "\""; break; case LLSD::TypeURI: ostr << "l\""; serialize_string(data.asString(), ostr); ostr << "\""; break; case LLSD::TypeBinary: { // *FIX: memory inefficient. std::vector<U8> buffer = data.asBinary(); ostr << "b(" << buffer.size() << ")\""; if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size()); ostr << "\""; break; } default: // *NOTE: This should never happen. ostr << "!"; break; } return format_count; }
void ensure_equals(const std::string& msg, const LLSD& actual, const LLSD& expected) { ensure_equals(msg + " type", actual.type(), expected.type()); switch (actual.type()) { case LLSD::TypeUndefined: return; case LLSD::TypeBoolean: ensure_equals(msg + " boolean", actual.asBoolean(), expected.asBoolean()); return; case LLSD::TypeInteger: ensure_equals(msg + " integer", actual.asInteger(), expected.asInteger()); return; case LLSD::TypeReal: ensure_equals(msg + " real", actual.asReal(), expected.asReal()); return; case LLSD::TypeString: ensure_equals(msg + " string", actual.asString(), expected.asString()); return; case LLSD::TypeUUID: ensure_equals(msg + " uuid", actual.asUUID(), expected.asUUID()); return; case LLSD::TypeDate: ensure_equals(msg + " date", actual.asDate(), expected.asDate()); return; case LLSD::TypeURI: ensure_equals(msg + " uri", actual.asURI(), expected.asURI()); return; case LLSD::TypeBinary: ensure_equals(msg + " binary", actual.asBinary(), expected.asBinary()); return; case LLSD::TypeMap: { ensure_equals(msg + " map size", actual.size(), expected.size()); LLSD::map_const_iterator actual_iter = actual.beginMap(); LLSD::map_const_iterator expected_iter = expected.beginMap(); while(actual_iter != actual.endMap()) { ensure_equals(msg + " map keys", actual_iter->first, expected_iter->first); ensure_equals(msg + "[" + actual_iter->first + "]", actual_iter->second, expected_iter->second); ++actual_iter; ++expected_iter; } return; } case LLSD::TypeArray: { ensure_equals(msg + " array size", actual.size(), expected.size()); for(int i = 0; i < actual.size(); ++i) { ensure_equals(msg + llformat("[%d]", i), actual[i], expected[i]); } return; } default: // should never get here, but compiler produces warning if we // don't cover this case, and at Linden warnings are fatal. throw failure(STRINGIZE("invalid type field " << actual.type())); } }
void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd) { ostr << "<value>"; switch(sd.type()) { case LLSD::TypeMap: { #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(map) BEGIN" << LL_ENDL; #endif ostr << "<struct>"; if(ostr.fail()) { LL_INFOS() << "STREAM FAILURE writing struct" << LL_ENDL; } LLSD::map_const_iterator it = sd.beginMap(); LLSD::map_const_iterator end = sd.endMap(); for(; it != end; ++it) { ostr << "<member><name>" << xml_escape_string((*it).first) << "</name>"; streamOut(ostr, (*it).second); if(ostr.fail()) { LL_INFOS() << "STREAM FAILURE writing '" << (*it).first << "' with sd type " << (*it).second.type() << LL_ENDL; } ostr << "</member>"; } ostr << "</struct>"; #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(map) END" << LL_ENDL; #endif break; } case LLSD::TypeArray: { #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(array) BEGIN" << LL_ENDL; #endif ostr << "<array><data>"; LLSD::array_const_iterator it = sd.beginArray(); LLSD::array_const_iterator end = sd.endArray(); for(; it != end; ++it) { streamOut(ostr, *it); if(ostr.fail()) { LL_INFOS() << "STREAM FAILURE writing array element sd type " << (*it).type() << LL_ENDL; } } #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(array) END" << LL_ENDL; #endif ostr << "</data></array>"; break; } case LLSD::TypeUndefined: // treat undefined as a bool with a false value. case LLSD::TypeBoolean: #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(bool)" << LL_ENDL; #endif ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>"; break; case LLSD::TypeInteger: #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(int)" << LL_ENDL; #endif ostr << "<i4>" << sd.asInteger() << "</i4>"; break; case LLSD::TypeReal: #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(real)" << LL_ENDL; #endif ostr << "<double>" << sd.asReal() << "</double>"; break; case LLSD::TypeString: #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(string)" << LL_ENDL; #endif ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; break; case LLSD::TypeUUID: #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(uuid)" << LL_ENDL; #endif // serialize it as a string ostr << "<string>" << sd.asString() << "</string>"; break; case LLSD::TypeURI: { #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(uri)" << LL_ENDL; #endif // serialize it as a string ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>"; break; } case LLSD::TypeBinary: { #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(binary)" << LL_ENDL; #endif // this is pretty inefficient, but we'll deal with that // problem when it becomes one. ostr << "<base64>"; LLSD::Binary buffer = sd.asBinary(); if(!buffer.empty()) { // *TODO: convert to LLBase64 int b64_buffer_length = apr_base64_encode_len(buffer.size()); char* b64_buffer = new char[b64_buffer_length]; b64_buffer_length = apr_base64_encode_binary( b64_buffer, &buffer[0], buffer.size()); ostr.write(b64_buffer, b64_buffer_length - 1); delete[] b64_buffer; } ostr << "</base64>"; break; } case LLSD::TypeDate: #if LL_SPEW_STREAM_OUT_DEBUGGING LL_INFOS() << "streamOut(date)" << LL_ENDL; #endif // no need to escape this since it will be alpha-numeric. ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>"; break; default: // unhandled type LL_WARNS() << "Unhandled structured data type: " << sd.type() << LL_ENDL; break; } ostr << "</value>"; }
// static LLURI LLURI::buildHTTP(const std::string& prefix, const LLSD& path) { LLURI result; // TODO: deal with '/' '?' '#' in host_port if (prefix.find("://") != prefix.npos) { // it is a prefix result = LLURI(prefix); } else { // it is just a host and optional port result.mScheme = "http"; result.mEscapedAuthority = escapeHostAndPort(prefix); } if (path.isArray()) { // break out and escape each path component for (LLSD::array_const_iterator it = path.beginArray(); it != path.endArray(); ++it) { LL_DEBUGS() << "PATH: inserting " << it->asString() << LL_ENDL; result.mEscapedPath += "/" + escapePathComponent(it->asString()); } } else if (path.isString()) { std::string pathstr(path); // Trailing slash is significant in HTTP land. If caller specified, // make a point of preserving. std::string last_slash; std::string::size_type len(pathstr.length()); if (len && pathstr[len-1] == '/') { last_slash = "/"; } // Escape every individual path component, recombining with slashes. for (boost::split_iterator<std::string::const_iterator> ti(pathstr, boost::first_finder("/")), tend; ti != tend; ++ti) { // Eliminate a leading slash or duplicate slashes anywhere. (Extra // slashes show up here as empty components.) This test also // eliminates a trailing slash, hence last_slash above. if (! ti->empty()) { result.mEscapedPath += "/" + escapePathComponent(std::string(ti->begin(), ti->end())); } } // Reinstate trailing slash, if any. result.mEscapedPath += last_slash; } else if(path.isUndefined()) { // do nothing } else { LL_WARNS() << "Valid path arguments to buildHTTP are array, string, or undef, you passed type" << path.type() << LL_ENDL; } result.mEscapedOpaque = "//" + result.mEscapedAuthority + result.mEscapedPath; return result; }
// virtual S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const { S32 format_count = 1; switch(data.type()) { case LLSD::TypeMap: { ostr.put('{'); U32 size_nbo = htonl(data.size()); ostr.write((const char*)(&size_nbo), sizeof(U32)); LLSD::map_const_iterator iter = data.beginMap(); LLSD::map_const_iterator end = data.endMap(); for(; iter != end; ++iter) { ostr.put('k'); formatString((*iter).first, ostr); format_count += format((*iter).second, ostr); } ostr.put('}'); break; } case LLSD::TypeArray: { ostr.put('['); U32 size_nbo = htonl(data.size()); ostr.write((const char*)(&size_nbo), sizeof(U32)); LLSD::array_const_iterator iter = data.beginArray(); LLSD::array_const_iterator end = data.endArray(); for(; iter != end; ++iter) { format_count += format(*iter, ostr); } ostr.put(']'); break; } case LLSD::TypeUndefined: ostr.put('!'); break; case LLSD::TypeBoolean: if(data.asBoolean()) ostr.put(BINARY_TRUE_SERIAL); else ostr.put(BINARY_FALSE_SERIAL); break; case LLSD::TypeInteger: { ostr.put('i'); U32 value_nbo = htonl(data.asInteger()); ostr.write((const char*)(&value_nbo), sizeof(U32)); break; } case LLSD::TypeReal: { ostr.put('r'); F64 value_nbo = ll_htond(data.asReal()); ostr.write((const char*)(&value_nbo), sizeof(F64)); break; } case LLSD::TypeUUID: { ostr.put('u'); LLUUID temp = data.asUUID(); ostr.write((const char*)(&(temp.mData)), UUID_BYTES); break; } case LLSD::TypeString: ostr.put('s'); formatString(data.asStringRef(), ostr); break; case LLSD::TypeDate: { ostr.put('d'); F64 value = data.asReal(); ostr.write((const char*)(&value), sizeof(F64)); break; } case LLSD::TypeURI: ostr.put('l'); formatString(data.asString(), ostr); break; case LLSD::TypeBinary: { ostr.put('b'); const std::vector<U8>& buffer = data.asBinary(); U32 size_nbo = htonl(buffer.size()); ostr.write((const char*)(&size_nbo), sizeof(U32)); if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size()); break; } default: // *NOTE: This should never happen. ostr.put('!'); break; } return format_count; }
S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const { S32 format_count = 1; std::string pre; std::string post; if (options & LLSDFormatter::OPTIONS_PRETTY) { for (U32 i = 0; i < level; i++) { pre += " "; } post = "\n"; } switch(data.type()) { case LLSD::TypeMap: { if (0 != level) ostr << post << pre; ostr << "{"; std::string inner_pre; if (options & LLSDFormatter::OPTIONS_PRETTY) { inner_pre = pre + " "; } bool need_comma = false; LLSD::map_const_iterator iter = data.beginMap(); LLSD::map_const_iterator end = data.endMap(); for(; iter != end; ++iter) { if(need_comma) ostr << ","; need_comma = true; ostr << post << inner_pre << '\''; serialize_string((*iter).first, ostr); ostr << "':"; format_count += format_impl((*iter).second, ostr, options, level + 2); } ostr << post << pre << "}"; break; } case LLSD::TypeArray: { ostr << post << pre << "["; bool need_comma = false; LLSD::array_const_iterator iter = data.beginArray(); LLSD::array_const_iterator end = data.endArray(); for(; iter != end; ++iter) { if(need_comma) ostr << ","; need_comma = true; format_count += format_impl(*iter, ostr, options, level + 1); } ostr << "]"; break; } case LLSD::TypeUndefined: ostr << "!"; break; case LLSD::TypeBoolean: if(mBoolAlpha || #if( LL_WINDOWS || __GNUC__ > 2) (ostr.flags() & std::ios::boolalpha) #else (ostr.flags() & 0x0100) #endif ) { ostr << (data.asBoolean() ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL); } else { ostr << (data.asBoolean() ? 1 : 0); } break; case LLSD::TypeInteger: ostr << "i" << data.asInteger(); break; case LLSD::TypeReal: ostr << "r"; if(mRealFormat.empty()) { ostr << data.asReal(); } else { formatReal(data.asReal(), ostr); } break; case LLSD::TypeUUID: ostr << "u" << data.asUUID(); break; case LLSD::TypeString: ostr << '\''; serialize_string(data.asStringRef(), ostr); ostr << '\''; break; case LLSD::TypeDate: ostr << "d\"" << data.asDate() << "\""; break; case LLSD::TypeURI: ostr << "l\""; serialize_string(data.asString(), ostr); ostr << "\""; break; case LLSD::TypeBinary: { // *FIX: memory inefficient. const std::vector<U8>& buffer = data.asBinary(); ostr << "b(" << buffer.size() << ")\""; if(buffer.size()) { if (options & LLSDFormatter::OPTIONS_PRETTY_BINARY) { std::ios_base::fmtflags old_flags = ostr.flags(); ostr.setf( std::ios::hex, std::ios::basefield ); ostr << "0x"; for (size_t i = 0; i < buffer.size(); i++) { ostr << (int) buffer[i]; } ostr.flags(old_flags); } else { ostr.write((const char*)&buffer[0], buffer.size()); } } ostr << "\""; break; } default: // *NOTE: This should never happen. ostr << "!"; break; } return format_count; }