llsd.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:12k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llsd.h
  3.  * @brief LLSD flexible data system.
  4.  *
  5.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2005-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLSD_NEW_H
  33. #define LL_LLSD_NEW_H
  34. #include <map>
  35. #include <string>
  36. #include <vector>
  37. #include "stdtypes.h"
  38. #include "lldate.h"
  39. #include "lluri.h"
  40. #include "lluuid.h"
  41. /**
  42. LLSD provides a flexible data system similar to the data facilities of
  43. dynamic languages like Perl and Python.  It is created to support exchange
  44. of structured data between loosly coupled systems.  (Here, "loosly coupled"
  45. means not compiled together into the same module.)
  46. Data in such exchanges must be highly tollerant of changes on either side
  47. such as:
  48. - recompilation
  49. - implementation in a different langauge
  50. - addition of extra parameters
  51. - execution of older versions (with fewer parameters)
  52. To this aim, the C++ API of LLSD strives to be very easy to use, and to
  53. default to "the right thing" whereever possible.  It is extremely tollerant
  54. of errors and unexpected situations.
  55. The fundimental class is LLSD.  LLSD is a value holding object.  It holds
  56. one value that is either undefined, one of the scalar types, or a map or an
  57. array.  LLSD objects have value semantics (copying them copies the value,
  58. though it can be considered efficient, due to shareing.), and mutable.
  59. Undefined is the singular value given to LLSD objects that are not
  60. initialized with any data.  It is also used as the return value for
  61. operations that return an LLSD,
  62. The sclar data types are:
  63. - Boolean - true or false
  64. - Integer - a 32 bit signed integer
  65. - Real - a 64 IEEE 754 floating point value
  66. - UUID - a 128 unique value
  67. - String - a sequence of zero or more Unicode chracters
  68. - Date - an absolute point in time, UTC,
  69. with resolution to the second
  70. - URI - a String that is a URI
  71. - Binary - a sequence of zero or more octets (unsigned bytes)
  72. A map is a dictionary mapping String keys to LLSD values.  The keys are
  73. unique within a map, and have only one value (though that value could be
  74. an LLSD array).
  75. An array is a sequence of zero or more LLSD values.
  76. @nosubgrouping
  77. */
  78. class LL_COMMON_API LLSD
  79. {
  80. public:
  81. LLSD(); ///< initially Undefined
  82. ~LLSD(); ///< this class may NOT be subclassed
  83. /** @name Copyable and Assignable */
  84. //@{
  85. LLSD(const LLSD&);
  86. void assign(const LLSD& other);
  87. LLSD& operator=(const LLSD& other) { assign(other); return *this; }
  88. //@}
  89. void clear(); ///< resets to Undefined
  90. /** @name Scalar Types
  91.     The scalar types, and how they map onto C++
  92. */
  93. //@{
  94. typedef bool Boolean;
  95. typedef S32 Integer;
  96. typedef F64 Real;
  97. typedef std::string String;
  98. typedef LLUUID UUID;
  99. typedef LLDate Date;
  100. typedef LLURI URI;
  101. typedef std::vector<U8> Binary;
  102. //@}
  103. /** @name Scalar Constructors */
  104. //@{
  105. LLSD(Boolean);
  106. LLSD(Integer);
  107. LLSD(Real);
  108. LLSD(const String&);
  109. LLSD(const UUID&);
  110. LLSD(const Date&);
  111. LLSD(const URI&);
  112. LLSD(const Binary&);
  113. //@}
  114. /** @name Convenience Constructors */
  115. //@{
  116. LLSD(F32); // F32 -> Real
  117. //@}
  118. /** @name Scalar Assignment */
  119. //@{
  120. void assign(Boolean);
  121. void assign(Integer);
  122. void assign(Real);
  123. void assign(const String&);
  124. void assign(const UUID&);
  125. void assign(const Date&);
  126. void assign(const URI&);
  127. void assign(const Binary&);
  128. LLSD& operator=(Boolean v) { assign(v); return *this; }
  129. LLSD& operator=(Integer v) { assign(v); return *this; }
  130. LLSD& operator=(Real v) { assign(v); return *this; }
  131. LLSD& operator=(const String& v) { assign(v); return *this; }
  132. LLSD& operator=(const UUID& v) { assign(v); return *this; }
  133. LLSD& operator=(const Date& v) { assign(v); return *this; }
  134. LLSD& operator=(const URI& v) { assign(v); return *this; }
  135. LLSD& operator=(const Binary& v) { assign(v); return *this; }
  136. //@}
  137. /**
  138. @name Scalar Accessors
  139. @brief Fetch a scalar value, converting if needed and possible
  140. Conversion among the basic types, Boolean, Integer, Real and String, is
  141. fully defined.  Each type can be converted to another with a reasonable
  142. interpretation.  These conversions can be used as a convenience even
  143. when you know the data is in one format, but you want it in another.  Of
  144. course, many of these conversions lose information.
  145. Note: These conversions are not the same as Perl's.  In particular, when
  146. converting a String to a Boolean, only the empty string converts to
  147. false.  Converting the String "0" to Boolean results in true.
  148. Conversion to and from UUID, Date, and URI is only defined to and from
  149. String.  Conversion is defined to be information preserving for valid
  150. values of those types.  These conversions can be used when one needs to
  151. convert data to or from another system that cannot handle these types
  152. natively, but can handle strings.
  153. Conversion to and from Binary isn't defined.
  154. Conversion of the Undefined value to any scalar type results in a
  155. reasonable null or zero value for the type.
  156. */
  157. //@{
  158. Boolean asBoolean() const;
  159. Integer asInteger() const;
  160. Real asReal() const;
  161. String asString() const;
  162. UUID asUUID() const;
  163. Date asDate() const;
  164. URI asURI() const;
  165. Binary asBinary() const;
  166. operator Boolean() const { return asBoolean(); }
  167. operator Integer() const { return asInteger(); }
  168. operator Real() const { return asReal(); }
  169. operator String() const { return asString(); }
  170. operator UUID() const { return asUUID(); }
  171. operator Date() const { return asDate(); }
  172. operator URI() const { return asURI(); }
  173. operator Binary() const { return asBinary(); }
  174. // This is needed because most platforms do not automatically
  175. // convert the boolean negation as a bool in an if statement.
  176. bool operator!() const {return !asBoolean();}
  177. //@}
  178. /** @name Character Pointer Helpers
  179. These are helper routines to make working with char* the same as easy as
  180. working with strings.
  181.  */
  182. //@{
  183. LLSD(const char*);
  184. void assign(const char*);
  185. LLSD& operator=(const char* v) { assign(v); return *this; }
  186. //@}
  187. /** @name Map Values */
  188. //@{
  189. static LLSD emptyMap();
  190. bool has(const String&) const;
  191. LLSD get(const String&) const;
  192. void insert(const String&, const LLSD&);
  193. void erase(const String&);
  194. LLSD& with(const String&, const LLSD&);
  195. LLSD& operator[](const String&);
  196. LLSD& operator[](const char* c) { return (*this)[String(c)]; }
  197. const LLSD& operator[](const String&) const;
  198. const LLSD& operator[](const char* c) const { return (*this)[String(c)]; }
  199. //@}
  200. /** @name Array Values */
  201. //@{
  202. static LLSD emptyArray();
  203. LLSD get(Integer) const;
  204. void set(Integer, const LLSD&);
  205. void insert(Integer, const LLSD&);
  206. void append(const LLSD&);
  207. void erase(Integer);
  208. LLSD& with(Integer, const LLSD&);
  209. const LLSD& operator[](Integer) const;
  210. LLSD& operator[](Integer);
  211. //@}
  212. /** @name Iterators */
  213. //@{
  214. int size() const;
  215. typedef std::map<String, LLSD>::iterator map_iterator;
  216. typedef std::map<String, LLSD>::const_iterator map_const_iterator;
  217. map_iterator beginMap();
  218. map_iterator endMap();
  219. map_const_iterator beginMap() const;
  220. map_const_iterator endMap() const;
  221. typedef std::vector<LLSD>::iterator array_iterator;
  222. typedef std::vector<LLSD>::const_iterator array_const_iterator;
  223. array_iterator beginArray();
  224. array_iterator endArray();
  225. array_const_iterator beginArray() const;
  226. array_const_iterator endArray() const;
  227. //@}
  228. /** @name Type Testing */
  229. //@{
  230. enum Type {
  231. TypeUndefined,
  232. TypeBoolean,
  233. TypeInteger,
  234. TypeReal,
  235. TypeString,
  236. TypeUUID,
  237. TypeDate,
  238. TypeURI,
  239. TypeBinary,
  240. TypeMap,
  241. TypeArray
  242. };
  243. Type type() const;
  244. bool isUndefined() const { return type() == TypeUndefined; }
  245. bool isDefined() const { return type() != TypeUndefined; }
  246. bool isBoolean() const { return type() == TypeBoolean; }
  247. bool isInteger() const { return type() == TypeInteger; }
  248. bool isReal() const { return type() == TypeReal; }
  249. bool isString() const { return type() == TypeString; }
  250. bool isUUID() const { return type() == TypeUUID; }
  251. bool isDate() const { return type() == TypeDate; }
  252. bool isURI() const { return type() == TypeURI; }
  253. bool isBinary() const { return type() == TypeBinary; }
  254. bool isMap() const { return type() == TypeMap; }
  255. bool isArray() const { return type() == TypeArray; }
  256. //@}
  257. /** @name Automatic Cast Protection
  258. These are not implemented on purpose.  Without them, C++ can perform
  259. some conversions that are clearly not what the programmer intended.
  260. If you get a linker error about these being missing, you have made
  261. mistake in your code.  DO NOT IMPLEMENT THESE FUNCTIONS as a fix.
  262. All of thse problems stem from trying to support char* in LLSD or in
  263. std::string.  There are too many automatic casts that will lead to
  264. using an arbitrary pointer or scalar type to std::string.
  265.  */
  266. //@{
  267. LLSD(const void*); ///< construct from aribrary pointers
  268. void assign(const void*); ///< assign from arbitrary pointers
  269. LLSD& operator=(const void*); ///< assign from arbitrary pointers
  270. bool has(Integer) const; ///< has only works for Maps
  271. //@}
  272. /** @name Implementation */
  273. //@{
  274. public:
  275. class Impl;
  276. private:
  277. Impl* impl;
  278. //@}
  279. /** @name Unit Testing Interface */
  280. //@{
  281. public:
  282. static U32 allocationCount(); ///< how many Impls have been made
  283. static U32 outstandingCount(); ///< how many Impls are still alive
  284. //@}
  285. private:
  286. /** @name Debugging Interface */
  287. //@{
  288. /// Returns XML version of llsd -- only to be called from debugger
  289. static const char *dumpXML(const LLSD &llsd);
  290. /// Returns Notation version of llsd -- only to be called from debugger
  291. static const char *dump(const LLSD &llsd);
  292. //@}
  293. };
  294. struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean>
  295. {
  296. LLSD::Boolean operator()(const LLSD& sd) const
  297. {
  298. return sd.asBoolean();
  299. }
  300. };
  301. struct llsd_select_integer : public std::unary_function<LLSD, LLSD::Integer>
  302. {
  303. LLSD::Integer operator()(const LLSD& sd) const
  304. {
  305. return sd.asInteger();
  306. }
  307. };
  308. struct llsd_select_real : public std::unary_function<LLSD, LLSD::Real>
  309. {
  310. LLSD::Real operator()(const LLSD& sd) const
  311. {
  312. return sd.asReal();
  313. }
  314. };
  315. struct llsd_select_float : public std::unary_function<LLSD, F32>
  316. {
  317. F32 operator()(const LLSD& sd) const
  318. {
  319. return (F32)sd.asReal();
  320. }
  321. };
  322. struct llsd_select_uuid : public std::unary_function<LLSD, LLSD::UUID>
  323. {
  324. LLSD::UUID operator()(const LLSD& sd) const
  325. {
  326. return sd.asUUID();
  327. }
  328. };
  329. struct llsd_select_string : public std::unary_function<LLSD, LLSD::String>
  330. {
  331. LLSD::String operator()(const LLSD& sd) const
  332. {
  333. return sd.asString();
  334. }
  335. };
  336. LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd);
  337. /** QUESTIONS & TO DOS
  338. - Would Binary be more convenient as usigned char* buffer semantics?
  339. - Should Binary be convertable to/from String, and if so how?
  340. - as UTF8 encoded strings (making not like UUID<->String)
  341. - as Base64 or Base96 encoded (making like UUID<->String)
  342. - Conversions to std::string and LLUUID do not result in easy assignment
  343. to std::string, std::string or LLUUID due to non-unique conversion paths
  344. */
  345. #endif // LL_LLSD_NEW_H