llsd.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 #include "llsd.h"
00034 
00035 #include "llerror.h"
00036 #include "../llmath/llmath.h"
00037 #include "llformat.h"
00038 #include "llsdserialize.h"
00039 
00040 #ifndef LL_RELEASE_FOR_DOWNLOAD
00041 #define NAME_UNNAMED_NAMESPACE
00042 #endif
00043 
00044 #ifdef NAME_UNNAMED_NAMESPACE
00045 namespace LLSDUnnamedNamespace {
00046 #else
00047 namespace {
00048 #endif
00049         class ImplMap;
00050         class ImplArray;
00051 }
00052 
00053 #ifdef NAME_UNNAMED_NAMESPACE
00054 using namespace LLSDUnnamedNamespace;
00055 #endif
00056 
00057 class LLSD::Impl
00064 {
00065 private:
00066         U32 mUseCount;
00067         
00068 protected:
00069         Impl();
00070 
00071         enum StaticAllocationMarker { STATIC };
00072         Impl(StaticAllocationMarker);
00074                 //   suppresses adjusting the debugging counters when they are
00075                 //       finally initialized.
00076                 
00077         virtual ~Impl();
00078         
00079         bool shared() const                                                     { return mUseCount > 1; }
00080         
00081 public:
00082         static void reset(Impl*& var, Impl* impl);
00084                 
00085         static       Impl& safe(      Impl*);
00086         static const Impl& safe(const Impl*);
00088                 //       always an object you call virtual member functions on
00089                 
00090         virtual ImplMap& makeMap(Impl*& var);
00091         virtual ImplArray& makeArray(Impl*& var);
00093         
00094         virtual LLSD::Type type() const                         { return LLSD::TypeUndefined; }
00095         
00096         static  void assignUndefined(LLSD::Impl*& var);
00097         static  void assign(LLSD::Impl*& var, const LLSD::Impl* other);
00098         
00099         virtual void assign(Impl*& var, LLSD::Boolean);
00100         virtual void assign(Impl*& var, LLSD::Integer);
00101         virtual void assign(Impl*& var, LLSD::Real);
00102         virtual void assign(Impl*& var, const LLSD::String&);
00103         virtual void assign(Impl*& var, const LLSD::UUID&);
00104         virtual void assign(Impl*& var, const LLSD::Date&);
00105         virtual void assign(Impl*& var, const LLSD::URI&);
00106         virtual void assign(Impl*& var, const LLSD::Binary&);
00108                 //   data assignments, othewise the default implementation handless
00109                 //   constructing the proper Impl subclass
00110                  
00111         virtual Boolean asBoolean() const                       { return false; }
00112         virtual Integer asInteger() const                       { return 0; }
00113         virtual Real    asReal() const                          { return 0.0; }
00114         virtual String  asString() const                        { return std::string(); }
00115         virtual UUID    asUUID() const                          { return LLUUID(); }
00116         virtual Date    asDate() const                          { return LLDate(); }
00117         virtual URI             asURI() const                           { return LLURI(); }
00118         virtual Binary  asBinary() const                        { return std::vector<U8>(); }
00119         
00120         virtual bool has(const String&) const           { return false; }
00121         virtual LLSD get(const String&) const           { return LLSD(); }
00122         virtual void erase(const String&)                       { }
00123         virtual const LLSD& ref(const String&) const{ return undef(); }
00124         
00125         virtual int size() const                                        { return 0; }
00126         virtual LLSD get(Integer) const                         { return LLSD(); }
00127         virtual void erase(Integer)                                     { }
00128         virtual const LLSD& ref(Integer) const          { return undef(); }
00129 
00130         virtual LLSD::map_const_iterator beginMap() const { return LLSD::map_const_iterator(); }
00131         virtual LLSD::map_const_iterator endMap() const { return LLSD::map_const_iterator(); }
00132         virtual LLSD::array_const_iterator beginArray() const { return LLSD::array_const_iterator(); }
00133         virtual LLSD::array_const_iterator endArray() const { return LLSD::array_const_iterator(); }
00134 
00135         static const LLSD& undef();
00136         
00137         static U32 sAllocationCount;
00138         static U32 sOutstandingCount;
00139 };
00140 
00141 #ifdef NAME_UNNAMED_NAMESPACE
00142 namespace LLSDUnnamedNamespace {
00143 #else
00144 namespace {
00145 #endif
00146         template<LLSD::Type T, class Data, class DataRef = Data>
00147         class ImplBase : public LLSD::Impl
00149                 //   for a given simple data type.  Subclasses of this provide the
00150                 //   conversion functions and a constructor.
00151         {
00152         protected:
00153                 Data mValue;
00154                 
00155                 typedef ImplBase Base;
00156 
00157         public:
00158                 ImplBase(DataRef value) : mValue(value) { }
00159                 
00160                 virtual LLSD::Type type() const { return T; }
00161 
00162                 virtual void assign(LLSD::Impl*& var, DataRef value) {
00163                         if (shared())
00164                         {
00165                                 Impl::assign(var, value);
00166                         }
00167                         else
00168                         {
00169                                 mValue = value;
00170                         }
00171                 }
00172         };
00173 
00174         
00175         class ImplBoolean
00176                 : public ImplBase<LLSD::TypeBoolean, LLSD::Boolean>
00177         {
00178         public:
00179                 ImplBoolean(LLSD::Boolean v) : Base(v) { }
00180                 
00181                 virtual LLSD::Boolean   asBoolean() const       { return mValue; }
00182                 virtual LLSD::Integer   asInteger() const       { return mValue ? 1 : 0; }
00183                 virtual LLSD::Real              asReal() const          { return mValue ? 1 : 0; }
00184                 virtual LLSD::String    asString() const;
00185         };
00186 
00187         LLSD::String ImplBoolean::asString() const
00188                 // *NOTE: The reason that false is not converted to "false" is
00189                 // because that would break roundtripping,
00190                 // e.g. LLSD(false).asString().asBoolean().  There are many
00191                 // reasons for wanting LLSD("false").asBoolean() == true, such
00192                 // as "everything else seems to work that way".
00193                 { return mValue ? "true" : ""; }
00194 
00195 
00196         class ImplInteger
00197                 : public ImplBase<LLSD::TypeInteger, LLSD::Integer>
00198         {
00199         public:
00200                 ImplInteger(LLSD::Integer v) : Base(v) { }
00201                 
00202                 virtual LLSD::Boolean   asBoolean() const       { return mValue != 0; }
00203                 virtual LLSD::Integer   asInteger() const       { return mValue; }
00204                 virtual LLSD::Real              asReal() const          { return mValue; }
00205                 virtual LLSD::String    asString() const;
00206         };
00207 
00208         LLSD::String ImplInteger::asString() const
00209                 { return llformat("%d", mValue); }
00210 
00211 
00212         class ImplReal
00213                 : public ImplBase<LLSD::TypeReal, LLSD::Real>
00214         {
00215         public:
00216                 ImplReal(LLSD::Real v) : Base(v) { }
00217                                 
00218                 virtual LLSD::Boolean   asBoolean() const;
00219                 virtual LLSD::Integer   asInteger() const;
00220                 virtual LLSD::Real              asReal() const          { return mValue; }
00221                 virtual LLSD::String    asString() const;
00222         };
00223 
00224         LLSD::Boolean ImplReal::asBoolean() const
00225                 { return !llisnan(mValue)  &&  mValue != 0.0; }
00226                 
00227         LLSD::Integer ImplReal::asInteger() const
00228                 { return !llisnan(mValue) ? (LLSD::Integer)mValue : 0; }
00229                 
00230         LLSD::String ImplReal::asString() const
00231                 { return llformat("%lg", mValue); }
00232 
00233 
00234         class ImplString
00235                 : public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&>
00236         {
00237         public:
00238                 ImplString(const LLSD::String& v) : Base(v) { }
00239                                 
00240                 virtual LLSD::Boolean   asBoolean() const       { return !mValue.empty(); }
00241                 virtual LLSD::Integer   asInteger() const;
00242                 virtual LLSD::Real              asReal() const;
00243                 virtual LLSD::String    asString() const        { return mValue; }
00244                 virtual LLSD::UUID              asUUID() const  { return LLUUID(mValue); }
00245                 virtual LLSD::Date              asDate() const  { return LLDate(mValue); }
00246                 virtual LLSD::URI               asURI() const   { return LLURI(mValue); }
00247         };
00248         
00249         LLSD::Integer   ImplString::asInteger() const
00250         {
00251                 // This must treat "1.23" not as an error, but as a number, which is
00252                 // then truncated down to an integer.  Hence, this code doesn't call
00253                 // std::istringstream::operator>>(int&), which would not consume the
00254                 // ".23" portion.
00255                 
00256                 return (int)asReal();
00257         }
00258         
00259         LLSD::Real              ImplString::asReal() const
00260         {
00261                 F64 v = 0.0;
00262                 std::istringstream i_stream(mValue);
00263                 i_stream >> v;
00264 
00265                 // we would probably like to ignore all trailing whitespace as
00266                 // well, but for now, simply eat the next character, and make
00267                 // sure we reached the end of the string.
00268                 // *NOTE: gcc 2.95 does not generate an eof() event on the
00269                 // stream operation above, so we manually get here to force it
00270                 // across platforms.
00271                 int c = i_stream.get();
00272                 return ((EOF ==c) ? v : 0.0);
00273         }
00274         
00275 
00276         class ImplUUID
00277                 : public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&>
00278         {
00279         public:
00280                 ImplUUID(const LLSD::UUID& v) : Base(v) { }
00281                                 
00282                 virtual LLSD::String    asString() const{ return mValue.asString(); }
00283                 virtual LLSD::UUID              asUUID() const  { return mValue; }
00284         };
00285 
00286 
00287         class ImplDate
00288                 : public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>
00289         {
00290         public:
00291                 ImplDate(const LLSD::Date& v)
00292                         : ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v)
00293                         { }
00294                 
00295                 virtual LLSD::Integer asInteger() const
00296                 {
00297                         return (LLSD::Integer)(mValue.secondsSinceEpoch());
00298                 }
00299                 virtual LLSD::Real asReal() const
00300                 {
00301                         return mValue.secondsSinceEpoch();
00302                 }
00303                 virtual LLSD::String    asString() const{ return mValue.asString(); }
00304                 virtual LLSD::Date              asDate() const  { return mValue; }
00305         };
00306 
00307 
00308         class ImplURI
00309                 : public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&>
00310         {
00311         public:
00312                 ImplURI(const LLSD::URI& v) : Base(v) { }
00313                                 
00314                 virtual LLSD::String    asString() const{ return mValue.asString(); }
00315                 virtual LLSD::URI               asURI() const   { return mValue; }
00316         };
00317 
00318 
00319         class ImplBinary
00320                 : public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&>
00321         {
00322         public:
00323                 ImplBinary(const LLSD::Binary& v) : Base(v) { }
00324                                 
00325                 virtual LLSD::Binary    asBinary() const{ return mValue; }
00326         };
00327 
00328 
00329         class ImplMap : public LLSD::Impl
00330         {
00331         private:
00332                 typedef std::map<LLSD::String, LLSD>    DataMap;
00333                 
00334                 DataMap mData;
00335                 
00336         protected:
00337                 ImplMap(const DataMap& data) : mData(data) { }
00338                 
00339         public:
00340                 ImplMap() { }
00341                 
00342                 virtual ImplMap& makeMap(LLSD::Impl*&);
00343 
00344                 virtual LLSD::Type type() const { return LLSD::TypeMap; }
00345 
00346                 virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
00347 
00348                 virtual bool has(const LLSD::String&) const; 
00349                 virtual LLSD get(const LLSD::String&) const; 
00350                         void insert(const LLSD::String& k, const LLSD& v);
00351                 virtual void erase(const LLSD::String&);
00352                               LLSD& ref(const LLSD::String&);
00353                 virtual const LLSD& ref(const LLSD::String&) const;
00354 
00355                 virtual int size() const { return mData.size(); }
00356 
00357                 LLSD::map_iterator beginMap() { return mData.begin(); }
00358                 LLSD::map_iterator endMap() { return mData.end(); }
00359                 virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
00360                 virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
00361         };
00362         
00363         ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
00364         {
00365                 if (shared())
00366                 {
00367                         ImplMap* i = new ImplMap(mData);
00368                         Impl::assign(var, i);
00369                         return *i;
00370                 }
00371                 else
00372                 {
00373                         return *this;
00374                 }
00375         }
00376         
00377         bool ImplMap::has(const LLSD::String& k) const
00378         {
00379                 DataMap::const_iterator i = mData.find(k);
00380                 return i != mData.end();
00381         }
00382         
00383         LLSD ImplMap::get(const LLSD::String& k) const
00384         {
00385                 DataMap::const_iterator i = mData.find(k);
00386                 return (i != mData.end()) ? i->second : LLSD();
00387         }
00388         
00389         void ImplMap::insert(const LLSD::String& k, const LLSD& v)
00390         {
00391                 mData.insert(DataMap::value_type(k, v));
00392         }
00393         
00394         void ImplMap::erase(const LLSD::String& k)
00395         {
00396                 mData.erase(k);
00397         }
00398         
00399         LLSD& ImplMap::ref(const LLSD::String& k)
00400         {
00401                 return mData[k];
00402         }
00403         
00404         const LLSD& ImplMap::ref(const LLSD::String& k) const
00405         {
00406                 DataMap::const_iterator i = mData.lower_bound(k);
00407                 if (i == mData.end()  ||  mData.key_comp()(k, i->first))
00408                 {
00409                         return undef();
00410                 }
00411                 
00412                 return i->second;
00413         }
00414 
00415         class ImplArray : public LLSD::Impl
00416         {
00417         private:
00418                 typedef std::vector<LLSD>       DataVector;
00419                 
00420                 DataVector mData;
00421                 
00422         protected:
00423                 ImplArray(const DataVector& data) : mData(data) { }
00424                 
00425         public:
00426                 ImplArray() { }
00427                 
00428                 virtual ImplArray& makeArray(Impl*&);
00429 
00430                 virtual LLSD::Type type() const { return LLSD::TypeArray; }
00431 
00432                 virtual LLSD::Boolean asBoolean() const { return !mData.empty(); }
00433 
00434                 virtual int size() const; 
00435                 virtual LLSD get(LLSD::Integer) const;
00436                         void set(LLSD::Integer, const LLSD&);
00437                         void insert(LLSD::Integer, const LLSD&);
00438                         void append(const LLSD&);
00439                 virtual void erase(LLSD::Integer);
00440                               LLSD& ref(LLSD::Integer);
00441                 virtual const LLSD& ref(LLSD::Integer) const; 
00442 
00443                 LLSD::array_iterator beginArray() { return mData.begin(); }
00444                 LLSD::array_iterator endArray() { return mData.end(); }
00445                 virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
00446                 virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
00447         };
00448 
00449         ImplArray& ImplArray::makeArray(Impl*& var)
00450         {
00451                 if (shared())
00452                 {
00453                         ImplArray* i = new ImplArray(mData);
00454                         Impl::assign(var, i);
00455                         return *i;
00456                 }
00457                 else
00458                 {
00459                         return *this;
00460                 }
00461         }
00462         
00463         int ImplArray::size() const             { return mData.size(); }
00464         
00465         LLSD ImplArray::get(LLSD::Integer i) const
00466         {
00467                 if (i < 0) { return LLSD(); }
00468                 DataVector::size_type index = i;
00469                 
00470                 return (index < mData.size()) ? mData[index] : LLSD();
00471         }
00472         
00473         void ImplArray::set(LLSD::Integer i, const LLSD& v)
00474         {
00475                 if (i < 0) { return; }
00476                 DataVector::size_type index = i;
00477                 
00478                 if (index >= mData.size())
00479                 {
00480                         mData.resize(index + 1);
00481                 }
00482                 
00483                 mData[index] = v;
00484         }
00485         
00486         void ImplArray::insert(LLSD::Integer i, const LLSD& v)
00487         {
00488                 if (i < 0) { return; }
00489                 DataVector::size_type index = i;
00490                 
00491                 if (index >= mData.size())
00492                 {
00493                         mData.resize(index + 1);
00494                 }
00495                 
00496                 mData.insert(mData.begin() + index, v);
00497         }
00498         
00499         void ImplArray::append(const LLSD& v)
00500         {
00501                 mData.push_back(v);
00502         }
00503         
00504         void ImplArray::erase(LLSD::Integer i)
00505         {
00506                 if (i < 0) { return; }
00507                 DataVector::size_type index = i;
00508                 
00509                 if (index < mData.size())
00510                 {
00511                         mData.erase(mData.begin() + index);
00512                 }
00513         }
00514         
00515         LLSD& ImplArray::ref(LLSD::Integer i)
00516         {
00517                 DataVector::size_type index = i >= 0 ? i : 0;
00518                 
00519                 if (index >= mData.size())
00520                 {
00521                         mData.resize(i + 1);
00522                 }
00523                 
00524                 return mData[index];
00525         }
00526 
00527         const LLSD& ImplArray::ref(LLSD::Integer i) const
00528         {
00529                 if (i < 0) { return undef(); }
00530                 DataVector::size_type index = i;
00531                 
00532                 if (index >= mData.size())
00533                 {
00534                         return undef();
00535                 }
00536                 
00537                 return mData[index];
00538         }
00539 }
00540 
00541 LLSD::Impl::Impl()
00542         : mUseCount(0)
00543 {
00544         ++sAllocationCount;
00545         ++sOutstandingCount;
00546 }
00547 
00548 LLSD::Impl::Impl(StaticAllocationMarker)
00549         : mUseCount(0)
00550 {
00551 }
00552 
00553 LLSD::Impl::~Impl()
00554 {
00555         --sOutstandingCount;
00556 }
00557 
00558 void LLSD::Impl::reset(Impl*& var, Impl* impl)
00559 {
00560         if (impl) ++impl->mUseCount;
00561         if (var  &&  --var->mUseCount == 0)
00562         {
00563                 delete var;
00564         }
00565         var = impl;
00566 }
00567 
00568 LLSD::Impl& LLSD::Impl::safe(Impl* impl)
00569 {
00570         static Impl theUndefined(STATIC);
00571         return impl ? *impl : theUndefined;
00572 }
00573 
00574 const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
00575 {
00576         static Impl theUndefined(STATIC);
00577         return impl ? *impl : theUndefined;
00578 }
00579 
00580 ImplMap& LLSD::Impl::makeMap(Impl*& var)
00581 {
00582         ImplMap* im = new ImplMap;
00583         reset(var, im);
00584         return *im;
00585 }
00586 
00587 ImplArray& LLSD::Impl::makeArray(Impl*& var)
00588 {
00589         ImplArray* ia = new ImplArray;
00590         reset(var, ia);
00591         return *ia;
00592 }
00593 
00594 
00595 void LLSD::Impl::assign(Impl*& var, const Impl* other)
00596 {
00597         reset(var, const_cast<Impl*>(other));
00598 }
00599 
00600 void LLSD::Impl::assignUndefined(Impl*& var)
00601 {
00602         reset(var, 0);
00603 }
00604 
00605 void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v)
00606 {
00607         reset(var, new ImplBoolean(v));
00608 }
00609 
00610 void LLSD::Impl::assign(Impl*& var, LLSD::Integer v)
00611 {
00612         reset(var, new ImplInteger(v));
00613 }
00614 
00615 void LLSD::Impl::assign(Impl*& var, LLSD::Real v)
00616 {
00617         reset(var, new ImplReal(v));
00618 }
00619 
00620 void LLSD::Impl::assign(Impl*& var, const LLSD::String& v)
00621 {
00622         reset(var, new ImplString(v));
00623 }
00624 
00625 void LLSD::Impl::assign(Impl*& var, const LLSD::UUID& v)
00626 {
00627         reset(var, new ImplUUID(v));
00628 }
00629 
00630 void LLSD::Impl::assign(Impl*& var, const LLSD::Date& v)
00631 {
00632         reset(var, new ImplDate(v));
00633 }
00634 
00635 void LLSD::Impl::assign(Impl*& var, const LLSD::URI& v)
00636 {
00637         reset(var, new ImplURI(v));
00638 }
00639 
00640 void LLSD::Impl::assign(Impl*& var, const LLSD::Binary& v)
00641 {
00642         reset(var, new ImplBinary(v));
00643 }
00644 
00645 
00646 const LLSD& LLSD::Impl::undef()
00647 {
00648         static const LLSD immutableUndefined;
00649         return immutableUndefined;
00650 }
00651 
00652 U32 LLSD::Impl::sAllocationCount = 0;
00653 U32 LLSD::Impl::sOutstandingCount = 0;
00654 
00655 
00656 
00657 #ifdef NAME_UNNAMED_NAMESPACE
00658 namespace LLSDUnnamedNamespace {
00659 #else
00660 namespace {
00661 #endif
00662         inline LLSD::Impl& safe(LLSD::Impl* impl)
00663                 { return LLSD::Impl::safe(impl); }
00664                 
00665         inline const LLSD::Impl& safe(const LLSD::Impl* impl)
00666                 { return LLSD::Impl::safe(impl); }
00667                 
00668         inline ImplMap& makeMap(LLSD::Impl*& var)
00669                 { return safe(var).makeMap(var); }
00670                 
00671         inline ImplArray& makeArray(LLSD::Impl*& var)
00672                 { return safe(var).makeArray(var); }
00673 }
00674 
00675 
00676 LLSD::LLSD()                                                    : impl(0)       { }
00677 LLSD::~LLSD()                                                   { Impl::reset(impl, 0); }
00678 
00679 LLSD::LLSD(const LLSD& other)                   : impl(0) { assign(other); }
00680 void LLSD::assign(const LLSD& other)    { Impl::assign(impl, other.impl); }
00681 
00682 
00683 void LLSD::clear()                                              { Impl::assignUndefined(impl); }
00684 
00685 LLSD::Type LLSD::type() const                   { return safe(impl).type(); }
00686 
00687 // Scaler Constructors
00688 LLSD::LLSD(Boolean v)                                   : impl(0) { assign(v); }
00689 LLSD::LLSD(Integer v)                                   : impl(0) { assign(v); }
00690 LLSD::LLSD(Real v)                                              : impl(0) { assign(v); }
00691 LLSD::LLSD(const UUID& v)                               : impl(0) { assign(v); }
00692 LLSD::LLSD(const String& v)                             : impl(0) { assign(v); }
00693 LLSD::LLSD(const Date& v)                               : impl(0) { assign(v); }
00694 LLSD::LLSD(const URI& v)                                : impl(0) { assign(v); }
00695 LLSD::LLSD(const Binary& v)                             : impl(0) { assign(v); }
00696 
00697 // Convenience Constructors
00698 LLSD::LLSD(F32 v)                                               : impl(0) { assign((Real)v); }
00699 
00700 // Scalar Assignment
00701 void LLSD::assign(Boolean v)                    { safe(impl).assign(impl, v); }
00702 void LLSD::assign(Integer v)                    { safe(impl).assign(impl, v); }
00703 void LLSD::assign(Real v)                               { safe(impl).assign(impl, v); }
00704 void LLSD::assign(const String& v)              { safe(impl).assign(impl, v); }
00705 void LLSD::assign(const UUID& v)                { safe(impl).assign(impl, v); }
00706 void LLSD::assign(const Date& v)                { safe(impl).assign(impl, v); }
00707 void LLSD::assign(const URI& v)                 { safe(impl).assign(impl, v); }
00708 void LLSD::assign(const Binary& v)              { safe(impl).assign(impl, v); }
00709 
00710 // Scalar Accessors
00711 LLSD::Boolean   LLSD::asBoolean() const { return safe(impl).asBoolean(); }
00712 LLSD::Integer   LLSD::asInteger() const { return safe(impl).asInteger(); }
00713 LLSD::Real              LLSD::asReal() const    { return safe(impl).asReal(); }
00714 LLSD::String    LLSD::asString() const  { return safe(impl).asString(); }
00715 LLSD::UUID              LLSD::asUUID() const    { return safe(impl).asUUID(); }
00716 LLSD::Date              LLSD::asDate() const    { return safe(impl).asDate(); }
00717 LLSD::URI               LLSD::asURI() const             { return safe(impl).asURI(); }
00718 LLSD::Binary    LLSD::asBinary() const  { return safe(impl).asBinary(); }
00719 
00720 // const char * helpers
00721 LLSD::LLSD(const char* v)                               : impl(0) { assign(v); }
00722 void LLSD::assign(const char* v)
00723 {
00724         if(v) assign(std::string(v));
00725         else assign(std::string());
00726 }
00727 
00728 
00729 LLSD LLSD::emptyMap()
00730 {
00731         LLSD v;
00732         makeMap(v.impl);
00733         return v;
00734 }
00735 
00736 bool LLSD::has(const String& k) const   { return safe(impl).has(k); }
00737 LLSD LLSD::get(const String& k) const   { return safe(impl).get(k); } 
00738 
00739 void LLSD::insert(const String& k, const LLSD& v)
00740                                                                                 { makeMap(impl).insert(k, v); }
00741 void LLSD::erase(const String& k)               { makeMap(impl).erase(k); }
00742 
00743 LLSD&           LLSD::operator[](const String& k)
00744                                                                                 { return makeMap(impl).ref(k); }
00745 const LLSD& LLSD::operator[](const String& k) const
00746                                                                                 { return safe(impl).ref(k); }
00747 
00748 
00749 LLSD LLSD::emptyArray()
00750 {
00751         LLSD v;
00752         makeArray(v.impl);
00753         return v;
00754 }
00755 
00756 int LLSD::size() const                                  { return safe(impl).size(); }
00757  
00758 LLSD LLSD::get(Integer i) const                 { return safe(impl).get(i); } 
00759 void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); }
00760 
00761 void LLSD::insert(Integer i, const LLSD& v)
00762                                                                                 { makeArray(impl).insert(i, v); }
00763 void LLSD::append(const LLSD& v)                { makeArray(impl).append(v); }
00764 void LLSD::erase(Integer i)                             { makeArray(impl).erase(i); }
00765 
00766 LLSD&           LLSD::operator[](Integer i)
00767                                                                                 { return makeArray(impl).ref(i); }
00768 const LLSD& LLSD::operator[](Integer i) const
00769                                                                                 { return safe(impl).ref(i); }
00770 
00771 U32 LLSD::allocationCount()                             { return Impl::sAllocationCount; }
00772 U32 LLSD::outstandingCount()                    { return Impl::sOutstandingCount; }
00773 
00774 static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
00775 {
00776         // sStorage is used to hold the string representation of the llsd last
00777         // passed into this function.  If this function is never called (the
00778         // normal case when not debugging), nothing is allocated.  Otherwise
00779         // sStorage will point to the result of the last call.  This will actually
00780         // be one leak, but since this is used only when running under the
00781         // debugger, it should not be an issue.
00782         static char *sStorage = NULL;
00783         delete[] sStorage;
00784         std::string out_string;
00785         {
00786                 std::ostringstream out;
00787                 if (useXMLFormat)
00788                         out << LLSDXMLStreamer(llsd);
00789                 else
00790                         out << LLSDNotationStreamer(llsd);
00791                 out_string = out.str();
00792         }
00793         int len = out_string.length();
00794         sStorage = new char[len + 1];
00795         memcpy(sStorage, out_string.c_str(), len);
00796         sStorage[len] = '\0';
00797         return sStorage;
00798 }
00799 
00801 const char *LLSD::dumpXML(const LLSD &llsd)
00802 {
00803         return llsd_dump(llsd, true);
00804 }
00805 
00807 const char *LLSD::dump(const LLSD &llsd)
00808 {
00809         return llsd_dump(llsd, false);
00810 }
00811 
00812 LLSD::map_iterator                      LLSD::beginMap()                { return makeMap(impl).beginMap(); }
00813 LLSD::map_iterator                      LLSD::endMap()                  { return makeMap(impl).endMap(); }
00814 LLSD::map_const_iterator        LLSD::beginMap() const  { return safe(impl).beginMap(); }
00815 LLSD::map_const_iterator        LLSD::endMap() const    { return safe(impl).endMap(); }
00816 
00817 LLSD::array_iterator            LLSD::beginArray()              { return makeArray(impl).beginArray(); }
00818 LLSD::array_iterator            LLSD::endArray()                { return makeArray(impl).endArray(); }
00819 LLSD::array_const_iterator      LLSD::beginArray() const{ return safe(impl).beginArray(); }
00820 LLSD::array_const_iterator      LLSD::endArray() const  { return safe(impl).endArray(); }

Generated on Fri May 16 08:32:07 2008 for SecondLife by  doxygen 1.5.5