diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llsd.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llcommon/llsd.cpp')
-rw-r--r-- | linden/indra/llcommon/llsd.cpp | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llsd.cpp b/linden/indra/llcommon/llsd.cpp new file mode 100644 index 0000000..7a0ff9d --- /dev/null +++ b/linden/indra/llcommon/llsd.cpp | |||
@@ -0,0 +1,750 @@ | |||
1 | /** | ||
2 | * @file llsd.cpp | ||
3 | * @brief LLSD flexible data system | ||
4 | * | ||
5 | * Copyright (c) 2005-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llsd.h" | ||
29 | |||
30 | #include <math.h> | ||
31 | #include "../llmath/llmath.h" | ||
32 | |||
33 | namespace { | ||
34 | class ImplMap; | ||
35 | class ImplArray; | ||
36 | } | ||
37 | |||
38 | class LLSD::Impl | ||
39 | /**< This class is the abstract base class of the implementation of LLSD | ||
40 | It provides the reference counting implementation, and the default | ||
41 | implementation of most methods for most data types. It also serves | ||
42 | as a working implementation of the Undefined type. | ||
43 | |||
44 | */ | ||
45 | { | ||
46 | private: | ||
47 | U32 mUseCount; | ||
48 | |||
49 | protected: | ||
50 | Impl(); | ||
51 | |||
52 | enum StaticAllocationMarker { STATIC }; | ||
53 | Impl(StaticAllocationMarker); | ||
54 | ///< This constructor is used for static objects and causes the | ||
55 | // suppresses adjusting the debugging counters when they are | ||
56 | // finally initialized. | ||
57 | |||
58 | virtual ~Impl(); | ||
59 | |||
60 | bool shared() const { return mUseCount > 1; } | ||
61 | |||
62 | public: | ||
63 | static void reset(Impl*& var, Impl* impl); | ||
64 | ///< safely set var to refer to the new impl (possibly shared) | ||
65 | |||
66 | static Impl& safe( Impl*); | ||
67 | static const Impl& safe(const Impl*); | ||
68 | ///< since a NULL Impl* is used for undefined, this ensures there is | ||
69 | // always an object you call virtual member functions on | ||
70 | |||
71 | virtual ImplMap& makeMap(Impl*& var); | ||
72 | virtual ImplArray& makeArray(Impl*& var); | ||
73 | ///< sure var is a modifiable, non-shared map or array | ||
74 | |||
75 | virtual LLSD::Type type() const { return LLSD::TypeUndefined; } | ||
76 | |||
77 | static void assignUndefined(LLSD::Impl*& var); | ||
78 | static void assign(LLSD::Impl*& var, const LLSD::Impl* other); | ||
79 | |||
80 | virtual void assign(Impl*& var, LLSD::Boolean); | ||
81 | virtual void assign(Impl*& var, LLSD::Integer); | ||
82 | virtual void assign(Impl*& var, LLSD::Real); | ||
83 | virtual void assign(Impl*& var, const LLSD::String&); | ||
84 | virtual void assign(Impl*& var, const LLSD::UUID&); | ||
85 | virtual void assign(Impl*& var, const LLSD::Date&); | ||
86 | virtual void assign(Impl*& var, const LLSD::URI&); | ||
87 | virtual void assign(Impl*& var, const LLSD::Binary&); | ||
88 | ///< If the receiver is the right type and unshared, these are simple | ||
89 | // data assignments, othewise the default implementation handless | ||
90 | // constructing the proper Impl subclass | ||
91 | |||
92 | virtual Boolean asBoolean() const { return false; } | ||
93 | virtual Integer asInteger() const { return 0; } | ||
94 | virtual Real asReal() const { return 0.0; } | ||
95 | virtual String asString() const { return std::string(); } | ||
96 | virtual UUID asUUID() const { return LLUUID(); } | ||
97 | virtual Date asDate() const { return LLDate(); } | ||
98 | virtual URI asURI() const { return LLURI(); } | ||
99 | virtual Binary asBinary() const { return std::vector<U8>(); } | ||
100 | |||
101 | virtual bool has(const String&) const { return false; } | ||
102 | virtual LLSD get(const String&) const { return LLSD(); } | ||
103 | virtual void erase(const String&) { } | ||
104 | virtual const LLSD& ref(const String&) const{ return undef(); } | ||
105 | |||
106 | virtual int size() const { return 0; } | ||
107 | virtual LLSD get(Integer) const { return LLSD(); } | ||
108 | virtual void erase(Integer) { } | ||
109 | virtual const LLSD& ref(Integer) const { return undef(); } | ||
110 | |||
111 | virtual LLSD::map_const_iterator beginMap() const { return LLSD::map_const_iterator(); } | ||
112 | virtual LLSD::map_const_iterator endMap() const { return LLSD::map_const_iterator(); } | ||
113 | virtual LLSD::array_const_iterator beginArray() const { return LLSD::array_const_iterator(); } | ||
114 | virtual LLSD::array_const_iterator endArray() const { return LLSD::array_const_iterator(); } | ||
115 | |||
116 | static const LLSD& undef(); | ||
117 | |||
118 | static U32 sAllocationCount; | ||
119 | static U32 sOutstandingCount; | ||
120 | }; | ||
121 | |||
122 | namespace { | ||
123 | template<LLSD::Type T, class Data, class DataRef = Data> | ||
124 | class ImplBase : public LLSD::Impl | ||
125 | ///< This class handles most of the work for a subclass of Impl | ||
126 | // for a given simple data type. Subclasses of this provide the | ||
127 | // conversion functions and a constructor. | ||
128 | { | ||
129 | protected: | ||
130 | Data mValue; | ||
131 | |||
132 | typedef ImplBase Base; | ||
133 | |||
134 | public: | ||
135 | ImplBase(DataRef value) : mValue(value) { } | ||
136 | |||
137 | virtual LLSD::Type type() const { return T; } | ||
138 | |||
139 | virtual void assign(LLSD::Impl*& var, DataRef value) { | ||
140 | if (shared()) | ||
141 | { | ||
142 | Impl::assign(var, value); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | mValue = value; | ||
147 | } | ||
148 | } | ||
149 | }; | ||
150 | |||
151 | |||
152 | class ImplBoolean | ||
153 | : public ImplBase<LLSD::TypeBoolean, LLSD::Boolean> | ||
154 | { | ||
155 | public: | ||
156 | ImplBoolean(LLSD::Boolean v) : Base(v) { } | ||
157 | |||
158 | virtual LLSD::Boolean asBoolean() const { return mValue; } | ||
159 | virtual LLSD::Integer asInteger() const { return mValue ? 1 : 0; } | ||
160 | virtual LLSD::Real asReal() const { return mValue ? 1 : 0; } | ||
161 | virtual LLSD::String asString() const; | ||
162 | }; | ||
163 | |||
164 | LLSD::String ImplBoolean::asString() const | ||
165 | { return mValue ? "true" : ""; } | ||
166 | |||
167 | |||
168 | class ImplInteger | ||
169 | : public ImplBase<LLSD::TypeInteger, LLSD::Integer> | ||
170 | { | ||
171 | public: | ||
172 | ImplInteger(LLSD::Integer v) : Base(v) { } | ||
173 | |||
174 | virtual LLSD::Boolean asBoolean() const { return mValue != 0; } | ||
175 | virtual LLSD::Integer asInteger() const { return mValue; } | ||
176 | virtual LLSD::Real asReal() const { return mValue; } | ||
177 | virtual LLSD::String asString() const; | ||
178 | }; | ||
179 | |||
180 | LLSD::String ImplInteger::asString() const | ||
181 | { return llformat("%d", mValue); } | ||
182 | |||
183 | |||
184 | class ImplReal | ||
185 | : public ImplBase<LLSD::TypeReal, LLSD::Real> | ||
186 | { | ||
187 | public: | ||
188 | ImplReal(LLSD::Real v) : Base(v) { } | ||
189 | |||
190 | virtual LLSD::Boolean asBoolean() const; | ||
191 | virtual LLSD::Integer asInteger() const; | ||
192 | virtual LLSD::Real asReal() const { return mValue; } | ||
193 | virtual LLSD::String asString() const; | ||
194 | }; | ||
195 | |||
196 | LLSD::Boolean ImplReal::asBoolean() const | ||
197 | { return !llisnan(mValue) && mValue != 0.0; } | ||
198 | |||
199 | LLSD::Integer ImplReal::asInteger() const | ||
200 | { return !llisnan(mValue) ? (LLSD::Integer)mValue : 0; } | ||
201 | |||
202 | LLSD::String ImplReal::asString() const | ||
203 | { return llformat("%lg", mValue); } | ||
204 | |||
205 | |||
206 | class ImplString | ||
207 | : public ImplBase<LLSD::TypeString, LLSD::String, const LLSD::String&> | ||
208 | { | ||
209 | public: | ||
210 | ImplString(const LLSD::String& v) : Base(v) { } | ||
211 | |||
212 | virtual LLSD::Boolean asBoolean() const { return !mValue.empty(); } | ||
213 | virtual LLSD::Integer asInteger() const; | ||
214 | virtual LLSD::Real asReal() const; | ||
215 | virtual LLSD::String asString() const { return mValue; } | ||
216 | virtual LLSD::UUID asUUID() const { return LLUUID(mValue); } | ||
217 | virtual LLSD::Date asDate() const { return LLDate(mValue); } | ||
218 | virtual LLSD::URI asURI() const { return LLURI(mValue); } | ||
219 | }; | ||
220 | |||
221 | LLSD::Integer ImplString::asInteger() const | ||
222 | { | ||
223 | // This must treat "1.23" not as an error, but as a number, which is | ||
224 | // then truncated down to an integer. Hence, this code doesn't call | ||
225 | // std::istringstream::operator>>(int&), which would not consume the | ||
226 | // ".23" portion. | ||
227 | |||
228 | return (int)asReal(); | ||
229 | } | ||
230 | |||
231 | LLSD::Real ImplString::asReal() const | ||
232 | { | ||
233 | F64 v = 0.0; | ||
234 | std::istringstream i_stream(mValue); | ||
235 | i_stream >> v; | ||
236 | |||
237 | // we would probably like to ignore all trailing whitespace as | ||
238 | // well, but for now, simply eat the next character, and make | ||
239 | // sure we reached the end of the string. | ||
240 | // *NOTE: gcc 2.95 does not generate an eof() event on the | ||
241 | // stream operation above, so we manually get here to force it | ||
242 | // across platforms. | ||
243 | int c = i_stream.get(); | ||
244 | return ((EOF ==c) ? v : 0.0); | ||
245 | } | ||
246 | |||
247 | |||
248 | class ImplUUID | ||
249 | : public ImplBase<LLSD::TypeUUID, LLSD::UUID, const LLSD::UUID&> | ||
250 | { | ||
251 | public: | ||
252 | ImplUUID(const LLSD::UUID& v) : Base(v) { } | ||
253 | |||
254 | virtual LLSD::String asString() const{ return mValue.getString(); } | ||
255 | virtual LLSD::UUID asUUID() const { return mValue; } | ||
256 | }; | ||
257 | |||
258 | |||
259 | class ImplDate | ||
260 | : public ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&> | ||
261 | { | ||
262 | public: | ||
263 | ImplDate(const LLSD::Date& v) | ||
264 | : ImplBase<LLSD::TypeDate, LLSD::Date, const LLSD::Date&>(v) | ||
265 | { } | ||
266 | |||
267 | virtual LLSD::Integer asInteger() const | ||
268 | { | ||
269 | return (LLSD::Integer)(mValue.secondsSinceEpoch()); | ||
270 | } | ||
271 | virtual LLSD::Real asReal() const | ||
272 | { | ||
273 | return mValue.secondsSinceEpoch(); | ||
274 | } | ||
275 | virtual LLSD::String asString() const{ return mValue.asString(); } | ||
276 | virtual LLSD::Date asDate() const { return mValue; } | ||
277 | }; | ||
278 | |||
279 | |||
280 | class ImplURI | ||
281 | : public ImplBase<LLSD::TypeURI, LLSD::URI, const LLSD::URI&> | ||
282 | { | ||
283 | public: | ||
284 | ImplURI(const LLSD::URI& v) : Base(v) { } | ||
285 | |||
286 | virtual LLSD::String asString() const{ return mValue.asString(); } | ||
287 | virtual LLSD::URI asURI() const { return mValue; } | ||
288 | }; | ||
289 | |||
290 | |||
291 | class ImplBinary | ||
292 | : public ImplBase<LLSD::TypeBinary, LLSD::Binary, const LLSD::Binary&> | ||
293 | { | ||
294 | public: | ||
295 | ImplBinary(const LLSD::Binary& v) : Base(v) { } | ||
296 | |||
297 | virtual LLSD::Binary asBinary() const{ return mValue; } | ||
298 | }; | ||
299 | |||
300 | |||
301 | class ImplMap : public LLSD::Impl | ||
302 | { | ||
303 | private: | ||
304 | typedef std::map<LLSD::String, LLSD> DataMap; | ||
305 | |||
306 | DataMap mData; | ||
307 | |||
308 | protected: | ||
309 | ImplMap(const DataMap& data) : mData(data) { } | ||
310 | |||
311 | public: | ||
312 | ImplMap() { } | ||
313 | |||
314 | virtual ImplMap& makeMap(LLSD::Impl*&); | ||
315 | |||
316 | virtual LLSD::Type type() const { return LLSD::TypeMap; } | ||
317 | |||
318 | virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } | ||
319 | |||
320 | virtual bool has(const LLSD::String&) const; | ||
321 | virtual LLSD get(const LLSD::String&) const; | ||
322 | void insert(const LLSD::String& k, const LLSD& v); | ||
323 | virtual void erase(const LLSD::String&); | ||
324 | LLSD& ref(const LLSD::String&); | ||
325 | virtual const LLSD& ref(const LLSD::String&) const; | ||
326 | |||
327 | virtual int size() const { return mData.size(); } | ||
328 | |||
329 | LLSD::map_iterator beginMap() { return mData.begin(); } | ||
330 | LLSD::map_iterator endMap() { return mData.end(); } | ||
331 | virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); } | ||
332 | virtual LLSD::map_const_iterator endMap() const { return mData.end(); } | ||
333 | }; | ||
334 | |||
335 | ImplMap& ImplMap::makeMap(LLSD::Impl*& var) | ||
336 | { | ||
337 | if (shared()) | ||
338 | { | ||
339 | ImplMap* i = new ImplMap(mData); | ||
340 | Impl::assign(var, i); | ||
341 | return *i; | ||
342 | } | ||
343 | else | ||
344 | { | ||
345 | return *this; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | bool ImplMap::has(const LLSD::String& k) const | ||
350 | { | ||
351 | DataMap::const_iterator i = mData.find(k); | ||
352 | return i != mData.end(); | ||
353 | } | ||
354 | |||
355 | LLSD ImplMap::get(const LLSD::String& k) const | ||
356 | { | ||
357 | DataMap::const_iterator i = mData.find(k); | ||
358 | return (i != mData.end()) ? i->second : LLSD(); | ||
359 | } | ||
360 | |||
361 | void ImplMap::insert(const LLSD::String& k, const LLSD& v) | ||
362 | { | ||
363 | mData.insert(DataMap::value_type(k, v)); | ||
364 | } | ||
365 | |||
366 | void ImplMap::erase(const LLSD::String& k) | ||
367 | { | ||
368 | mData.erase(k); | ||
369 | } | ||
370 | |||
371 | LLSD& ImplMap::ref(const LLSD::String& k) | ||
372 | { | ||
373 | return mData[k]; | ||
374 | } | ||
375 | |||
376 | const LLSD& ImplMap::ref(const LLSD::String& k) const | ||
377 | { | ||
378 | DataMap::const_iterator i = mData.lower_bound(k); | ||
379 | if (i == mData.end() || mData.key_comp()(k, i->first)) | ||
380 | { | ||
381 | return undef(); | ||
382 | } | ||
383 | |||
384 | return i->second; | ||
385 | } | ||
386 | |||
387 | class ImplArray : public LLSD::Impl | ||
388 | { | ||
389 | private: | ||
390 | typedef std::vector<LLSD> DataVector; | ||
391 | |||
392 | DataVector mData; | ||
393 | |||
394 | protected: | ||
395 | ImplArray(const DataVector& data) : mData(data) { } | ||
396 | |||
397 | public: | ||
398 | ImplArray() { } | ||
399 | |||
400 | virtual ImplArray& makeArray(Impl*&); | ||
401 | |||
402 | virtual LLSD::Type type() const { return LLSD::TypeArray; } | ||
403 | |||
404 | virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } | ||
405 | |||
406 | virtual int size() const; | ||
407 | virtual LLSD get(LLSD::Integer) const; | ||
408 | void set(LLSD::Integer, const LLSD&); | ||
409 | void insert(LLSD::Integer, const LLSD&); | ||
410 | void append(const LLSD&); | ||
411 | virtual void erase(LLSD::Integer); | ||
412 | LLSD& ref(LLSD::Integer); | ||
413 | virtual const LLSD& ref(LLSD::Integer) const; | ||
414 | |||
415 | LLSD::array_iterator beginArray() { return mData.begin(); } | ||
416 | LLSD::array_iterator endArray() { return mData.end(); } | ||
417 | virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); } | ||
418 | virtual LLSD::array_const_iterator endArray() const { return mData.end(); } | ||
419 | }; | ||
420 | |||
421 | ImplArray& ImplArray::makeArray(Impl*& var) | ||
422 | { | ||
423 | if (shared()) | ||
424 | { | ||
425 | ImplArray* i = new ImplArray(mData); | ||
426 | Impl::assign(var, i); | ||
427 | return *i; | ||
428 | } | ||
429 | else | ||
430 | { | ||
431 | return *this; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | int ImplArray::size() const { return mData.size(); } | ||
436 | |||
437 | LLSD ImplArray::get(LLSD::Integer i) const | ||
438 | { | ||
439 | if (i < 0) { return LLSD(); } | ||
440 | DataVector::size_type index = i; | ||
441 | |||
442 | return (index < mData.size()) ? mData[index] : LLSD(); | ||
443 | } | ||
444 | |||
445 | void ImplArray::set(LLSD::Integer i, const LLSD& v) | ||
446 | { | ||
447 | if (i < 0) { return; } | ||
448 | DataVector::size_type index = i; | ||
449 | |||
450 | if (index >= mData.size()) | ||
451 | { | ||
452 | mData.resize(index + 1); | ||
453 | } | ||
454 | |||
455 | mData[index] = v; | ||
456 | } | ||
457 | |||
458 | void ImplArray::insert(LLSD::Integer i, const LLSD& v) | ||
459 | { | ||
460 | if (i < 0) { return; } | ||
461 | DataVector::size_type index = i; | ||
462 | |||
463 | if (index >= mData.size()) | ||
464 | { | ||
465 | mData.resize(index + 1); | ||
466 | } | ||
467 | |||
468 | mData.insert(mData.begin() + index, v); | ||
469 | } | ||
470 | |||
471 | void ImplArray::append(const LLSD& v) | ||
472 | { | ||
473 | mData.push_back(v); | ||
474 | } | ||
475 | |||
476 | void ImplArray::erase(LLSD::Integer i) | ||
477 | { | ||
478 | if (i < 0) { return; } | ||
479 | DataVector::size_type index = i; | ||
480 | |||
481 | if (index < mData.size()) | ||
482 | { | ||
483 | mData.erase(mData.begin() + index); | ||
484 | } | ||
485 | } | ||
486 | |||
487 | LLSD& ImplArray::ref(LLSD::Integer i) | ||
488 | { | ||
489 | DataVector::size_type index = i >= 0 ? i : 0; | ||
490 | |||
491 | if (index >= mData.size()) | ||
492 | { | ||
493 | mData.resize(i + 1); | ||
494 | } | ||
495 | |||
496 | return mData[index]; | ||
497 | } | ||
498 | |||
499 | const LLSD& ImplArray::ref(LLSD::Integer i) const | ||
500 | { | ||
501 | if (i < 0) { return undef(); } | ||
502 | DataVector::size_type index = i; | ||
503 | |||
504 | if (index >= mData.size()) | ||
505 | { | ||
506 | return undef(); | ||
507 | } | ||
508 | |||
509 | return mData[index]; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | LLSD::Impl::Impl() | ||
514 | : mUseCount(0) | ||
515 | { | ||
516 | ++sAllocationCount; | ||
517 | ++sOutstandingCount; | ||
518 | } | ||
519 | |||
520 | LLSD::Impl::Impl(StaticAllocationMarker) | ||
521 | : mUseCount(0) | ||
522 | { | ||
523 | } | ||
524 | |||
525 | LLSD::Impl::~Impl() | ||
526 | { | ||
527 | --sOutstandingCount; | ||
528 | } | ||
529 | |||
530 | void LLSD::Impl::reset(Impl*& var, Impl* impl) | ||
531 | { | ||
532 | if (impl) ++impl->mUseCount; | ||
533 | if (var && --var->mUseCount == 0) | ||
534 | { | ||
535 | delete var; | ||
536 | } | ||
537 | var = impl; | ||
538 | } | ||
539 | |||
540 | LLSD::Impl& LLSD::Impl::safe(Impl* impl) | ||
541 | { | ||
542 | static Impl theUndefined(STATIC); | ||
543 | return impl ? *impl : theUndefined; | ||
544 | } | ||
545 | |||
546 | const LLSD::Impl& LLSD::Impl::safe(const Impl* impl) | ||
547 | { | ||
548 | static Impl theUndefined(STATIC); | ||
549 | return impl ? *impl : theUndefined; | ||
550 | } | ||
551 | |||
552 | ImplMap& LLSD::Impl::makeMap(Impl*& var) | ||
553 | { | ||
554 | ImplMap* im = new ImplMap; | ||
555 | reset(var, im); | ||
556 | return *im; | ||
557 | } | ||
558 | |||
559 | ImplArray& LLSD::Impl::makeArray(Impl*& var) | ||
560 | { | ||
561 | ImplArray* ia = new ImplArray; | ||
562 | reset(var, ia); | ||
563 | return *ia; | ||
564 | } | ||
565 | |||
566 | |||
567 | void LLSD::Impl::assign(Impl*& var, const Impl* other) | ||
568 | { | ||
569 | reset(var, const_cast<Impl*>(other)); | ||
570 | } | ||
571 | |||
572 | void LLSD::Impl::assignUndefined(Impl*& var) | ||
573 | { | ||
574 | reset(var, 0); | ||
575 | } | ||
576 | |||
577 | void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v) | ||
578 | { | ||
579 | reset(var, new ImplBoolean(v)); | ||
580 | } | ||
581 | |||
582 | void LLSD::Impl::assign(Impl*& var, LLSD::Integer v) | ||
583 | { | ||
584 | reset(var, new ImplInteger(v)); | ||
585 | } | ||
586 | |||
587 | void LLSD::Impl::assign(Impl*& var, LLSD::Real v) | ||
588 | { | ||
589 | reset(var, new ImplReal(v)); | ||
590 | } | ||
591 | |||
592 | void LLSD::Impl::assign(Impl*& var, const LLSD::String& v) | ||
593 | { | ||
594 | reset(var, new ImplString(v)); | ||
595 | } | ||
596 | |||
597 | void LLSD::Impl::assign(Impl*& var, const LLSD::UUID& v) | ||
598 | { | ||
599 | reset(var, new ImplUUID(v)); | ||
600 | } | ||
601 | |||
602 | void LLSD::Impl::assign(Impl*& var, const LLSD::Date& v) | ||
603 | { | ||
604 | reset(var, new ImplDate(v)); | ||
605 | } | ||
606 | |||
607 | void LLSD::Impl::assign(Impl*& var, const LLSD::URI& v) | ||
608 | { | ||
609 | reset(var, new ImplURI(v)); | ||
610 | } | ||
611 | |||
612 | void LLSD::Impl::assign(Impl*& var, const LLSD::Binary& v) | ||
613 | { | ||
614 | reset(var, new ImplBinary(v)); | ||
615 | } | ||
616 | |||
617 | |||
618 | const LLSD& LLSD::Impl::undef() | ||
619 | { | ||
620 | static const LLSD immutableUndefined; | ||
621 | return immutableUndefined; | ||
622 | } | ||
623 | |||
624 | U32 LLSD::Impl::sAllocationCount = 0; | ||
625 | U32 LLSD::Impl::sOutstandingCount = 0; | ||
626 | |||
627 | |||
628 | |||
629 | namespace { | ||
630 | inline LLSD::Impl& safe(LLSD::Impl* impl) | ||
631 | { return LLSD::Impl::safe(impl); } | ||
632 | |||
633 | inline const LLSD::Impl& safe(const LLSD::Impl* impl) | ||
634 | { return LLSD::Impl::safe(impl); } | ||
635 | |||
636 | inline ImplMap& makeMap(LLSD::Impl*& var) | ||
637 | { return safe(var).makeMap(var); } | ||
638 | |||
639 | inline ImplArray& makeArray(LLSD::Impl*& var) | ||
640 | { return safe(var).makeArray(var); } | ||
641 | } | ||
642 | |||
643 | |||
644 | LLSD::LLSD() : impl(0) { } | ||
645 | LLSD::~LLSD() { Impl::reset(impl, 0); } | ||
646 | |||
647 | LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); } | ||
648 | void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); } | ||
649 | |||
650 | |||
651 | void LLSD::clear() { Impl::assignUndefined(impl); } | ||
652 | |||
653 | LLSD::Type LLSD::type() const { return safe(impl).type(); } | ||
654 | |||
655 | // Scaler Constructors | ||
656 | LLSD::LLSD(Boolean v) : impl(0) { assign(v); } | ||
657 | LLSD::LLSD(Integer v) : impl(0) { assign(v); } | ||
658 | LLSD::LLSD(Real v) : impl(0) { assign(v); } | ||
659 | LLSD::LLSD(const UUID& v) : impl(0) { assign(v); } | ||
660 | LLSD::LLSD(const String& v) : impl(0) { assign(v); } | ||
661 | LLSD::LLSD(const Date& v) : impl(0) { assign(v); } | ||
662 | LLSD::LLSD(const URI& v) : impl(0) { assign(v); } | ||
663 | LLSD::LLSD(const Binary& v) : impl(0) { assign(v); } | ||
664 | |||
665 | // Convenience Constructors | ||
666 | LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); } | ||
667 | |||
668 | // Scalar Assignment | ||
669 | void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); } | ||
670 | void LLSD::assign(Integer v) { safe(impl).assign(impl, v); } | ||
671 | void LLSD::assign(Real v) { safe(impl).assign(impl, v); } | ||
672 | void LLSD::assign(const String& v) { safe(impl).assign(impl, v); } | ||
673 | void LLSD::assign(const UUID& v) { safe(impl).assign(impl, v); } | ||
674 | void LLSD::assign(const Date& v) { safe(impl).assign(impl, v); } | ||
675 | void LLSD::assign(const URI& v) { safe(impl).assign(impl, v); } | ||
676 | void LLSD::assign(const Binary& v) { safe(impl).assign(impl, v); } | ||
677 | |||
678 | // Scalar Accessors | ||
679 | LLSD::Boolean LLSD::asBoolean() const { return safe(impl).asBoolean(); } | ||
680 | LLSD::Integer LLSD::asInteger() const { return safe(impl).asInteger(); } | ||
681 | LLSD::Real LLSD::asReal() const { return safe(impl).asReal(); } | ||
682 | LLSD::String LLSD::asString() const { return safe(impl).asString(); } | ||
683 | LLSD::UUID LLSD::asUUID() const { return safe(impl).asUUID(); } | ||
684 | LLSD::Date LLSD::asDate() const { return safe(impl).asDate(); } | ||
685 | LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); } | ||
686 | LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); } | ||
687 | |||
688 | // const char * helpers | ||
689 | LLSD::LLSD(const char* v) : impl(0) { assign(v); } | ||
690 | void LLSD::assign(const char* v) | ||
691 | { | ||
692 | if(v) assign(std::string(v)); | ||
693 | else assign(std::string()); | ||
694 | } | ||
695 | |||
696 | |||
697 | LLSD LLSD::emptyMap() | ||
698 | { | ||
699 | LLSD v; | ||
700 | makeMap(v.impl); | ||
701 | return v; | ||
702 | } | ||
703 | |||
704 | bool LLSD::has(const String& k) const { return safe(impl).has(k); } | ||
705 | LLSD LLSD::get(const String& k) const { return safe(impl).get(k); } | ||
706 | |||
707 | void LLSD::insert(const String& k, const LLSD& v) | ||
708 | { makeMap(impl).insert(k, v); } | ||
709 | void LLSD::erase(const String& k) { makeMap(impl).erase(k); } | ||
710 | |||
711 | LLSD& LLSD::operator[](const String& k) | ||
712 | { return makeMap(impl).ref(k); } | ||
713 | const LLSD& LLSD::operator[](const String& k) const | ||
714 | { return safe(impl).ref(k); } | ||
715 | |||
716 | |||
717 | LLSD LLSD::emptyArray() | ||
718 | { | ||
719 | LLSD v; | ||
720 | makeArray(v.impl); | ||
721 | return v; | ||
722 | } | ||
723 | |||
724 | int LLSD::size() const { return safe(impl).size(); } | ||
725 | |||
726 | LLSD LLSD::get(Integer i) const { return safe(impl).get(i); } | ||
727 | void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); } | ||
728 | |||
729 | void LLSD::insert(Integer i, const LLSD& v) | ||
730 | { makeArray(impl).insert(i, v); } | ||
731 | void LLSD::append(const LLSD& v) { makeArray(impl).append(v); } | ||
732 | void LLSD::erase(Integer i) { makeArray(impl).erase(i); } | ||
733 | |||
734 | LLSD& LLSD::operator[](Integer i) | ||
735 | { return makeArray(impl).ref(i); } | ||
736 | const LLSD& LLSD::operator[](Integer i) const | ||
737 | { return safe(impl).ref(i); } | ||
738 | |||
739 | U32 LLSD::allocationCount() { return Impl::sAllocationCount; } | ||
740 | U32 LLSD::outstandingCount() { return Impl::sOutstandingCount; } | ||
741 | |||
742 | LLSD::map_iterator LLSD::beginMap() { return makeMap(impl).beginMap(); } | ||
743 | LLSD::map_iterator LLSD::endMap() { return makeMap(impl).endMap(); } | ||
744 | LLSD::map_const_iterator LLSD::beginMap() const { return safe(impl).beginMap(); } | ||
745 | LLSD::map_const_iterator LLSD::endMap() const { return safe(impl).endMap(); } | ||
746 | |||
747 | LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray(); } | ||
748 | LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); } | ||
749 | LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); } | ||
750 | LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); } | ||