aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llsd.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llsd.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp750
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
33namespace {
34 class ImplMap;
35 class ImplArray;
36}
37
38class 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{
46private:
47 U32 mUseCount;
48
49protected:
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
62public:
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
122namespace {
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
513LLSD::Impl::Impl()
514 : mUseCount(0)
515{
516 ++sAllocationCount;
517 ++sOutstandingCount;
518}
519
520LLSD::Impl::Impl(StaticAllocationMarker)
521 : mUseCount(0)
522{
523}
524
525LLSD::Impl::~Impl()
526{
527 --sOutstandingCount;
528}
529
530void 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
540LLSD::Impl& LLSD::Impl::safe(Impl* impl)
541{
542 static Impl theUndefined(STATIC);
543 return impl ? *impl : theUndefined;
544}
545
546const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
547{
548 static Impl theUndefined(STATIC);
549 return impl ? *impl : theUndefined;
550}
551
552ImplMap& LLSD::Impl::makeMap(Impl*& var)
553{
554 ImplMap* im = new ImplMap;
555 reset(var, im);
556 return *im;
557}
558
559ImplArray& LLSD::Impl::makeArray(Impl*& var)
560{
561 ImplArray* ia = new ImplArray;
562 reset(var, ia);
563 return *ia;
564}
565
566
567void LLSD::Impl::assign(Impl*& var, const Impl* other)
568{
569 reset(var, const_cast<Impl*>(other));
570}
571
572void LLSD::Impl::assignUndefined(Impl*& var)
573{
574 reset(var, 0);
575}
576
577void LLSD::Impl::assign(Impl*& var, LLSD::Boolean v)
578{
579 reset(var, new ImplBoolean(v));
580}
581
582void LLSD::Impl::assign(Impl*& var, LLSD::Integer v)
583{
584 reset(var, new ImplInteger(v));
585}
586
587void LLSD::Impl::assign(Impl*& var, LLSD::Real v)
588{
589 reset(var, new ImplReal(v));
590}
591
592void LLSD::Impl::assign(Impl*& var, const LLSD::String& v)
593{
594 reset(var, new ImplString(v));
595}
596
597void LLSD::Impl::assign(Impl*& var, const LLSD::UUID& v)
598{
599 reset(var, new ImplUUID(v));
600}
601
602void LLSD::Impl::assign(Impl*& var, const LLSD::Date& v)
603{
604 reset(var, new ImplDate(v));
605}
606
607void LLSD::Impl::assign(Impl*& var, const LLSD::URI& v)
608{
609 reset(var, new ImplURI(v));
610}
611
612void LLSD::Impl::assign(Impl*& var, const LLSD::Binary& v)
613{
614 reset(var, new ImplBinary(v));
615}
616
617
618const LLSD& LLSD::Impl::undef()
619{
620 static const LLSD immutableUndefined;
621 return immutableUndefined;
622}
623
624U32 LLSD::Impl::sAllocationCount = 0;
625U32 LLSD::Impl::sOutstandingCount = 0;
626
627
628
629namespace {
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
644LLSD::LLSD() : impl(0) { }
645LLSD::~LLSD() { Impl::reset(impl, 0); }
646
647LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); }
648void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
649
650
651void LLSD::clear() { Impl::assignUndefined(impl); }
652
653LLSD::Type LLSD::type() const { return safe(impl).type(); }
654
655// Scaler Constructors
656LLSD::LLSD(Boolean v) : impl(0) { assign(v); }
657LLSD::LLSD(Integer v) : impl(0) { assign(v); }
658LLSD::LLSD(Real v) : impl(0) { assign(v); }
659LLSD::LLSD(const UUID& v) : impl(0) { assign(v); }
660LLSD::LLSD(const String& v) : impl(0) { assign(v); }
661LLSD::LLSD(const Date& v) : impl(0) { assign(v); }
662LLSD::LLSD(const URI& v) : impl(0) { assign(v); }
663LLSD::LLSD(const Binary& v) : impl(0) { assign(v); }
664
665// Convenience Constructors
666LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); }
667
668// Scalar Assignment
669void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
670void LLSD::assign(Integer v) { safe(impl).assign(impl, v); }
671void LLSD::assign(Real v) { safe(impl).assign(impl, v); }
672void LLSD::assign(const String& v) { safe(impl).assign(impl, v); }
673void LLSD::assign(const UUID& v) { safe(impl).assign(impl, v); }
674void LLSD::assign(const Date& v) { safe(impl).assign(impl, v); }
675void LLSD::assign(const URI& v) { safe(impl).assign(impl, v); }
676void LLSD::assign(const Binary& v) { safe(impl).assign(impl, v); }
677
678// Scalar Accessors
679LLSD::Boolean LLSD::asBoolean() const { return safe(impl).asBoolean(); }
680LLSD::Integer LLSD::asInteger() const { return safe(impl).asInteger(); }
681LLSD::Real LLSD::asReal() const { return safe(impl).asReal(); }
682LLSD::String LLSD::asString() const { return safe(impl).asString(); }
683LLSD::UUID LLSD::asUUID() const { return safe(impl).asUUID(); }
684LLSD::Date LLSD::asDate() const { return safe(impl).asDate(); }
685LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); }
686LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); }
687
688// const char * helpers
689LLSD::LLSD(const char* v) : impl(0) { assign(v); }
690void LLSD::assign(const char* v)
691{
692 if(v) assign(std::string(v));
693 else assign(std::string());
694}
695
696
697LLSD LLSD::emptyMap()
698{
699 LLSD v;
700 makeMap(v.impl);
701 return v;
702}
703
704bool LLSD::has(const String& k) const { return safe(impl).has(k); }
705LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
706
707void LLSD::insert(const String& k, const LLSD& v)
708 { makeMap(impl).insert(k, v); }
709void LLSD::erase(const String& k) { makeMap(impl).erase(k); }
710
711LLSD& LLSD::operator[](const String& k)
712 { return makeMap(impl).ref(k); }
713const LLSD& LLSD::operator[](const String& k) const
714 { return safe(impl).ref(k); }
715
716
717LLSD LLSD::emptyArray()
718{
719 LLSD v;
720 makeArray(v.impl);
721 return v;
722}
723
724int LLSD::size() const { return safe(impl).size(); }
725
726LLSD LLSD::get(Integer i) const { return safe(impl).get(i); }
727void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); }
728
729void LLSD::insert(Integer i, const LLSD& v)
730 { makeArray(impl).insert(i, v); }
731void LLSD::append(const LLSD& v) { makeArray(impl).append(v); }
732void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
733
734LLSD& LLSD::operator[](Integer i)
735 { return makeArray(impl).ref(i); }
736const LLSD& LLSD::operator[](Integer i) const
737 { return safe(impl).ref(i); }
738
739U32 LLSD::allocationCount() { return Impl::sAllocationCount; }
740U32 LLSD::outstandingCount() { return Impl::sOutstandingCount; }
741
742LLSD::map_iterator LLSD::beginMap() { return makeMap(impl).beginMap(); }
743LLSD::map_iterator LLSD::endMap() { return makeMap(impl).endMap(); }
744LLSD::map_const_iterator LLSD::beginMap() const { return safe(impl).beginMap(); }
745LLSD::map_const_iterator LLSD::endMap() const { return safe(impl).endMap(); }
746
747LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray(); }
748LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
749LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
750LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }