llsdserialize.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  1. /**
  2. * @file llsdserialize.h
  3. * @author Phoenix
  4. * @date 2006-02-26
  5. * @brief Declaration of parsers and formatters for LLSD
  6. *
  7. * $LicenseInfo:firstyear=2006&license=viewergpl$
  8. *
  9. * Copyright (c) 2006-2009, Linden Research, Inc.
  10. *
  11. * Second Life Viewer Source Code
  12. * The source code in this file ("Source Code") is provided by Linden Lab
  13. * to you under the terms of the GNU General Public License, version 2.0
  14. * ("GPL"), unless you have obtained a separate licensing agreement
  15. * ("Other License"), formally executed by you and Linden Lab. Terms of
  16. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18. *
  19. * There are special exceptions to the terms and conditions of the GPL as
  20. * it is applied to this Source Code. View the full text of the exception
  21. * in the file doc/FLOSS-exception.txt in this software distribution, or
  22. * online at
  23. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24. *
  25. * By copying, modifying or distributing this software, you acknowledge
  26. * that you have read and understood your obligations described above,
  27. * and agree to abide by those obligations.
  28. *
  29. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31. * COMPLETENESS OR PERFORMANCE.
  32. * $/LicenseInfo$
  33. */
  34. #ifndef LL_LLSDSERIALIZE_H
  35. #define LL_LLSDSERIALIZE_H
  36. #include <iosfwd>
  37. #include <type_traits>
  38. #include "llpointer.h"
  39. #include "llrefcount.h"
  40. #include "llsd.h"
  41. // Set to 1 to enable the new deserialize code: it is currently plain BOGUS,
  42. // so keep it disabled for now... HB
  43. #define LL_USE_NEW_DESERIALIZE 0
  44. // To express an index that might go negative (ssize_t being provided by SOME
  45. // compilers, do not collide names).
  46. typedef typename std::make_signed<size_t>::type llssize;
  47. // Abstract base class for LLSD parsers.
  48. class LLSDParser : public LLRefCount
  49. {
  50. protected:
  51. ~LLSDParser() override = default;
  52. public:
  53. // Anonymous enum to indicate parsing failure.
  54. enum
  55. {
  56. PARSE_FAILURE = -1
  57. };
  58. LLSDParser();
  59. // Call this method to parse a stream forr a structured data. It assumes
  60. // that the istream is a complete llsd object, for example an opened and
  61. // closed map with an arbitrary nesting of elements. Returns after reading
  62. // one data object, allowing continued reading from the stream by the
  63. // caller.
  64. // 'istr' is the input stream.
  65. // 'data' is the output for the parsed structured data.
  66. // 'max_bytes' is the maximum number of bytes that will be in the stream.
  67. // Pass in LLSDSerialize::SIZE_UNLIMITED (-1) to set no byte limit.
  68. // 'max_depth' is the maximum depth parser will check before exiting with
  69. // parse error, -1 = unlimited.
  70. // Returns the number of LLSD objects parsed into data or PARSE_FAILURE on
  71. // parse failure.
  72. S32 parse(std::istream& istr, LLSD& data, llssize max_bytes,
  73. S32 max_depth = -1);
  74. // Like parse(), but uses a different call (istream.getline()) to read by
  75. // lines. This API is better suited for XML, where the parse cannot tell
  76. // where the document actually ends.
  77. S32 parseLines(std::istream& istr, LLSD& data);
  78. // Resets the parser so parse() or parseLines() can be called again for
  79. // another <llsd> chunk.
  80. void reset() { doReset(); }
  81. protected:
  82. // Pure virtual base for doing the parse.
  83. // This method parses the istream for a structured data. It assumes that
  84. // the istream is a complete llsd object, for example an opened and closed
  85. // map with an arbitrary nesting of elements. It will return after reading
  86. // one data object, allowing continued reading from the stream by the
  87. // caller. 'istr' is input stream, 'data[out]' is the newly parse
  88. // structured data, 'max_depth' is the max depth the parser will check
  89. // before exiting with parse error (-1 = unlimited). The method returns the
  90. // number of LLSD objects parsed into data or PARSE_FAILURE (-1) on parse
  91. // failure.
  92. virtual S32 doParse(std::istream& istr, LLSD& data,
  93. S32 max_depth = -1) const = 0;
  94. // Virtual default method for resetting the parser
  95. virtual void doReset() {}
  96. // The following istream helper methods exist to help correctly use the
  97. // mMaxBytesLeft without really thinking about it for most simple
  98. // operations. Use of the streamtools in llstreamtools.h will require
  99. // custom wrapping.
  100. // Gets a byte off the stream
  101. int get(std::istream& istr) const;
  102. // Gets several bytes off the stream into a buffer.
  103. // 'istr' is the istream to work with, 's' is the buffer to get into,
  104. // 'n' is the number of bytes in the buffer (nul terminator included); a
  105. // maximum of n - 1 bytes will be extracted. 'delim' is the delimiter to
  106. // get until found. Returns istr.
  107. std::istream& get(std::istream& istr, char* s, std::streamsize n,
  108. char delim) const;
  109. // Gets several bytes off the stream into a streambuf
  110. std::istream& get(std::istream& istr, std::streambuf& sb, char dlim) const;
  111. // Ignores the next byte on the istream
  112. std::istream& ignore(std::istream& istr) const;
  113. // Puts the last character retrieved back on the stream
  114. std::istream& putback(std::istream& istr, char c) const;
  115. // Reads a block of 'n' characters into a buffer ('s')
  116. std::istream& read(std::istream& istr, char* s, std::streamsize n) const;
  117. protected:
  118. // Accounte for 'bytes' read outside of the istream helpers. Conceptually
  119. // const since it only modifies mutable members.
  120. void account(llssize bytes) const;
  121. protected:
  122. // The maximum number of bytes left to be parsed.
  123. mutable llssize mMaxBytesLeft;
  124. // To set if byte counts should be checked during parsing.
  125. bool mCheckLimits;
  126. // Set to use line-based reading to get text
  127. bool mParseLines;
  128. };
  129. // Parser class which handles the original notation format for LLSD.
  130. class LLSDNotationParser final : public LLSDParser
  131. {
  132. protected:
  133. LOG_CLASS(LLSDNotationParser);
  134. public:
  135. LLSDNotationParser();
  136. protected:
  137. ~LLSDNotationParser() override = default;
  138. /**
  139. * @brief Call this method to parse a stream for LLSD.
  140. *
  141. * This method parses the istream for a structured data. This
  142. * method assumes that the istream is a complete llsd object --
  143. * for example an opened and closed map with an arbitrary nesting
  144. * of elements. This method will return after reading one data
  145. * object, allowing continued reading from the stream by the
  146. * caller.
  147. * @param istr The input stream.
  148. * @param data[out] The newly parse structured data. Undefined on failure.
  149. * @param depth Max depth parser will check before exiting with
  150. * parse error, -1 = unlimited.
  151. * @return Returns the number of LLSD objects parsed into
  152. * data. Returns PARSE_FAILURE (-1) on parse failure.
  153. */
  154. S32 doParse(std::istream& istr, LLSD& data, S32 depth = -1) const override;
  155. private:
  156. /**
  157. * @brief Parse a map from the istream
  158. *
  159. * @param istr The input stream.
  160. * @param map The map to add the parsed data.
  161. * @param max_depth Allowed parsing depth.
  162. * @return Returns The number of LLSD objects parsed into data.
  163. */
  164. S32 parseMap(std::istream& istr, LLSD& map, S32 max_depth) const;
  165. /**
  166. * @brief Parse an array from the istream.
  167. *
  168. * @param istr The input stream.
  169. * @param array The array to append the parsed data.
  170. * @param max_depth Allowed parsing depth.
  171. * @return Returns The number of LLSD objects parsed into data.
  172. */
  173. S32 parseArray(std::istream& istr, LLSD& array, S32 max_depth) const;
  174. /**
  175. * @brief Parse a string from the istream and assign it to data.
  176. *
  177. * @param istr The input stream.
  178. * @param data[out] The data to assign.
  179. * @param max_depth Allowed parsing depth.
  180. * @return Retuns true if a complete string was parsed.
  181. */
  182. bool parseString(std::istream& istr, LLSD& data) const;
  183. /**
  184. * @brief Parse binary data from the stream.
  185. *
  186. * @param istr The input stream.
  187. * @param data[out] The data to assign.
  188. * @param max_depth Allowed parsing depth.
  189. * @return Retuns true if a complete blob was parsed.
  190. */
  191. bool parseBinary(std::istream& istr, LLSD& data) const;
  192. };
  193. // Parser class which handles XML format LLSD.
  194. class LLSDXMLParser final : public LLSDParser
  195. {
  196. protected:
  197. LOG_CLASS(LLSDXMLParser);
  198. public:
  199. LLSDXMLParser(bool emit_errors = true);
  200. protected:
  201. ~LLSDXMLParser() override;
  202. /**
  203. * @brief Call this method to parse a stream for LLSD.
  204. *
  205. * This method parses the istream for a structured data. This
  206. * method assumes that the istream is a complete llsd object --
  207. * for example an opened and closed map with an arbitrary nesting
  208. * of elements. This method will return after reading one data
  209. * object, allowing continued reading from the stream by the
  210. * caller.
  211. * @param istr The input stream.
  212. * @param data[out] The newly parse structured data.
  213. * @param depth Max depth parser will check before exiting with
  214. * parse error, -1 = unlimited.
  215. * @return Returns the number of LLSD objects parsed into
  216. * data. Returns PARSE_FAILURE (-1) on parse failure.
  217. */
  218. S32 doParse(std::istream& istr, LLSD& data, S32 depth = -1) const override;
  219. // Virtual default function for resetting the parser
  220. void doReset() override;
  221. private:
  222. class Impl;
  223. Impl& impl;
  224. void parsePart(const char* buf, llssize len);
  225. friend class LLSDSerialize;
  226. };
  227. // Parser class which handles binary formatted LLSD.
  228. class LLSDBinaryParser final : public LLSDParser
  229. {
  230. protected:
  231. LOG_CLASS(LLSDNotationParser);
  232. public:
  233. LLSDBinaryParser();
  234. protected:
  235. ~LLSDBinaryParser() override = default;
  236. /**
  237. * @brief Call this method to parse a stream for LLSD.
  238. *
  239. * This method parses the istream for a structured data. This
  240. * method assumes that the istream is a complete llsd object --
  241. * for example an opened and closed map with an arbitrary nesting
  242. * of elements. This method will return after reading one data
  243. * object, allowing continued reading from the stream by the
  244. * caller.
  245. * @param istr The input stream.
  246. * @param data[out] The newly parse structured data.
  247. * @param depth Max depth parser will check before exiting with
  248. * parse error, -1 = unlimited.
  249. * @return Returns the number of LLSD objects parsed into
  250. * data. Returns -1 on parse failure.
  251. */
  252. S32 doParse(std::istream& istr, LLSD& data, S32 depth = -1) const override;
  253. private:
  254. /**
  255. * @brief Parse a map from the istream
  256. *
  257. * @param istr The input stream.
  258. * @param map The map to add the parsed data.
  259. * @param max_depth Allowed parsing depth.
  260. * @return Returns The number of LLSD objects parsed into data.
  261. */
  262. S32 parseMap(std::istream& istr, LLSD& map, S32 max_depth) const;
  263. /**
  264. * @brief Parse an array from the istream.
  265. *
  266. * @param istr The input stream.
  267. * @param array The array to append the parsed data.
  268. * @param max_depth Allowed parsing depth.
  269. * @return Returns The number of LLSD objects parsed into data.
  270. */
  271. S32 parseArray(std::istream& istr, LLSD& array, S32 max_depth) const;
  272. /**
  273. * @brief Parse a string from the istream and assign it to data.
  274. *
  275. * @param istr The input stream.
  276. * @param value[out] The string to assign.
  277. * @return Retuns true if a complete string was parsed.
  278. */
  279. bool parseString(std::istream& istr, std::string& value) const;
  280. };
  281. // Abstract base class for formatting LLSD.
  282. class LLSDFormatter : public LLRefCount
  283. {
  284. protected:
  285. ~LLSDFormatter() override = default;
  286. public:
  287. /**
  288. * Options for output
  289. */
  290. typedef enum e_formatter_options_type
  291. {
  292. OPTIONS_NONE = 0,
  293. OPTIONS_PRETTY = 1,
  294. OPTIONS_PRETTY_BINARY = 2
  295. } EFormatterOptions;
  296. LLSDFormatter(bool bool_apha = false, const std::string& real_format = "",
  297. EFormatterOptions options = OPTIONS_PRETTY_BINARY);
  298. /**
  299. * @brief Set the boolean serialization format.
  300. *
  301. * @param alpha Serializes boolean as alpha if true.
  302. */
  303. LL_INLINE void boolalpha(bool alpha) { mBoolAlpha = alpha; }
  304. /**
  305. * @brief Set the real format
  306. *
  307. * By default, the formatter will use default double serialization
  308. * which is frequently frustrating for many applications. You can
  309. * set the precision on the stream independently, but that still
  310. * might not work depending on the value.
  311. * EXAMPLES:<br>
  312. * %.2f<br>
  313. * @param format A format string which follows the printf format
  314. * rules. Specify an empty string to return to default formatting.
  315. */
  316. LL_INLINE void realFormat(const std::string& fmt) { mRealFormat = fmt;}
  317. // Call this method to format an LLSD to a stream with options as set by
  318. // the constructor.
  319. S32 format(const LLSD& data, std::ostream& ostr) const;
  320. /**
  321. * @brief Call this method to format an LLSD to a stream.
  322. *
  323. * @param data The data to write.
  324. * @param ostr The destination stream for the data.
  325. * @return Returns The number of LLSD objects fomatted out
  326. */
  327. virtual S32 format(const LLSD& data, std::ostream& ostr,
  328. EFormatterOptions options) const;
  329. protected:
  330. // Implementation to format the data. This is called recursively.
  331. // 'data' is the data to write and 'ostr' the destination stream for the
  332. // data. Returns the number of LLSD objects formatted out.
  333. virtual S32 format_impl(const LLSD& data, std::ostream& ostr,
  334. EFormatterOptions options, U32 level) const = 0;
  335. /**
  336. * @brief Helper method which appropriately obeys the real format.
  337. *
  338. * @param real The real value to format.
  339. * @param ostr The destination stream for the data.
  340. */
  341. void formatReal(LLSD::Real real, std::ostream& ostr) const;
  342. protected:
  343. EFormatterOptions mOptions;
  344. std::string mRealFormat;
  345. bool mBoolAlpha;
  346. };
  347. // Formatter class which outputs the original notation format for LLSD.
  348. class LLSDNotationFormatter final : public LLSDFormatter
  349. {
  350. protected:
  351. ~LLSDNotationFormatter() override = default;
  352. public:
  353. LLSDNotationFormatter(bool bool_apha = false,
  354. const std::string& real_format = "",
  355. EFormatterOptions options = OPTIONS_PRETTY_BINARY);
  356. /**
  357. * @brief Helper static method to return a notation escaped string
  358. *
  359. * This method will return the notation escaped string, but not
  360. * the surrounding serialization identifiers such as a double or
  361. * single quote. It will be up to the caller to embed those as
  362. * appropriate.
  363. * @param in The raw, unescaped string.
  364. * @return Returns an escaped string appropriate for serialization.
  365. */
  366. static std::string escapeString(const std::string& in);
  367. protected:
  368. /**
  369. * @brief Implementation to format the data. This is called recursively.
  370. *
  371. * @param data The data to write.
  372. * @param ostr The destination stream for the data.
  373. * @return Returns The number of LLSD objects fomatted out
  374. */
  375. S32 format_impl(const LLSD& data, std::ostream& ostr,
  376. EFormatterOptions options, U32 level) const override;
  377. };
  378. // Formatter class which outputs the LLSD as XML.
  379. class LLSDXMLFormatter final : public LLSDFormatter
  380. {
  381. protected:
  382. ~LLSDXMLFormatter() override = default;
  383. public:
  384. LLSDXMLFormatter(bool bool_apha = false,
  385. const std::string& real_format = "",
  386. EFormatterOptions options = OPTIONS_PRETTY_BINARY);
  387. /**
  388. * @brief Helper static method to return an xml escaped string
  389. *
  390. * @param in A valid UTF-8 string.
  391. * @return Returns an escaped string appropriate for serialization.
  392. */
  393. static std::string escapeString(const std::string& in);
  394. /**
  395. * @brief Call this method to format an LLSD to a stream.
  396. *
  397. * @param data The data to write.
  398. * @param ostr The destination stream for the data.
  399. * @return Returns The number of LLSD objects fomatted out
  400. */
  401. S32 format(const LLSD& data, std::ostream& ostr,
  402. EFormatterOptions options) const override;
  403. // Also pull down base-class format() method that isn't overridden
  404. using LLSDFormatter::format;
  405. protected:
  406. /**
  407. * @brief Implementation to format the data. This is called recursively.
  408. *
  409. * @param data The data to write.
  410. * @param ostr The destination stream for the data.
  411. * @return Returns The number of LLSD objects fomatted out
  412. */
  413. S32 format_impl(const LLSD& data, std::ostream& ostr,
  414. EFormatterOptions options,
  415. U32 level) const override;
  416. };
  417. /**
  418. * @class LLSDBinaryFormatter
  419. * @brief Formatter which outputs the LLSD as a binary notation format.
  420. *
  421. * The binary format is a compact and efficient representation of
  422. * structured data useful for when transmitting over a small data pipe
  423. * or when transmission frequency is very high.<br>
  424. *
  425. * The normal boolalpha and real format commands are ignored.<br>
  426. *
  427. * All integers are transmitted in network byte order. The format is:<br>
  428. * Undefined: '!'<br>
  429. * Boolean: character '1' for true character '0' for false<br>
  430. * Integer: 'i' + 4 bytes network byte order<br>
  431. * Real: 'r' + 8 bytes IEEE double<br>
  432. * UUID: 'u' + 16 byte unsigned integer<br>
  433. * String: 's' + 4 byte integer size + string<br>
  434. * Date: 'd' + 8 byte IEEE double for seconds since epoch<br>
  435. * URI: 'l' + 4 byte integer size + string uri<br>
  436. * Binary: 'b' + 4 byte integer size + binary data<br>
  437. * Array: '[' + 4 byte integer size + all values + ']'<br>
  438. * Map: '{' + 4 byte integer size every(key + value) + '}'<br>
  439. * map keys are serialized as 'k' + 4 byte integer size + string
  440. */
  441. class LLSDBinaryFormatter final : public LLSDFormatter
  442. {
  443. protected:
  444. ~LLSDBinaryFormatter() override = default;
  445. public:
  446. LLSDBinaryFormatter(bool bool_apha = false,
  447. const std::string& real_format = "",
  448. EFormatterOptions options = OPTIONS_PRETTY_BINARY);
  449. protected:
  450. /**
  451. * @brief Implementation to format the data. This is called recursively.
  452. *
  453. * @param data The data to write.
  454. * @param ostr The destination stream for the data.
  455. * @return Returns The number of LLSD objects fomatted out
  456. */
  457. S32 format_impl(const LLSD& data, std::ostream& ostr,
  458. EFormatterOptions options,
  459. U32 level) const override;
  460. /**
  461. * @brief Helper method to serialize strings
  462. *
  463. * This method serializes a network byte order size and the raw
  464. * string contents.
  465. * @param string The string to write.
  466. * @param ostr The destination stream for the data.
  467. */
  468. void formatString(const std::string& string, std::ostream& ostr) const;
  469. };
  470. /**
  471. * @class LLSDNotationStreamFormatter
  472. * @brief Formatter which is specialized for use on streams which
  473. * outputs the original notation format for LLSD.
  474. *
  475. * This class is useful for doing inline stream operations. For example:
  476. *
  477. * <code>
  478. * LLSD sd;<br>
  479. * sd["foo"] = "bar";<br>
  480. * std::stringstream params;<br>
  481. * params << "[{'version':i1}," << LLSDOStreamer<LLSDNotationFormatter>(sd)
  482. * << "]";
  483. * </code>
  484. *
  485. * *NOTE - formerly this class inherited from its template parameter Formatter,
  486. * but all instantiations passed in LLRefCount subclasses. This conflicted with
  487. * the auto allocation intended for this class template (demonstrated in the
  488. * example above). -brad
  489. */
  490. template <class Formatter>
  491. class LLSDOStreamer
  492. {
  493. public:
  494. LLSDOStreamer(const LLSD& data,
  495. LLSDFormatter::EFormatterOptions options =
  496. LLSDFormatter::OPTIONS_PRETTY_BINARY)
  497. : mSD(data),
  498. mOptions(options)
  499. {
  500. }
  501. // Use this inline during construction during a stream operation.
  502. // 'str' is the destination stream for serialized output.
  503. // 'formatter' is the formatter which will output its LLSD.
  504. // Returns the stream passed in after streaming mSD.
  505. friend std::ostream& operator<<(std::ostream& str,
  506. const LLSDOStreamer<Formatter>& formatter)
  507. {
  508. LLPointer<Formatter> f = new Formatter;
  509. f->format(formatter.mSD, str, formatter.mOptions);
  510. return str;
  511. }
  512. protected:
  513. LLSD mSD;
  514. LLSDFormatter::EFormatterOptions mOptions;
  515. };
  516. typedef LLSDOStreamer<LLSDNotationFormatter> LLSDNotationStreamer;
  517. typedef LLSDOStreamer<LLSDXMLFormatter> LLSDXMLStreamer;
  518. // Serializer / deserializer class for the various LLSD formats
  519. class LLSDSerialize
  520. {
  521. protected:
  522. LOG_CLASS(LLSDSerialize);
  523. public:
  524. enum ELLSD_Serialize
  525. {
  526. LLSD_BINARY, LLSD_XML, LLSD_NOTATION
  527. };
  528. // Anonymous enumeration for useful max_bytes constants.
  529. enum
  530. {
  531. // Setting an unlimited size is discouraged and should only be
  532. // used when reading cin or another stream source which does
  533. // not provide access to size.
  534. SIZE_UNLIMITED = -1,
  535. };
  536. // Generic input/output methods
  537. static void serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize,
  538. LLSDFormatter::EFormatterOptions options =
  539. LLSDFormatter::OPTIONS_PRETTY_BINARY);
  540. // Examines a stream, and parse 1 sd object out based on contents.
  541. // Returns true if the stream appears to contain valid data
  542. // 'sd' is the output for the data found on the stream
  543. // 'str' is the incoming stream
  544. // 'max_bytes' is the maximum number of bytes to parse
  545. static bool deserialize(LLSD& sd, std::istream& str, llssize max_bytes);
  546. // Notation methods
  547. static S32 toNotation(const LLSD& sd, std::ostream& str)
  548. {
  549. LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
  550. return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
  551. }
  552. static S32 toPrettyNotation(const LLSD& sd, std::ostream& str)
  553. {
  554. LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
  555. return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
  556. }
  557. static S32 toPrettyBinaryNotation(const LLSD& sd, std::ostream& str)
  558. {
  559. LLPointer<LLSDNotationFormatter> f = new LLSDNotationFormatter;
  560. const LLSDFormatter::EFormatterOptions options =
  561. LLSDFormatter::EFormatterOptions(LLSDFormatter::OPTIONS_PRETTY |
  562. LLSDFormatter::OPTIONS_PRETTY_BINARY);
  563. return f->format(sd, str, options);
  564. }
  565. static S32 fromNotation(LLSD& sd, std::istream& str, llssize max_bytes)
  566. {
  567. LLPointer<LLSDNotationParser> p = new LLSDNotationParser;
  568. return p->parse(str, sd, max_bytes);
  569. }
  570. static LLSD fromNotation(std::istream& str, llssize max_bytes)
  571. {
  572. LLPointer<LLSDNotationParser> p = new LLSDNotationParser;
  573. LLSD sd;
  574. (void)p->parse(str, sd, max_bytes);
  575. return sd;
  576. }
  577. // XML methods
  578. static S32 toXML(const LLSD& sd, std::ostream& str)
  579. {
  580. LLPointer<LLSDXMLFormatter> f = new LLSDXMLFormatter;
  581. return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
  582. }
  583. static S32 toPrettyXML(const LLSD& sd, std::ostream& str)
  584. {
  585. LLPointer<LLSDXMLFormatter> f = new LLSDXMLFormatter;
  586. return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
  587. }
  588. static S32 fromXMLEmbedded(LLSD& sd, std::istream& str,
  589. bool emit_errors = true)
  590. {
  591. // No need for max_bytes since xml formatting is not subvertable by
  592. // bad sizes.
  593. LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
  594. return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
  595. }
  596. // Line oriented parser, 30% faster than fromXML(), but can
  597. // only be used when you know you have the complete XML
  598. // document available in the stream.
  599. static S32 fromXMLDocument(LLSD& sd, std::istream& str,
  600. bool emit_errors = true)
  601. {
  602. LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
  603. return p->parseLines(str, sd);
  604. }
  605. static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors = true)
  606. {
  607. #if 1
  608. return fromXMLEmbedded(sd, str, emit_errors);
  609. #else
  610. return fromXMLDocument(sd, str, emit_errors);
  611. #endif
  612. }
  613. // Binary methods
  614. static S32 toBinary(const LLSD& sd, std::ostream& str)
  615. {
  616. LLPointer<LLSDBinaryFormatter> f = new LLSDBinaryFormatter;
  617. return f->format(sd, str, LLSDFormatter::OPTIONS_NONE);
  618. }
  619. static S32 fromBinary(LLSD& sd, std::istream& str, llssize max_bytes,
  620. S32 max_depth = -1)
  621. {
  622. LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser;
  623. return p->parse(str, sd, max_bytes, max_depth);
  624. }
  625. static LLSD fromBinary(std::istream& str, llssize max_bytes,
  626. S32 max_depth = -1)
  627. {
  628. LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser;
  629. LLSD sd;
  630. (void)p->parse(str, sd, max_bytes, max_depth);
  631. return sd;
  632. }
  633. };
  634. // Dirty little zip functions
  635. std::string zip_llsd(LLSD& data);
  636. bool unzip_llsd(LLSD& data, const U8* in, S32 size);
  637. bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
  638. U8* unzip_llsdNavMesh(bool& valid, size_t& outsize, const U8* in, S32 size);
  639. #endif // LL_LLSDSERIALIZE_H