summaryrefslogtreecommitdiff
path: root/indra/llcommon/llsd.cpp
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2011-11-17 08:06:31 -0500
committerNat Goodspeed <nat@lindenlab.com>2011-11-17 08:06:31 -0500
commitcc1fb7bcac2924674763d917f66d84fbadb11623 (patch)
tree4be6fb6742157246e9fdda0c9ca86947ec5c3268 /indra/llcommon/llsd.cpp
parent4bcdcd02fb7e83a2754084f2fb599b56ea6c8743 (diff)
LLSD-14: Bring over llsd.{h,cpp} enhancements from server-trunk.
Because new enum values have been added to the LLSD type field, a few external switch statements must be adjusted to suppress fatal warnings, even though we never expect to encounter an LLSD instance containing any of the new values.
Diffstat (limited to 'indra/llcommon/llsd.cpp')
-rw-r--r--indra/llcommon/llsd.cpp194
1 files changed, 162 insertions, 32 deletions
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 6ca0737445..862b6b5ebc 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -31,6 +31,7 @@
#include "../llmath/llmath.h"
#include "llformat.h"
#include "llsdserialize.h"
+#include "stringize.h"
#ifndef LL_RELEASE_FOR_DOWNLOAD
#define NAME_UNNAMED_NAMESPACE
@@ -50,6 +51,24 @@ namespace
using namespace LLSDUnnamedNamespace;
#endif
+
+// Normally undefined
+#ifdef LLSD_DEBUG_INFO
+
+// statics
+S32 LLSD::sLLSDAllocationCount = 0;
+S32 LLSD::sLLSDNetObjects = 0;
+
+#define ALLOC_LLSD_OBJECT { sLLSDNetObjects++; sLLSDAllocationCount++; }
+#define FREE_LLSD_OBJECT { sLLSDNetObjects--; }
+
+#else
+
+#define ALLOC_LLSD_OBJECT
+#define FREE_LLSD_OBJECT
+
+#endif
+
class LLSD::Impl
/**< This class is the abstract base class of the implementation of LLSD
It provides the reference counting implementation, and the default
@@ -58,13 +77,10 @@ class LLSD::Impl
*/
{
-private:
- U32 mUseCount;
-
protected:
Impl();
- enum StaticAllocationMarker { STATIC };
+ enum StaticAllocationMarker { STATIC_USAGE_COUNT = 0xFFFFFFFF };
Impl(StaticAllocationMarker);
///< This constructor is used for static objects and causes the
// suppresses adjusting the debugging counters when they are
@@ -72,7 +88,9 @@ protected:
virtual ~Impl();
- bool shared() const { return mUseCount > 1; }
+ bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); }
+
+ U32 mUseCount;
public:
static void reset(Impl*& var, Impl* impl);
@@ -128,6 +146,9 @@ public:
virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
+ virtual void dumpStats() const;
+ virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
+
static const LLSD& undef();
static U32 sAllocationCount;
@@ -360,6 +381,9 @@ namespace
LLSD::map_iterator endMap() { return mData.end(); }
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
+
+ virtual void dumpStats() const;
+ virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
};
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
@@ -414,6 +438,36 @@ namespace
return i->second;
}
+ void ImplMap::dumpStats() const
+ {
+ std::cout << "Map size: " << mData.size() << std::endl;
+
+ #ifdef LLSD_DEBUG_INFO
+ std::cout << "LLSD Net Objects: " << LLSD::sLLSDNetObjects << std::endl;
+ std::cout << "LLSD allocations: " << LLSD::sLLSDAllocationCount << std::endl;
+ #endif
+
+ std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl;
+ std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl;
+
+ Impl::dumpStats();
+ }
+
+ void ImplMap::calcStats(S32 type_counts[], S32 share_counts[]) const
+ {
+ LLSD::map_const_iterator iter = beginMap();
+ while (iter != endMap())
+ {
+ //std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
+ (*iter).second.calcStats(type_counts, share_counts);
+ iter++;
+ }
+
+ // Add in the values for this map
+ Impl::calcStats(type_counts, share_counts);
+ }
+
+
class ImplArray : public LLSD::Impl
{
private:
@@ -449,6 +503,8 @@ namespace
LLSD::array_iterator endArray() { return mData.end(); }
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
+
+ virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
};
ImplArray& ImplArray::makeArray(Impl*& var)
@@ -490,12 +546,13 @@ namespace
void ImplArray::insert(LLSD::Integer i, const LLSD& v)
{
- if (i < 0) {
+ if (i < 0)
+ {
return;
}
DataVector::size_type index = i;
- if (index >= mData.size())
+ if (index >= mData.size()) // tbd - sanity check limit for index ?
{
mData.resize(index + 1);
}
@@ -543,6 +600,19 @@ namespace
return mData[index];
}
+
+ void ImplArray::calcStats(S32 type_counts[], S32 share_counts[]) const
+ {
+ LLSD::array_const_iterator iter = beginArray();
+ while (iter != endArray())
+ { // Add values for all items held in the array
+ (*iter).calcStats(type_counts, share_counts);
+ iter++;
+ }
+
+ // Add in the values for this array
+ Impl::calcStats(type_counts, share_counts);
+ }
}
LLSD::Impl::Impl()
@@ -564,8 +634,11 @@ LLSD::Impl::~Impl()
void LLSD::Impl::reset(Impl*& var, Impl* impl)
{
- if (impl) ++impl->mUseCount;
- if (var && --var->mUseCount == 0)
+ if (impl && impl->mUseCount != STATIC_USAGE_COUNT)
+ {
+ ++impl->mUseCount;
+ }
+ if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
{
delete var;
}
@@ -574,13 +647,13 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl)
LLSD::Impl& LLSD::Impl::safe(Impl* impl)
{
- static Impl theUndefined(STATIC);
+ static Impl theUndefined(STATIC_USAGE_COUNT);
return impl ? *impl : theUndefined;
}
const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
{
- static Impl theUndefined(STATIC);
+ static Impl theUndefined(STATIC_USAGE_COUNT);
return impl ? *impl : theUndefined;
}
@@ -656,6 +729,39 @@ const LLSD& LLSD::Impl::undef()
return immutableUndefined;
}
+void LLSD::Impl::dumpStats() const
+{
+ S32 type_counts[LLSD::TypeLLSDNumTypes + 1];
+ memset(&type_counts, 0, LLSD::TypeLLSDNumTypes * sizeof(S32));
+
+ S32 share_counts[LLSD::TypeLLSDNumTypes + 1];
+ memset(&share_counts, 0, LLSD::TypeLLSDNumTypes * sizeof(S32));
+
+ // Add info from all the values this object has
+ calcStats(type_counts, share_counts);
+
+ S32 type_index = LLSD::TypeLLSDTypeBegin;
+ while (type_index != LLSD::TypeLLSDTypeEnd)
+ {
+ std::cout << LLSD::typeString((LLSD::Type)type_index) << " type "
+ << type_counts[type_index] << " objects, "
+ << share_counts[type_index] << " shared"
+ << std::endl;
+ type_index++;
+ }
+}
+
+
+void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
+{
+ type_counts[(S32) type()]++;
+ if (shared())
+ {
+ share_counts[(S32) type()]++;
+ }
+}
+
+
U32 LLSD::Impl::sAllocationCount = 0;
U32 LLSD::Impl::sOutstandingCount = 0;
@@ -681,10 +787,10 @@ namespace
}
-LLSD::LLSD() : impl(0) { }
-LLSD::~LLSD() { Impl::reset(impl, 0); }
+LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
+LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
-LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); }
+LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
@@ -693,17 +799,17 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
LLSD::Type LLSD::type() const { return safe(impl).type(); }
// Scaler Constructors
-LLSD::LLSD(Boolean v) : impl(0) { assign(v); }
-LLSD::LLSD(Integer v) : impl(0) { assign(v); }
-LLSD::LLSD(Real v) : impl(0) { assign(v); }
-LLSD::LLSD(const UUID& v) : impl(0) { assign(v); }
-LLSD::LLSD(const String& v) : impl(0) { assign(v); }
-LLSD::LLSD(const Date& v) : impl(0) { assign(v); }
-LLSD::LLSD(const URI& v) : impl(0) { assign(v); }
-LLSD::LLSD(const Binary& v) : impl(0) { assign(v); }
+LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
+LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
// Convenience Constructors
-LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); }
+LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
// Scalar Assignment
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
@@ -726,7 +832,7 @@ LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); }
LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); }
// const char * helpers
-LLSD::LLSD(const char* v) : impl(0) { assign(v); }
+LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
void LLSD::assign(const char* v)
{
if(v) assign(std::string(v));
@@ -801,15 +907,9 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
{
std::ostringstream out;
if (useXMLFormat)
- {
- LLSDXMLStreamer xml_streamer(llsd);
- out << xml_streamer;
- }
+ out << LLSDXMLStreamer(llsd);
else
- {
- LLSDNotationStreamer notation_streamer(llsd);
- out << notation_streamer;
- }
+ out << LLSDNotationStreamer(llsd);
out_string = out.str();
}
int len = out_string.length();
@@ -840,3 +940,33 @@ LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray();
LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }
+
+
+// Diagnostic dump of contents in an LLSD object
+void LLSD::dumpStats() const { safe(impl).dumpStats(); }
+void LLSD::calcStats(S32 type_counts[], S32 share_counts[]) const
+ { safe(impl).calcStats(type_counts, share_counts); }
+
+// static
+std::string LLSD::typeString(Type type)
+{
+ static const char * sTypeNameArray[] = {
+ "Undefined",
+ "Boolean",
+ "Integer",
+ "Real",
+ "String",
+ "UUID",
+ "Date",
+ "URI",
+ "Binary",
+ "Map",
+ "Array"
+ };
+
+ if (0 <= type < (sizeof(sTypeNameArray)/sizeof(sTypeNameArray[0])))
+ {
+ return sTypeNameArray[type];
+ }
+ return STRINGIZE("** invalid type value " << type);
+}