summaryrefslogtreecommitdiff
path: root/indra/llcorehttp
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2012-06-22 14:41:08 -0400
committerMonty Brandenberg <monty@lindenlab.com>2012-06-22 14:41:08 -0400
commit5ff1758b633f1984f601aacbb7920c3c744b87f7 (patch)
tree74916117ab2e64b70bd55975ec4d5ae826502d73 /indra/llcorehttp
parented55eec8e352a9c38670a9155bc239748f578da4 (diff)
SH-3177, SH-3180 std::iostream and LLSD serialization for BufferArray objects.
Seems to be working correctly. Not certain this is the fastest possible way to provide a std::streambuf interface but it's visually acceptable.
Diffstat (limited to 'indra/llcorehttp')
-rw-r--r--indra/llcorehttp/bufferstream.h59
-rw-r--r--indra/llcorehttp/tests/test_bufferstream.hpp54
2 files changed, 112 insertions, 1 deletions
diff --git a/indra/llcorehttp/bufferstream.h b/indra/llcorehttp/bufferstream.h
index 60bda9ff9a..9327a798aa 100644
--- a/indra/llcorehttp/bufferstream.h
+++ b/indra/llcorehttp/bufferstream.h
@@ -34,13 +34,59 @@
#include "bufferarray.h"
+/// @file bufferstream.h
+///
+/// std::streambuf and std::iostream adapters for BufferArray
+/// objects.
+///
+/// BufferArrayStreamBuf inherits std::streambuf and implements
+/// an unbuffered interface for streambuf. This may or may not
+/// be the most time efficient implementation and it is a little
+/// challenging.
+///
+/// BufferArrayStream inherits std::iostream and will be the
+/// adapter object most callers will be interested in (though
+/// it uses BufferArrayStreamBuf internally). Instances allow
+/// for the usual streaming operators ('<<', '>>') and serialization
+/// methods.
+///
+/// Example of LLSD serialization to a BufferArray:
+///
+/// BufferArray * ba = new BufferArray;
+/// BufferArrayStream bas(ba);
+/// LLSDSerialize::toXML(llsd, bas);
+/// operationOnBufferArray(ba);
+/// ba->release();
+/// ba = NULL;
+/// // operationOnBufferArray and bas are each holding
+/// // references to the ba instance at this point.
+///
+
namespace LLCore
{
+// =====================================================
+// BufferArrayStreamBuf
+// =====================================================
+
+/// Adapter class to put a std::streambuf interface on a BufferArray
+///
+/// Application developers will rarely be interested in anything
+/// other than the constructor and even that will rarely be used
+/// except indirectly via the @BufferArrayStream class. The
+/// choice of interfaces implemented yields a bufferless adapter
+/// that doesn't used either the input or output pointer triplets
+/// of the more common buffered implementations. This may or may
+/// not be faster and that question could stand to be looked at
+/// sometime.
+///
+
class BufferArrayStreamBuf : public std::streambuf
{
public:
+ /// Constructor increments the reference count on the
+ /// BufferArray argument and calls release() on destruction.
BufferArrayStreamBuf(BufferArray * array);
virtual ~BufferArrayStreamBuf();
@@ -74,9 +120,22 @@ protected:
}; // end class BufferArrayStreamBuf
+// =====================================================
+// BufferArrayStream
+// =====================================================
+
+/// Adapter class that supplies streaming operators to BufferArray
+///
+/// Provides a streaming adapter to an existing BufferArray
+/// instance so that the convenient '<<' and '>>' conversions
+/// can be applied to a BufferArray. Very convenient for LLSD
+/// serialization and parsing as well.
+
class BufferArrayStream : public std::iostream
{
public:
+ /// Constructor increments the reference count on the
+ /// BufferArray argument and calls release() on destruction.
BufferArrayStream(BufferArray * ba);
~BufferArrayStream();
diff --git a/indra/llcorehttp/tests/test_bufferstream.hpp b/indra/llcorehttp/tests/test_bufferstream.hpp
index 45ddb7fd80..831c901b9d 100644
--- a/indra/llcorehttp/tests/test_bufferstream.hpp
+++ b/indra/llcorehttp/tests/test_bufferstream.hpp
@@ -31,6 +31,8 @@
#include <iostream>
#include "test_allocator.h"
+#include "llsd.h"
+#include "llsdserialize.h"
using namespace LLCore;
@@ -173,6 +175,8 @@ void BufferStreamTestObjectType::test<5>()
const char * content("This is a string. A fragment.");
const size_t c_len(strlen(content));
ba->append(content, c_len);
+
+ // Creat an adapter for the BufferArray
BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba);
ensure("Memory being used", mMemTotal < GetMemTotal());
@@ -223,7 +227,7 @@ void BufferStreamTestObjectType::test<6>()
//ba->append(content, strlen(content));
{
- // create a new ref counted object with an implicit reference
+ // Creat an adapter for the BufferArray
BufferArrayStream bas(ba);
ensure("Memory being used", mMemTotal < GetMemTotal());
@@ -246,6 +250,54 @@ void BufferStreamTestObjectType::test<6>()
}
+template <> template <>
+void BufferStreamTestObjectType::test<7>()
+{
+ set_test_name("BufferArrayStream with LLSD serialization");
+
+ // record the total amount of dynamically allocated memory
+ mMemTotal = GetMemTotal();
+
+ // create a new ref counted BufferArray with implicit reference
+ BufferArray * ba = new BufferArray;
+
+ {
+ // Creat an adapter for the BufferArray
+ BufferArrayStream bas(ba);
+ ensure("Memory being used", mMemTotal < GetMemTotal());
+
+ // LLSD
+ LLSD llsd = LLSD::emptyMap();
+
+ llsd["int"] = LLSD::Integer(3);
+ llsd["float"] = LLSD::Real(923289.28992);
+ llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj");
+
+ LLSD llsd_map = LLSD::emptyMap();
+ llsd_map["int"] = LLSD::Integer(-2889);
+ llsd_map["float"] = LLSD::Real(2.37829e32);
+ llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP");
+
+ llsd["map"] = llsd_map;
+
+ // Serialize it
+ LLSDSerialize::toXML(llsd, bas);
+
+ std::string str;
+ bas >> str;
+ // std::cout << "SERIALIZED LLSD: " << str << std::endl;
+ ensure("Extracted string has reasonable length", str.size() > 60);
+ }
+
+ // release the implicit reference, causing the object to be released
+ ba->release();
+ ba = NULL;
+
+ // make sure we didn't leak any memory
+ // ensure("Allocated memory returned", mMemTotal == GetMemTotal());
+}
+
+
} // end namespace tut