From 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Fri, 15 Aug 2008 23:44:46 -0500 Subject: Second Life viewer sources 1.13.2.12 --- linden/indra/llcommon/llsd.h | 385 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 linden/indra/llcommon/llsd.h (limited to 'linden/indra/llcommon/llsd.h') diff --git a/linden/indra/llcommon/llsd.h b/linden/indra/llcommon/llsd.h new file mode 100644 index 0000000..625b480 --- /dev/null +++ b/linden/indra/llcommon/llsd.h @@ -0,0 +1,385 @@ +/** + * @file llsd.h + * @brief LLSD flexible data system. + * + * Copyright (c) 2005-2007, Linden Research, Inc. + * + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + */ + +#ifndef LL_LLSD_NEW_H +#define LL_LLSD_NEW_H + +#include +#include +#include + +#include "stdtypes.h" + +#include "lldate.h" +#include "lluri.h" +#include "../llmath/lluuid.h" + +/** + LLSD provides a flexible data system similar to the data facilities of + dynamic languages like Perl and Python. It is created to support exchange + of structured data between loosly coupled systems. (Here, "loosly coupled" + means not compiled together into the same module.) + + Data in such exchanges must be highly tollerant of changes on either side + such as: + - recompilation + - implementation in a different langauge + - addition of extra parameters + - execution of older versions (with fewer parameters) + + To this aim, the C++ API of LLSD strives to be very easy to use, and to + default to "the right thing" whereever possible. It is extremely tollerant + of errors and unexpected situations. + + The fundimental class is LLSD. LLSD is a value holding object. It holds + one value that is either undefined, one of the scalar types, or a map or an + array. LLSD objects have value semantics (copying them copies the value, + though it can be considered efficient, due to shareing.), and mutable. + + Undefined is the singular value given to LLSD objects that are not + initialized with any data. It is also used as the return value for + operations that return an LLSD, + + The sclar data types are: + - Boolean - true or false + - Integer - a 32 bit signed integer + - Real - a 64 IEEE 754 floating point value + - UUID - a 128 unique value + - String - a sequence of zero or more Unicode chracters + - Date - an absolute point in time, UTC, + with resolution to the second + - URI - a String that is a URI + - Binary - a sequence of zero or more octets (unsigned bytes) + + A map is a dictionary mapping String keys to LLSD values. The keys are + unique within a map, and have only one value (though that value could be + an LLSD array). + + An array is a sequence of zero or more LLSD values. + + @nosubgrouping +*/ + +class LLSD +{ +public: + LLSD(); ///< initially Undefined + ~LLSD(); ///< this class may NOT be subclassed + + /** @name Copyable and Assignable */ + //@{ + LLSD(const LLSD&); + void assign(const LLSD& other); + LLSD& operator=(const LLSD& other) { assign(other); return *this; } + + //@} + + void clear(); ///< resets to Undefined + + + /** @name Scalar Types + The scalar types, and how they map onto C++ + */ + //@{ + typedef bool Boolean; + typedef S32 Integer; + typedef F64 Real; + typedef std::string String; + typedef LLUUID UUID; + typedef LLDate Date; + typedef LLURI URI; + typedef std::vector Binary; + //@} + + /** @name Scalar Constructors */ + //@{ + LLSD(Boolean); + LLSD(Integer); + LLSD(Real); + LLSD(const String&); + LLSD(const UUID&); + LLSD(const Date&); + LLSD(const URI&); + LLSD(const Binary&); + //@} + + /** @name Convenience Constructors */ + //@{ + LLSD(F32); // F32 -> Real + //@} + + /** @name Scalar Assignment */ + //@{ + void assign(Boolean); + void assign(Integer); + void assign(Real); + void assign(const String&); + void assign(const UUID&); + void assign(const Date&); + void assign(const URI&); + void assign(const Binary&); + + LLSD& operator=(Boolean v) { assign(v); return *this; } + LLSD& operator=(Integer v) { assign(v); return *this; } + LLSD& operator=(Real v) { assign(v); return *this; } + LLSD& operator=(const String& v) { assign(v); return *this; } + LLSD& operator=(const UUID& v) { assign(v); return *this; } + LLSD& operator=(const Date& v) { assign(v); return *this; } + LLSD& operator=(const URI& v) { assign(v); return *this; } + LLSD& operator=(const Binary& v) { assign(v); return *this; } + //@} + + /** + @name Scalar Accessors + @brief Fetch a scalar value, converting if needed and possible + + Conversion among the basic types, Boolean, Integer, Real and String, is + fully defined. Each type can be converted to another with a reasonable + interpretation. These conversions can be used as a convenience even + when you know the data is in one format, but you want it in another. Of + course, many of these conversions lose information. + + Note: These conversions are not the same as Perl's. In particular, when + converting a String to a Boolean, only the empty string converts to + false. Converting the String "0" to Boolean results in true. + + Conversion to and from UUID, Date, and URI is only defined to and from + String. Conversion is defined to be information preserving for valid + values of those types. These conversions can be used when one needs to + convert data to or from another system that cannot handle these types + natively, but can handle strings. + + Conversion to and from Binary isn't defined. + + Conversion of the Undefined value to any scalar type results in a + reasonable null or zero value for the type. + */ + //@{ + Boolean asBoolean() const; + Integer asInteger() const; + Real asReal() const; + String asString() const; + UUID asUUID() const; + Date asDate() const; + URI asURI() const; + Binary asBinary() const; + + operator Boolean() const { return asBoolean(); } + operator Integer() const { return asInteger(); } + operator Real() const { return asReal(); } + operator String() const { return asString(); } + operator UUID() const { return asUUID(); } + operator Date() const { return asDate(); } + operator URI() const { return asURI(); } + operator Binary() const { return asBinary(); } + + // This is needed because most platforms do not automatically + // convert the boolean negation as a bool in an if statement. + bool operator!() const {return !asBoolean();} + //@} + + /** @name Character Pointer Helpers + These are helper routines to make working with char* the same as easy as + working with strings. + */ + //@{ + LLSD(const char*); + void assign(const char*); + LLSD& operator=(const char* v) { assign(v); return *this; } + //@} + + /** @name Map Values */ + //@{ + static LLSD emptyMap(); + + bool has(const String&) const; + LLSD get(const String&) const; + void insert(const String&, const LLSD&); + void erase(const String&); + + LLSD& operator[](const String&); + LLSD& operator[](const char* c) { return (*this)[String(c)]; } + const LLSD& operator[](const String&) const; + const LLSD& operator[](const char* c) const { return (*this)[String(c)]; } + //@} + + /** @name Array Values */ + //@{ + static LLSD emptyArray(); + + LLSD get(Integer) const; + void set(Integer, const LLSD&); + void insert(Integer, const LLSD&); + void append(const LLSD&); + void erase(Integer); + + const LLSD& operator[](Integer) const; + LLSD& operator[](Integer); + //@} + + /** @name Iterators */ + //@{ + int size() const; + + typedef std::map::iterator map_iterator; + typedef std::map::const_iterator map_const_iterator; + + map_iterator beginMap(); + map_iterator endMap(); + map_const_iterator beginMap() const; + map_const_iterator endMap() const; + + typedef std::vector::iterator array_iterator; + typedef std::vector::const_iterator array_const_iterator; + + array_iterator beginArray(); + array_iterator endArray(); + array_const_iterator beginArray() const; + array_const_iterator endArray() const; + //@} + + /** @name Type Testing */ + //@{ + enum Type { + TypeUndefined, + TypeBoolean, + TypeInteger, + TypeReal, + TypeString, + TypeUUID, + TypeDate, + TypeURI, + TypeBinary, + TypeMap, + TypeArray + }; + + Type type() const; + + bool isUndefined() const { return type() == TypeUndefined; } + bool isDefined() const { return type() != TypeUndefined; } + bool isBoolean() const { return type() == TypeBoolean; } + bool isInteger() const { return type() == TypeInteger; } + bool isReal() const { return type() == TypeReal; } + bool isString() const { return type() == TypeString; } + bool isUUID() const { return type() == TypeUUID; } + bool isDate() const { return type() == TypeDate; } + bool isURI() const { return type() == TypeURI; } + bool isBinary() const { return type() == TypeBinary; } + bool isMap() const { return type() == TypeMap; } + bool isArray() const { return type() == TypeArray; } + //@} + + /** @name Automatic Cast Protection + These are not implemented on purpose. Without them, C++ can perform + some conversions that are clearly not what the programmer intended. + + If you get a linker error about these being missing, you have made + mistake in your code. DO NOT IMPLEMENT THESE FUNCTIONS as a fix. + + All of thse problems stem from trying to support char* in LLSD or in + std::string. There are too many automatic casts that will lead to + using an arbitrary pointer or scalar type to std::string. + */ + //@{ + LLSD(const void*); ///< construct from aribrary pointers + void assign(const void*); ///< assign from arbitrary pointers + LLSD& operator=(const void*); ///< assign from arbitrary pointers + + bool has(Integer) const; ///< has only works for Maps + //@} + + /** @name Implementation */ + //@{ +public: + class Impl; +private: + Impl* impl; + //@} + + /** @name Unit Testing Interface */ + //@{ +public: + static U32 allocationCount(); ///< how many Impls have been made + static U32 outstandingCount(); ///< how many Impls are still alive + //@} +}; + +struct llsd_select_bool : public std::unary_function +{ + LLSD::Boolean operator()(const LLSD& sd) const + { + return sd.asBoolean(); + } +}; +struct llsd_select_integer : public std::unary_function +{ + LLSD::Integer operator()(const LLSD& sd) const + { + return sd.asInteger(); + } +}; +struct llsd_select_real : public std::unary_function +{ + LLSD::Real operator()(const LLSD& sd) const + { + return sd.asReal(); + } +}; +struct llsd_select_float : public std::unary_function +{ + F32 operator()(const LLSD& sd) const + { + return (F32)sd.asReal(); + } +}; +struct llsd_select_uuid : public std::unary_function +{ + LLSD::UUID operator()(const LLSD& sd) const + { + return sd.asUUID(); + } +}; +struct llsd_select_string : public std::unary_function +{ + LLSD::String operator()(const LLSD& sd) const + { + return sd.asString(); + } +}; + + +/** QUESTIONS & TO DOS + - Would Binary be more convenient as usigned char* buffer semantics? + - Should Binary be convertable to/from String, and if so how? + - as UTF8 encoded strings (making not like UUID<->String) + - as Base64 or Base96 encoded (making like UUID<->String) + - Conversions to std::string and LLUUID do not result in easy assignment + to std::string, LLString or LLUUID due to non-unique conversion paths +*/ + +#endif // LL_LLSD_NEW_H -- cgit v1.1