diff options
| author | Don Kjer <don@lindenlab.com> | 2013-03-13 06:26:25 +0000 | 
|---|---|---|
| committer | Don Kjer <don@lindenlab.com> | 2013-03-13 06:26:25 +0000 | 
| commit | f945415210f0e18c2c6d941fda6b7d45cb0f06f1 (patch) | |
| tree | cf93ca0d9596a82a8fc7a4d1b1f0ee263ea5549e /indra/llcommon/llsdserialize.cpp | |
| parent | 54cdc322b8f2bd35b289cacf3493622e7cc51194 (diff) | |
Large changes to the LLCurl::Responder API, as well as pulling in some changes to common libraries from the server codebase:
* Additional error checking in http handlers.
* Uniform log spam for http errors.
* Switch to using constants for http heads and status codes.
* Fixed bugs in incorrectly checking if parsing LLSD xml resulted in an error.
* Reduced spam regarding LLSD parsing errors in the default completedRaw http handler.  It should not longer be necessary to short-circuit completedRaw to avoid spam.
* Ported over a few bug fixes from the server code.
* Switch mode http status codes to use S32 instead of U32.
* Ported LLSD::asStringRef from server code; avoids copying strings all over the place.
* Ported server change to LLSD::asBinary; this always returns a reference now instead of copying the entire binary blob.
* Ported server pretty notation format (and pretty binary format) to llsd serialization.
* The new LLCurl::Responder API no longer has two error handlers to choose from.  Overriding the following methods have been deprecated:
** error - use httpFailure
** errorWithContent - use httpFailure
** result - use httpSuccess
** completed - use httpCompleted
** completedHeader - no longer necessary; call getResponseHeaders() from a completion method to obtain these headers.
* In order to 'catch' a completed http request, override one of these methods:
** httpSuccess - Called for any 2xx status code.
** httpFailure - Called for any non-2xx status code.
** httpComplete - Called for all status codes.  Default implementation is to call either httpSuccess or httpFailure.
* It is recommended to keep these methods protected/private in order to avoid triggering of these methods without using a 'push' method (see below).
* Uniform error handling should followed whenever possible by calling a variant of this during httpFailure:
** llwarns << dumpResponse() << llendl;
* Be sure to include LOG_CLASS(your_class_name) in your class in order for the log entry to give more context.
* In order to 'push' a result into the responder, you should no longer call error, errorWithContent, result, or completed.
* Nor should you directly call httpSuccess/Failure/Completed (unless passing a message up to a parent class).
* Instead, you can set the internal content of a responder and trigger a corresponding method using the following methods:
** successResult - Sets results and calls httpSuccess
** failureResult - Sets results and calls httpFailure
** completedResult - Sets results and calls httpCompleted
* To obtain information about a the response from a reponder method, use the following getters:
** getStatus - HTTP status code
** getReason - Reason string
** getContent - Content (Parsed body LLSD)
** getResponseHeaders - Response Headers (LLSD map)
** getHTTPMethod - HTTP method of the request
** getURL - URL of the request
* It is still possible to override completeRaw if you want to manipulate data directly out of LLPumpIO.
* See indra/llmessage/llcurl.h for more information.
Diffstat (limited to 'indra/llcommon/llsdserialize.cpp')
| -rw-r--r-- | indra/llcommon/llsdserialize.cpp | 65 | 
1 files changed, 53 insertions, 12 deletions
| diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index ad4fce6f35..774d827762 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -873,7 +873,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const  {  /**   * Undefined: '!'<br> - * Boolean: 't' for true 'f' for false<br> + * Boolean: '1' for true '0' for false<br>   * Integer: 'i' + 4 bytes network byte order<br>   * Real: 'r' + 8 bytes IEEE double<br>   * UUID: 'u' + 16 byte unsigned integer<br> @@ -1261,12 +1261,37 @@ std::string LLSDNotationFormatter::escapeString(const std::string& in)  // virtual  S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const  { +	S32 rv = format_impl(data, ostr, options, 0); +	return rv; +} + +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(); @@ -1274,18 +1299,18 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  		{  			if(need_comma) ostr << ",";  			need_comma = true; -			ostr << '\''; +			ostr << post << inner_pre << '\'';  			serialize_string((*iter).first, ostr);  			ostr << "':"; -			format_count += format((*iter).second, ostr); +			format_count += format_impl((*iter).second, ostr, options, level + 2);  		} -		ostr << "}"; +		ostr << post << pre << "}";  		break;  	}  	case LLSD::TypeArray:  	{ -		ostr << "["; +		ostr << post << pre << "[";  		bool need_comma = false;  		LLSD::array_const_iterator iter = data.beginArray();  		LLSD::array_const_iterator end = data.endArray(); @@ -1293,7 +1318,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  		{  			if(need_comma) ostr << ",";  			need_comma = true; -			format_count += format(*iter, ostr); +			format_count += format_impl(*iter, ostr, options, level + 1);  		}  		ostr << "]";  		break; @@ -1343,7 +1368,7 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  	case LLSD::TypeString:  		ostr << '\''; -		serialize_string(data.asString(), ostr); +		serialize_string(data.asStringRef(), ostr);  		ostr << '\'';  		break; @@ -1360,9 +1385,26 @@ S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 opti  	case LLSD::TypeBinary:  	{  		// *FIX: memory inefficient. -		std::vector<U8> buffer = data.asBinary(); +		const std::vector<U8>& buffer = data.asBinary();  		ostr << "b(" << buffer.size() << ")\""; -		if(buffer.size()) ostr.write((const char*)&buffer[0], 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 (int 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;  	} @@ -1460,7 +1502,7 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option  	case LLSD::TypeString:  		ostr.put('s'); -		formatString(data.asString(), ostr); +		formatString(data.asStringRef(), ostr);  		break;  	case LLSD::TypeDate: @@ -1478,9 +1520,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option  	case LLSD::TypeBinary:  	{ -		// *FIX: memory inefficient.  		ostr.put('b'); -		std::vector<U8> buffer = data.asBinary(); +		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()); | 
