aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llsdserialize.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llsdserialize.h')
-rw-r--r--linden/indra/llcommon/llsdserialize.h611
1 files changed, 611 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llsdserialize.h b/linden/indra/llcommon/llsdserialize.h
new file mode 100644
index 0000000..76c65c2
--- /dev/null
+++ b/linden/indra/llcommon/llsdserialize.h
@@ -0,0 +1,611 @@
1/**
2 * @file llsdserialize.h
3 * @author Phoenix
4 * @date 2006-02-26
5 * @brief Declaration of parsers and formatters for LLSD
6 *
7 * Copyright (c) 2006-2007, Linden Research, Inc.
8 *
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#ifndef LL_LLSDSERIALIZE_H
31#define LL_LLSDSERIALIZE_H
32
33#include <iosfwd>
34#include "llsd.h"
35#include "llmemory.h"
36
37/**
38 * @class LLSDParser
39 * @brief Abstract base class for simple LLSD parsers.
40 */
41class LLSDParser : public LLRefCount
42{
43protected:
44 /**
45 * @brief Destructor
46 */
47 virtual ~LLSDParser();
48
49public:
50 /**
51 * @brief Constructor
52 */
53 LLSDParser();
54
55 /**
56 * @brief Call this method to parse a stream for LLSD.
57 *
58 * This method parses the istream for a structured data. This
59 * method assumes that the istream is a complete llsd object --
60 * for example an opened and closed map with an arbitrary nesting
61 * of elements. This method will return after reading one data
62 * object, allowing continued reading from the stream by the
63 * caller.
64 * @param istr The input stream.
65 * @param data[out] The newly parse structured data.
66 * @return Returns The number of LLSD objects parsed into data.
67 */
68 virtual S32 parse(std::istream& istr, LLSD& data) const = 0;
69
70protected:
71
72};
73
74/**
75 * @class LLSDNotationParser
76 * @brief Parser which handles the original notation format for LLSD.
77 */
78class LLSDNotationParser : public LLSDParser
79{
80protected:
81 /**
82 * @brief Destructor
83 */
84 virtual ~LLSDNotationParser();
85
86public:
87 /**
88 * @brief Constructor
89 */
90 LLSDNotationParser() {}
91
92 /**
93 * @brief Call this method to parse a stream for LLSD.
94 *
95 * This method parses the istream for a structured data. This
96 * method assumes that the istream is a complete llsd object --
97 * for example an opened and closed map with an arbitrary nesting
98 * of elements. This method will return after reading one data
99 * object, allowing continued reading from the stream by the
100 * caller.
101 * @param istr The input stream.
102 * @param data[out] The newly parse structured data. Undefined on failure.
103 * @return Returns the number of LLSD objects parsed into
104 * data. Returns -1 on parse failure.
105 */
106 virtual S32 parse(std::istream& istr, LLSD& data) const;
107
108 /**
109 * @brief Simple notation parse.
110 *
111 * This simplified parser cannot not distinguish between a failed
112 * parse and a parse which yields a single undefined LLSD. You can
113 * use this if error checking will be implicit in the use of the
114 * results of the parse.
115 * @param istr The input stream.
116 * @return Returns the parsed LLSD object.
117 */
118 static LLSD parse(std::istream& istr);
119
120private:
121 /**
122 * @brief Parse a map from the istream
123 *
124 * @param istr The input stream.
125 * @param map The map to add the parsed data.
126 * @return Returns The number of LLSD objects parsed into data.
127 */
128 S32 parseMap(std::istream& istr, LLSD& map) const;
129
130 /**
131 * @brief Parse an array from the istream.
132 *
133 * @param istr The input stream.
134 * @param array The array to append the parsed data.
135 * @return Returns The number of LLSD objects parsed into data.
136 */
137 S32 parseArray(std::istream& istr, LLSD& array) const;
138
139 /**
140 * @brief Parse a string from the istream and assign it to data.
141 *
142 * @param istr The input stream.
143 * @param data[out] The data to assign.
144 */
145 void parseString(std::istream& istr, LLSD& data) const;
146
147 /**
148 * @brief Parse binary data from the stream.
149 *
150 * @param istr The input stream.
151 * @param data[out] The data to assign.
152 */
153 void parseBinary(std::istream& istr, LLSD& data) const;
154};
155
156/**
157 * @class LLSDXMLParser
158 * @brief Parser which handles XML format LLSD.
159 */
160class LLSDXMLParser : public LLSDParser
161{
162protected:
163 /**
164 * @brief Destructor
165 */
166 virtual ~LLSDXMLParser();
167
168public:
169 /**
170 * @brief Constructor
171 */
172 LLSDXMLParser();
173
174 /**
175 * @brief Call this method to parse a stream for LLSD.
176 *
177 * This method parses the istream for a structured data. This
178 * method assumes that the istream is a complete llsd object --
179 * for example an opened and closed map with an arbitrary nesting
180 * of elements. This method will return after reading one data
181 * object, allowing continued reading from the stream by the
182 * caller.
183 * @param istr The input stream.
184 * @param data[out] The newly parse structured data.
185 * @return Returns the number of LLSD objects parsed into data.
186 */
187 virtual S32 parse(std::istream& istr, LLSD& data) const;
188
189private:
190 class Impl;
191 Impl& impl;
192
193 void parsePart(const char *buf, int len);
194 friend class LLSDSerialize;
195};
196
197/**
198 * @class LLSDBinaryParser
199 * @brief Parser which handles binary formatted LLSD.
200 */
201class LLSDBinaryParser : public LLSDParser
202{
203protected:
204 /**
205 * @brief Destructor
206 */
207 virtual ~LLSDBinaryParser();
208
209public:
210 /**
211 * @brief Constructor
212 */
213 LLSDBinaryParser();
214
215 /**
216 * @brief Call this method to parse a stream for LLSD.
217 *
218 * This method parses the istream for a structured data. This
219 * method assumes that the istream is a complete llsd object --
220 * for example an opened and closed map with an arbitrary nesting
221 * of elements. This method will return after reading one data
222 * object, allowing continued reading from the stream by the
223 * caller.
224 * @param istr The input stream.
225 * @param data[out] The newly parse structured data.
226 * @return Returns the number of LLSD objects parsed into data.
227 */
228 virtual S32 parse(std::istream& istr, LLSD& data) const;
229
230 /**
231 * @brief Simple notation parse.
232 *
233 * This simplified parser cannot not distinguish between a failed
234 * parse and a parse which yields a single undefined LLSD. You can
235 * use this if error checking will be implicit in the use of the
236 * results of the parse.
237 * @param istr The input stream.
238 * @return Returns the parsed LLSD object.
239 */
240 static LLSD parse(std::istream& istr);
241
242private:
243 /**
244 * @brief Parse a map from the istream
245 *
246 * @param istr The input stream.
247 * @param map The map to add the parsed data.
248 * @return Returns The number of LLSD objects parsed into data.
249 */
250 S32 parseMap(std::istream& istr, LLSD& map) const;
251
252 /**
253 * @brief Parse an array from the istream.
254 *
255 * @param istr The input stream.
256 * @param array The array to append the parsed data.
257 * @return Returns The number of LLSD objects parsed into data.
258 */
259 S32 parseArray(std::istream& istr, LLSD& array) const;
260
261 /**
262 * @brief Parse a string from the istream and assign it to data.
263 *
264 * @param istr The input stream.
265 * @param value[out] The string to assign.
266 */
267 void parseString(std::istream& istr, std::string& value) const;
268};
269
270
271/**
272 * @class LLSDFormatter
273 * @brief Abstract base class for formatting LLSD.
274 */
275class LLSDFormatter : public LLRefCount
276{
277protected:
278 /**
279 * @brief Destructor
280 */
281 virtual ~LLSDFormatter();
282
283public:
284 /**
285 * Options for output
286 */
287 enum e_formatter_options_type
288 {
289 OPTIONS_NONE = 0,
290 OPTIONS_PRETTY = 1
291 } EFormatterOptions;
292
293 /**
294 * @brief Constructor
295 */
296 LLSDFormatter();
297
298 /**
299 * @brief Set the boolean serialization format.
300 *
301 * @param alpha Serializes boolean as alpha if true.
302 */
303 void boolalpha(bool alpha);
304
305 /**
306 * @brief Set the real format
307 *
308 * By default, the formatter will use default double serialization
309 * which is frequently frustrating for many applications. You can
310 * set the precision on the stream independently, but that still
311 * might not work depending on the value.
312 * EXAMPLES:<br>
313 * %.2f<br>
314 * @param format A format string which follows the printf format
315 * rules. Specify an empty string to return to default formatting.
316 */
317 void realFormat(const std::string& format);
318
319 /**
320 * @brief Call this method to format an LLSD to a stream.
321 *
322 * @param data The data to write.
323 * @param ostr The destination stream for the data.
324 * @return Returns The number of LLSD objects fomatted out
325 */
326 virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const = 0;
327
328protected:
329 /**
330 * @brief Helper method which appropriately obeys the real format.
331 *
332 * @param real The real value to format.
333 * @param ostr The destination stream for the data.
334 */
335 void formatReal(LLSD::Real real, std::ostream& ostr) const;
336
337protected:
338 bool mBoolAlpha;
339 std::string mRealFormat;
340};
341
342
343/**
344 * @class LLSDNotationFormatter
345 * @brief Formatter which outputs the original notation format for LLSD.
346 */
347class LLSDNotationFormatter : public LLSDFormatter
348{
349protected:
350 /**
351 * @brief Destructor
352 */
353 virtual ~LLSDNotationFormatter();
354
355public:
356 /**
357 * @brief Constructor
358 */
359 LLSDNotationFormatter();
360
361 /**
362 * @brief Helper static method to return a notation escaped string
363 *
364 * This method will return the notation escaped string, but not
365 * the surrounding serialization identifiers such as a double or
366 * single quote. It will be up to the caller to embed those as
367 * appropriate.
368 * @param in The raw, unescaped string.
369 * @return Returns an escaped string appropriate for serialization.
370 */
371 static std::string escapeString(const std::string& in);
372
373 /**
374 * @brief Call this method to format an LLSD to a stream.
375 *
376 * @param data The data to write.
377 * @param ostr The destination stream for the data.
378 * @return Returns The number of LLSD objects fomatted out
379 */
380 virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const;
381};
382
383
384/**
385 * @class LLSDXMLFormatter
386 * @brief Formatter which outputs the LLSD as XML.
387 */
388class LLSDXMLFormatter : public LLSDFormatter
389{
390protected:
391 /**
392 * @brief Destructor
393 */
394 virtual ~LLSDXMLFormatter();
395
396public:
397 /**
398 * @brief Constructor
399 */
400 LLSDXMLFormatter();
401
402 /**
403 * @brief Helper static method to return an xml escaped string
404 *
405 * @param in A valid UTF-8 string.
406 * @return Returns an escaped string appropriate for serialization.
407 */
408 static std::string escapeString(const std::string& in);
409
410 /**
411 * @brief Call this method to format an LLSD to a stream.
412 *
413 * @param data The data to write.
414 * @param ostr The destination stream for the data.
415 * @return Returns The number of LLSD objects fomatted out
416 */
417 virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const;
418
419protected:
420
421 /**
422 * @brief Implementation to format the data. This is called recursively.
423 *
424 * @param data The data to write.
425 * @param ostr The destination stream for the data.
426 * @return Returns The number of LLSD objects fomatted out
427 */
428 S32 format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const;
429};
430
431
432/**
433 * @class LLSDBinaryFormatter
434 * @brief Formatter which outputs the LLSD as a binary notation format.
435 *
436 * The binary format is a compact and efficient representation of
437 * structured data useful for when transmitting over a small data pipe
438 * or when transmission frequency is very high.<br>
439 *
440 * The normal boolalpha and real format commands are ignored.<br>
441 *
442 * All integers are transmitted in network byte order. The format is:<br>
443 * Undefined: '!'<br>
444 * Boolean: character '1' for true character '0' for false<br>
445 * Integer: 'i' + 4 bytes network byte order<br>
446 * Real: 'r' + 8 bytes IEEE double<br>
447 * UUID: 'u' + 16 byte unsigned integer<br>
448 * String: 's' + 4 byte integer size + string<br>
449 * Date: 'd' + 8 byte IEEE double for seconds since epoch<br>
450 * URI: 'l' + 4 byte integer size + string uri<br>
451 * Binary: 'b' + 4 byte integer size + binary data<br>
452 * Array: '[' + 4 byte integer size + all values + ']'<br>
453 * Map: '{' + 4 byte integer size every(key + value) + '}'<br>
454 * map keys are serialized as 'k' + 4 byte integer size + string
455 */
456class LLSDBinaryFormatter : public LLSDFormatter
457{
458protected:
459 /**
460 * @brief Destructor
461 */
462 virtual ~LLSDBinaryFormatter();
463
464public:
465 /**
466 * @brief Constructor
467 */
468 LLSDBinaryFormatter();
469
470 /**
471 * @brief Call this method to format an LLSD to a stream.
472 *
473 * @param data The data to write.
474 * @param ostr The destination stream for the data.
475 * @return Returns The number of LLSD objects fomatted out
476 */
477 virtual S32 format(const LLSD& data, std::ostream& ostr, U32 options = LLSDFormatter::OPTIONS_NONE) const;
478
479protected:
480 /**
481 * @brief Helper method to serialize strings
482 *
483 * This method serializes a network byte order size and the raw
484 * string contents.
485 * @param string The string to write.
486 * @param ostr The destination stream for the data.
487 */
488 void formatString(const std::string& string, std::ostream& ostr) const;
489};
490
491
492/**
493 * @class LLSDNotationStreamFormatter
494 * @brief Formatter which is specialized for use on streams which
495 * outputs the original notation format for LLSD.
496 *
497 * This class is useful for doing inline stream operations. For example:
498 *
499 * <code>
500 * LLSD sd;<br>
501 * sd["foo"] = "bar";<br>
502 * std::stringstream params;<br>
503 * params << "[{'version':i1}," << LLSDOStreamer<LLSDNotationFormatter>(sd)
504 * << "]";
505 * </code>
506 */
507template <class Formatter>
508class LLSDOStreamer : public Formatter
509{
510public:
511 /**
512 * @brief Constructor
513 */
514 LLSDOStreamer(const LLSD& data, U32 options = LLSDFormatter::OPTIONS_NONE) :
515 mSD(data), mOptions(options) {}
516
517 /**
518 * @brief Stream operator.
519 *
520 * Use this inline during construction during a stream operation.
521 * @param str The destination stream for serialized output.
522 * @param The formatter which will output it's LLSD.
523 * @return Returns the stream passed in after streaming mSD.
524 */
525 friend std::ostream& operator<<(
526 std::ostream& str,
527 const LLSDOStreamer<Formatter>& formatter)
528 {
529 formatter.format(formatter.mSD, str, formatter.mOptions);
530 return str;
531 }
532
533protected:
534 LLSD mSD;
535 U32 mOptions;
536};
537
538typedef LLSDOStreamer<LLSDNotationFormatter> LLSDNotationStreamer;
539typedef LLSDOStreamer<LLSDXMLFormatter> LLSDXMLStreamer;
540
541/**
542 * @class LLSDSerialize
543 * @Serializer / deserializer for the various LLSD formats
544 */
545class LLSDSerialize
546{
547public:
548 enum ELLSD_Serialize
549 {
550 LLSD_BINARY, LLSD_XML
551 };
552
553 /*
554 * Generic in/outs
555 */
556 static void serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize,
557 U32 options = LLSDFormatter::OPTIONS_NONE);
558 static bool deserialize(LLSD& sd, std::istream& str);
559
560 /*
561 * Notation Methods
562 */
563 static S32 toNotation(const LLSD& sd, std::ostream& str)
564 {
565 LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
566 return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
567 }
568 static S32 fromNotation(LLSD& sd, std::istream& str)
569 {
570 LLPointer<LLSDNotationParser> p = new LLSDNotationParser;
571 return p->parse(str, sd);
572 }
573
574 /*
575 * XML Methods
576 */
577 static S32 toXML(const LLSD& sd, std::ostream& str)
578 {
579 LLPointer<LLSDXMLFormatter> f = new LLSDXMLFormatter;
580 return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
581 }
582 static S32 toPrettyXML(const LLSD& sd, std::ostream& str)
583 {
584 LLPointer<LLSDXMLFormatter> f = new LLSDXMLFormatter;
585 return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
586 }
587 static S32 fromXML(LLSD& sd, std::istream& str)
588 {
589 LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
590 return p->parse(str, sd);
591 }
592
593 /*
594 * Binary Methods
595 */
596 static S32 toBinary(const LLSD& sd, std::ostream& str)
597 {
598 LLPointer<LLSDBinaryFormatter> f = new LLSDBinaryFormatter;
599 return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
600 }
601 static S32 fromBinary(LLSD& sd, std::istream& str)
602 {
603 LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser;
604 return p->parse(str, sd);
605 }
606private:
607 static const char *LLSDBinaryHeader;
608 static const char *LLSDXMLHeader;
609};
610
611#endif // LL_LLSDSERIALIZE_H