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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llsdserialize.cpp
  3.  * @author Phoenix
  4.  * @date 2006-03-05
  5.  * @brief Implementation of LLSD parsers and formatters
  6.  *
  7.  * $LicenseInfo:firstyear=2006&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2006-2010, 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. #include "linden_common.h"
  35. #include "llsdserialize.h"
  36. #include "llpointer.h"
  37. #include "llstreamtools.h" // for fullread
  38. #include <iostream>
  39. #include "apr_base64.h"
  40. #if !LL_WINDOWS
  41. #include <netinet/in.h> // htonl & ntohl
  42. #endif
  43. #include "lldate.h"
  44. #include "llsd.h"
  45. #include "llstring.h"
  46. #include "lluri.h"
  47. // File constants
  48. static const int MAX_HDR_LEN = 20;
  49. static const char LEGACY_NON_HEADER[] = "<llsd>";
  50. const std::string LLSD_BINARY_HEADER("LLSD/Binary");
  51. const std::string LLSD_XML_HEADER("LLSD/XML");
  52. /**
  53.  * LLSDSerialize
  54.  */
  55. // static
  56. void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize type, U32 options)
  57. {
  58. LLPointer<LLSDFormatter> f = NULL;
  59. switch (type)
  60. {
  61. case LLSD_BINARY:
  62. str << "<? " << LLSD_BINARY_HEADER << " ?>n";
  63. f = new LLSDBinaryFormatter;
  64. break;
  65. case LLSD_XML:
  66. str << "<? " << LLSD_XML_HEADER << " ?>n";
  67. f = new LLSDXMLFormatter;
  68. break;
  69. default:
  70. llwarns << "serialize request for unkown ELLSD_Serialize" << llendl;
  71. }
  72. if (f.notNull())
  73. {
  74. f->format(sd, str, options);
  75. }
  76. }
  77. // static
  78. bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
  79. {
  80. LLPointer<LLSDParser> p = NULL;
  81. char hdr_buf[MAX_HDR_LEN + 1] = ""; /* Flawfinder: ignore */
  82. int i;
  83. int inbuf = 0;
  84. bool legacy_no_header = false;
  85. bool fail_if_not_legacy = false;
  86. std::string header;
  87. /*
  88.  * Get the first line before anything.
  89.  */
  90. str.get(hdr_buf, MAX_HDR_LEN, 'n');
  91. if (str.fail())
  92. {
  93. str.clear();
  94. fail_if_not_legacy = true;
  95. }
  96. if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */
  97. {
  98. legacy_no_header = true;
  99. inbuf = str.gcount();
  100. }
  101. else
  102. {
  103. if (fail_if_not_legacy)
  104. goto fail;
  105. /*
  106. * Remove the newline chars
  107. */
  108. for (i = 0; i < MAX_HDR_LEN; i++)
  109. {
  110. if (hdr_buf[i] == 0 || hdr_buf[i] == 'r' ||
  111. hdr_buf[i] == 'n')
  112. {
  113. hdr_buf[i] = 0;
  114. break;
  115. }
  116. }
  117. header = hdr_buf;
  118. std::string::size_type start = std::string::npos;
  119. std::string::size_type end = std::string::npos;
  120. start = header.find_first_not_of("<? ");
  121. if (start != std::string::npos)
  122. {
  123. end = header.find_first_of(" ?", start);
  124. }
  125. if ((start == std::string::npos) || (end == std::string::npos))
  126. goto fail;
  127. header = header.substr(start, end - start);
  128. ws(str);
  129. }
  130. /*
  131.  * Create the parser as appropriate
  132.  */
  133. if (legacy_no_header)
  134. { // Create a LLSD XML parser, and parse the first chunk read above
  135. LLSDXMLParser* x = new LLSDXMLParser();
  136. x->parsePart(hdr_buf, inbuf); // Parse the first part that was already read
  137. x->parseLines(str, sd); // Parse the rest of it
  138. delete x;
  139. return true;
  140. }
  141. if (header == LLSD_BINARY_HEADER)
  142. {
  143. p = new LLSDBinaryParser;
  144. }
  145. else if (header == LLSD_XML_HEADER)
  146. {
  147. p = new LLSDXMLParser;
  148. }
  149. else
  150. {
  151. llwarns << "deserialize request for unknown ELLSD_Serialize" << llendl;
  152. }
  153. if (p.notNull())
  154. {
  155. p->parse(str, sd, max_bytes);
  156. return true;
  157. }
  158. fail:
  159. llwarns << "deserialize LLSD parse failure" << llendl;
  160. return false;
  161. }
  162. /**
  163.  * Endian handlers
  164.  */
  165. #if LL_BIG_ENDIAN
  166. U64 ll_htonll(U64 hostlonglong) { return hostlonglong; }
  167. U64 ll_ntohll(U64 netlonglong) { return netlonglong; }
  168. F64 ll_htond(F64 hostlonglong) { return hostlonglong; }
  169. F64 ll_ntohd(F64 netlonglong) { return netlonglong; }
  170. #else
  171. // I read some comments one a indicating that doing an integer add
  172. // here would be faster than a bitwise or. For now, the or has
  173. // programmer clarity, since the intended outcome matches the
  174. // operation.
  175. U64 ll_htonll(U64 hostlonglong)
  176. {
  177. return ((U64)(htonl((U32)((hostlonglong >> 32) & 0xFFFFFFFF))) |
  178. ((U64)(htonl((U32)(hostlonglong & 0xFFFFFFFF))) << 32));
  179. }
  180. U64 ll_ntohll(U64 netlonglong)
  181. {
  182. return ((U64)(ntohl((U32)((netlonglong >> 32) & 0xFFFFFFFF))) |
  183. ((U64)(ntohl((U32)(netlonglong & 0xFFFFFFFF))) << 32));
  184. }
  185. union LLEndianSwapper
  186. {
  187. F64 d;
  188. U64 i;
  189. };
  190. F64 ll_htond(F64 hostdouble)
  191. {
  192. LLEndianSwapper tmp;
  193. tmp.d = hostdouble;
  194. tmp.i = ll_htonll(tmp.i);
  195. return tmp.d;
  196. }
  197. F64 ll_ntohd(F64 netdouble)
  198. {
  199. LLEndianSwapper tmp;
  200. tmp.d = netdouble;
  201. tmp.i = ll_ntohll(tmp.i);
  202. return tmp.d;
  203. }
  204. #endif
  205. /**
  206.  * Local functions.
  207.  */
  208. /**
  209.  * @brief Figure out what kind of string it is (raw or delimited) and handoff.
  210.  *
  211.  * @param istr The stream to read from.
  212.  * @param value [out] The string which was found.
  213.  * @param max_bytes The maximum possible length of the string. Passing in
  214.  * a negative value will skip this check.
  215.  * @return Returns number of bytes read off of the stream. Returns
  216.  * PARSE_FAILURE (-1) on failure.
  217.  */
  218. int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes);
  219. /**
  220.  * @brief Parse a delimited string. 
  221.  *
  222.  * @param istr The stream to read from, with the delimiter already popped.
  223.  * @param value [out] The string which was found.
  224.  * @param d The delimiter to use.
  225.  * @return Returns number of bytes read off of the stream. Returns
  226.  * PARSE_FAILURE (-1) on failure.
  227.  */
  228. int deserialize_string_delim(std::istream& istr, std::string& value, char d);
  229. /**
  230.  * @brief Read a raw string off the stream.
  231.  *
  232.  * @param istr The stream to read from, with the (len) parameter
  233.  * leading the stream.
  234.  * @param value [out] The string which was found.
  235.  * @param d The delimiter to use.
  236.  * @param max_bytes The maximum possible length of the string. Passing in
  237.  * a negative value will skip this check.
  238.  * @return Returns number of bytes read off of the stream. Returns
  239.  * PARSE_FAILURE (-1) on failure.
  240.  */
  241. int deserialize_string_raw(
  242. std::istream& istr,
  243. std::string& value,
  244. S32 max_bytes);
  245. /**
  246.  * @brief helper method for dealing with the different notation boolean format.
  247.  *
  248.  * @param istr The stream to read from with the leading character stripped.
  249.  * @param data [out] the result of the parse.
  250.  * @param compare The string to compare the boolean against
  251.  * @param vale The value to assign to data if the parse succeeds.
  252.  * @return Returns number of bytes read off of the stream. Returns
  253.  * PARSE_FAILURE (-1) on failure.
  254.  */
  255. int deserialize_boolean(
  256. std::istream& istr,
  257. LLSD& data,
  258. const std::string& compare,
  259. bool value);
  260. /**
  261.  * @brief Do notation escaping of a string to an ostream.
  262.  *
  263.  * @param value The string to escape and serialize
  264.  * @param str The stream to serialize to.
  265.  */
  266. void serialize_string(const std::string& value, std::ostream& str);
  267. /**
  268.  * Local constants.
  269.  */
  270. static const std::string NOTATION_TRUE_SERIAL("true");
  271. static const std::string NOTATION_FALSE_SERIAL("false");
  272. static const char BINARY_TRUE_SERIAL = '1';
  273. static const char BINARY_FALSE_SERIAL = '0';
  274. /**
  275.  * LLSDParser
  276.  */
  277. LLSDParser::LLSDParser()
  278. : mCheckLimits(true), mMaxBytesLeft(0), mParseLines(false)
  279. {
  280. }
  281. // virtual
  282. LLSDParser::~LLSDParser()
  283. { }
  284. S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes)
  285. {
  286. mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true;
  287. mMaxBytesLeft = max_bytes;
  288. return doParse(istr, data);
  289. }
  290. // Parse using routine to get() lines, faster than parse()
  291. S32 LLSDParser::parseLines(std::istream& istr, LLSD& data)
  292. {
  293. mCheckLimits = false;
  294. mParseLines = true;
  295. return doParse(istr, data);
  296. }
  297. int LLSDParser::get(std::istream& istr) const
  298. {
  299. if(mCheckLimits) --mMaxBytesLeft;
  300. return istr.get();
  301. }
  302. std::istream& LLSDParser::get(
  303. std::istream& istr,
  304. char* s,
  305. std::streamsize n,
  306. char delim) const
  307. {
  308. istr.get(s, n, delim);
  309. if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
  310. return istr;
  311. }
  312. std::istream& LLSDParser::get(
  313. std::istream& istr,
  314. std::streambuf& sb,
  315. char delim) const
  316. {
  317. istr.get(sb, delim);
  318. if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
  319. return istr;
  320. }
  321. std::istream& LLSDParser::ignore(std::istream& istr) const
  322. {
  323. istr.ignore();
  324. if(mCheckLimits) --mMaxBytesLeft;
  325. return istr;
  326. }
  327. std::istream& LLSDParser::putback(std::istream& istr, char c) const
  328. {
  329. istr.putback(c);
  330. if(mCheckLimits) ++mMaxBytesLeft;
  331. return istr;
  332. }
  333. std::istream& LLSDParser::read(
  334. std::istream& istr,
  335. char* s,
  336. std::streamsize n) const
  337. {
  338. istr.read(s, n);
  339. if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
  340. return istr;
  341. }
  342. void LLSDParser::account(S32 bytes) const
  343. {
  344. if(mCheckLimits) mMaxBytesLeft -= bytes;
  345. }
  346. /**
  347.  * LLSDNotationParser
  348.  */
  349. LLSDNotationParser::LLSDNotationParser()
  350. {
  351. }
  352. // virtual
  353. LLSDNotationParser::~LLSDNotationParser()
  354. { }
  355. // virtual
  356. S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data) const
  357. {
  358. // map: { string:object, string:object }
  359. // array: [ object, object, object ]
  360. // undef: !
  361. // boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE
  362. // integer: i####
  363. // real: r####
  364. // uuid: u####
  365. // string: "g'day" | 'have a "nice" day' | s(size)"raw data"
  366. // uri: l"escaped"
  367. // date: d"YYYY-MM-DDTHH:MM:SS.FFZ"
  368. // binary: b##"ff3120ab1" | b(size)"raw data"
  369. char c;
  370. c = istr.peek();
  371. while(isspace(c))
  372. {
  373. // pop the whitespace.
  374. c = get(istr);
  375. c = istr.peek();
  376. continue;
  377. }
  378. if(!istr.good())
  379. {
  380. return 0;
  381. }
  382. S32 parse_count = 1;
  383. switch(c)
  384. {
  385. case '{':
  386. {
  387. S32 child_count = parseMap(istr, data);
  388. if((child_count == PARSE_FAILURE) || data.isUndefined())
  389. {
  390. parse_count = PARSE_FAILURE;
  391. }
  392. else
  393. {
  394. parse_count += child_count;
  395. }
  396. if(istr.fail())
  397. {
  398. llinfos << "STREAM FAILURE reading map." << llendl;
  399. parse_count = PARSE_FAILURE;
  400. }
  401. break;
  402. }
  403. case '[':
  404. {
  405. S32 child_count = parseArray(istr, data);
  406. if((child_count == PARSE_FAILURE) || data.isUndefined())
  407. {
  408. parse_count = PARSE_FAILURE;
  409. }
  410. else
  411. {
  412. parse_count += child_count;
  413. }
  414. if(istr.fail())
  415. {
  416. llinfos << "STREAM FAILURE reading array." << llendl;
  417. parse_count = PARSE_FAILURE;
  418. }
  419. break;
  420. }
  421. case '!':
  422. c = get(istr);
  423. data.clear();
  424. break;
  425. case '0':
  426. c = get(istr);
  427. data = false;
  428. break;
  429. case 'F':
  430. case 'f':
  431. ignore(istr);
  432. c = istr.peek();
  433. if(isalpha(c))
  434. {
  435. int cnt = deserialize_boolean(
  436. istr,
  437. data,
  438. NOTATION_FALSE_SERIAL,
  439. false);
  440. if(PARSE_FAILURE == cnt) parse_count = cnt;
  441. else account(cnt);
  442. }
  443. else
  444. {
  445. data = false;
  446. }
  447. if(istr.fail())
  448. {
  449. llinfos << "STREAM FAILURE reading boolean." << llendl;
  450. parse_count = PARSE_FAILURE;
  451. }
  452. break;
  453. case '1':
  454. c = get(istr);
  455. data = true;
  456. break;
  457. case 'T':
  458. case 't':
  459. ignore(istr);
  460. c = istr.peek();
  461. if(isalpha(c))
  462. {
  463. int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true);
  464. if(PARSE_FAILURE == cnt) parse_count = cnt;
  465. else account(cnt);
  466. }
  467. else
  468. {
  469. data = true;
  470. }
  471. if(istr.fail())
  472. {
  473. llinfos << "STREAM FAILURE reading boolean." << llendl;
  474. parse_count = PARSE_FAILURE;
  475. }
  476. break;
  477. case 'i':
  478. {
  479. c = get(istr);
  480. S32 integer = 0;
  481. istr >> integer;
  482. data = integer;
  483. if(istr.fail())
  484. {
  485. llinfos << "STREAM FAILURE reading integer." << llendl;
  486. parse_count = PARSE_FAILURE;
  487. }
  488. break;
  489. }
  490. case 'r':
  491. {
  492. c = get(istr);
  493. F64 real = 0.0;
  494. istr >> real;
  495. data = real;
  496. if(istr.fail())
  497. {
  498. llinfos << "STREAM FAILURE reading real." << llendl;
  499. parse_count = PARSE_FAILURE;
  500. }
  501. break;
  502. }
  503. case 'u':
  504. {
  505. c = get(istr);
  506. LLUUID id;
  507. istr >> id;
  508. data = id;
  509. if(istr.fail())
  510. {
  511. llinfos << "STREAM FAILURE reading uuid." << llendl;
  512. parse_count = PARSE_FAILURE;
  513. }
  514. break;
  515. }
  516. case '"':
  517. case ''':
  518. case 's':
  519. if(!parseString(istr, data))
  520. {
  521. parse_count = PARSE_FAILURE;
  522. }
  523. if(istr.fail())
  524. {
  525. llinfos << "STREAM FAILURE reading string." << llendl;
  526. parse_count = PARSE_FAILURE;
  527. }
  528. break;
  529. case 'l':
  530. {
  531. c = get(istr); // pop the 'l'
  532. c = get(istr); // pop the delimiter
  533. std::string str;
  534. int cnt = deserialize_string_delim(istr, str, c);
  535. if(PARSE_FAILURE == cnt)
  536. {
  537. parse_count = PARSE_FAILURE;
  538. }
  539. else
  540. {
  541. data = LLURI(str);
  542. account(cnt);
  543. }
  544. if(istr.fail())
  545. {
  546. llinfos << "STREAM FAILURE reading link." << llendl;
  547. parse_count = PARSE_FAILURE;
  548. }
  549. break;
  550. }
  551. case 'd':
  552. {
  553. c = get(istr); // pop the 'd'
  554. c = get(istr); // pop the delimiter
  555. std::string str;
  556. int cnt = deserialize_string_delim(istr, str, c);
  557. if(PARSE_FAILURE == cnt)
  558. {
  559. parse_count = PARSE_FAILURE;
  560. }
  561. else
  562. {
  563. data = LLDate(str);
  564. account(cnt);
  565. }
  566. if(istr.fail())
  567. {
  568. llinfos << "STREAM FAILURE reading date." << llendl;
  569. parse_count = PARSE_FAILURE;
  570. }
  571. break;
  572. }
  573. case 'b':
  574. if(!parseBinary(istr, data))
  575. {
  576. parse_count = PARSE_FAILURE;
  577. }
  578. if(istr.fail())
  579. {
  580. llinfos << "STREAM FAILURE reading data." << llendl;
  581. parse_count = PARSE_FAILURE;
  582. }
  583. break;
  584. default:
  585. parse_count = PARSE_FAILURE;
  586. llinfos << "Unrecognized character while parsing: int(" << (int)c
  587. << ")" << llendl;
  588. break;
  589. }
  590. if(PARSE_FAILURE == parse_count)
  591. {
  592. data.clear();
  593. }
  594. return parse_count;
  595. }
  596. S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map) const
  597. {
  598. // map: { string:object, string:object }
  599. map = LLSD::emptyMap();
  600. S32 parse_count = 0;
  601. char c = get(istr);
  602. if(c == '{')
  603. {
  604. // eat commas, white
  605. bool found_name = false;
  606. std::string name;
  607. c = get(istr);
  608. while(c != '}' && istr.good())
  609. {
  610. if(!found_name)
  611. {
  612. if((c == '"') || (c == ''') || (c == 's'))
  613. {
  614. putback(istr, c);
  615. found_name = true;
  616. int count = deserialize_string(istr, name, mMaxBytesLeft);
  617. if(PARSE_FAILURE == count) return PARSE_FAILURE;
  618. account(count);
  619. }
  620. c = get(istr);
  621. }
  622. else
  623. {
  624. if(isspace(c) || (c == ':'))
  625. {
  626. c = get(istr);
  627. continue;
  628. }
  629. putback(istr, c);
  630. LLSD child;
  631. S32 count = doParse(istr, child);
  632. if(count > 0)
  633. {
  634. // There must be a value for every key, thus
  635. // child_count must be greater than 0.
  636. parse_count += count;
  637. map.insert(name, child);
  638. }
  639. else
  640. {
  641. return PARSE_FAILURE;
  642. }
  643. found_name = false;
  644. c = get(istr);
  645. }
  646. }
  647. if(c != '}')
  648. {
  649. map.clear();
  650. return PARSE_FAILURE;
  651. }
  652. }
  653. return parse_count;
  654. }
  655. S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array) const
  656. {
  657. // array: [ object, object, object ]
  658. array = LLSD::emptyArray();
  659. S32 parse_count = 0;
  660. char c = get(istr);
  661. if(c == '[')
  662. {
  663. // eat commas, white
  664. c = get(istr);
  665. while((c != ']') && istr.good())
  666. {
  667. LLSD child;
  668. if(isspace(c) || (c == ','))
  669. {
  670. c = get(istr);
  671. continue;
  672. }
  673. putback(istr, c);
  674. S32 count = doParse(istr, child);
  675. if(PARSE_FAILURE == count)
  676. {
  677. return PARSE_FAILURE;
  678. }
  679. else
  680. {
  681. parse_count += count;
  682. array.append(child);
  683. }
  684. c = get(istr);
  685. }
  686. if(c != ']')
  687. {
  688. return PARSE_FAILURE;
  689. }
  690. }
  691. return parse_count;
  692. }
  693. bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const
  694. {
  695. std::string value;
  696. int count = deserialize_string(istr, value, mMaxBytesLeft);
  697. if(PARSE_FAILURE == count) return false;
  698. account(count);
  699. data = value;
  700. return true;
  701. }
  702. bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
  703. {
  704. // binary: b##"ff3120ab1"
  705. // or: b(len)"..."
  706. // I want to manually control those values here to make sure the
  707. // parser doesn't break when someone changes a constant somewhere
  708. // else.
  709. const U32 BINARY_BUFFER_SIZE = 256;
  710. const U32 STREAM_GET_COUNT = 255;
  711. // need to read the base out.
  712. char buf[BINARY_BUFFER_SIZE]; /* Flawfinder: ignore */
  713. get(istr, buf, STREAM_GET_COUNT, '"');
  714. char c = get(istr);
  715. if(c != '"') return false;
  716. if(0 == strncmp("b(", buf, 2))
  717. {
  718. // We probably have a valid raw binary stream. determine
  719. // the size, and read it.
  720. S32 len = strtol(buf + 2, NULL, 0);
  721. if(mCheckLimits && (len > mMaxBytesLeft)) return false;
  722. std::vector<U8> value;
  723. if(len)
  724. {
  725. value.resize(len);
  726. account(fullread(istr, (char *)&value[0], len));
  727. }
  728. c = get(istr); // strip off the trailing double-quote
  729. data = value;
  730. }
  731. else if(0 == strncmp("b64", buf, 3))
  732. {
  733. // *FIX: A bit inefficient, but works for now. To make the
  734. // format better, I would need to add a hint into the
  735. // serialization format that indicated how long it was.
  736. std::stringstream coded_stream;
  737. get(istr, *(coded_stream.rdbuf()), '"');
  738. c = get(istr);
  739. std::string encoded(coded_stream.str());
  740. S32 len = apr_base64_decode_len(encoded.c_str());
  741. std::vector<U8> value;
  742. if(len)
  743. {
  744. value.resize(len);
  745. len = apr_base64_decode_binary(&value[0], encoded.c_str());
  746. value.resize(len);
  747. }
  748. data = value;
  749. }
  750. else if(0 == strncmp("b16", buf, 3))
  751. {
  752. // yay, base 16. We pop the next character which is either a
  753. // double quote or base 16 data. If it's a double quote, we're
  754. // done parsing. If it's not, put the data back, and read the
  755. // stream until the next double quote.
  756. char* read;  /*Flawfinder: ignore*/
  757. U8 byte;
  758. U8 byte_buffer[BINARY_BUFFER_SIZE];
  759. U8* write;
  760. std::vector<U8> value;
  761. c = get(istr);
  762. while(c != '"')
  763. {
  764. putback(istr, c);
  765. read = buf;
  766. write = byte_buffer;
  767. get(istr, buf, STREAM_GET_COUNT, '"');
  768. c = get(istr);
  769. while(*read != '')  /*Flawfinder: ignore*/
  770. {
  771. byte = hex_as_nybble(*read++);
  772. byte = byte << 4;
  773. byte |= hex_as_nybble(*read++);
  774. *write++ = byte;
  775. }
  776. // copy the data out of the byte buffer
  777. value.insert(value.end(), byte_buffer, write);
  778. }
  779. data = value;
  780. }
  781. else
  782. {
  783. return false;
  784. }
  785. return true;
  786. }
  787. /**
  788.  * LLSDBinaryParser
  789.  */
  790. LLSDBinaryParser::LLSDBinaryParser()
  791. {
  792. }
  793. // virtual
  794. LLSDBinaryParser::~LLSDBinaryParser()
  795. {
  796. }
  797. // virtual
  798. S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
  799. {
  800. /**
  801.  * Undefined: '!'<br>
  802.  * Boolean: 't' for true 'f' for false<br>
  803.  * Integer: 'i' + 4 bytes network byte order<br>
  804.  * Real: 'r' + 8 bytes IEEE double<br>
  805.  * UUID: 'u' + 16 byte unsigned integer<br>
  806.  * String: 's' + 4 byte integer size + string<br>
  807.  *  strings also secretly support the notation format
  808.  * Date: 'd' + 8 byte IEEE double for seconds since epoch<br>
  809.  * URI: 'l' + 4 byte integer size + string uri<br>
  810.  * Binary: 'b' + 4 byte integer size + binary data<br>
  811.  * Array: '[' + 4 byte integer size  + all values + ']'<br>
  812.  * Map: '{' + 4 byte integer size  every(key + value) + '}'<br>
  813.  *  map keys are serialized as s + 4 byte integer size + string or in the
  814.  *  notation format.
  815.  */
  816. char c;
  817. c = get(istr);
  818. if(!istr.good())
  819. {
  820. return 0;
  821. }
  822. S32 parse_count = 1;
  823. switch(c)
  824. {
  825. case '{':
  826. {
  827. S32 child_count = parseMap(istr, data);
  828. if((child_count == PARSE_FAILURE) || data.isUndefined())
  829. {
  830. parse_count = PARSE_FAILURE;
  831. }
  832. else
  833. {
  834. parse_count += child_count;
  835. }
  836. if(istr.fail())
  837. {
  838. llinfos << "STREAM FAILURE reading binary map." << llendl;
  839. parse_count = PARSE_FAILURE;
  840. }
  841. break;
  842. }
  843. case '[':
  844. {
  845. S32 child_count = parseArray(istr, data);
  846. if((child_count == PARSE_FAILURE) || data.isUndefined())
  847. {
  848. parse_count = PARSE_FAILURE;
  849. }
  850. else
  851. {
  852. parse_count += child_count;
  853. }
  854. if(istr.fail())
  855. {
  856. llinfos << "STREAM FAILURE reading binary array." << llendl;
  857. parse_count = PARSE_FAILURE;
  858. }
  859. break;
  860. }
  861. case '!':
  862. data.clear();
  863. break;
  864. case '0':
  865. data = false;
  866. break;
  867. case '1':
  868. data = true;
  869. break;
  870. case 'i':
  871. {
  872. U32 value_nbo = 0;
  873. read(istr, (char*)&value_nbo, sizeof(U32));  /*Flawfinder: ignore*/
  874. data = (S32)ntohl(value_nbo);
  875. if(istr.fail())
  876. {
  877. llinfos << "STREAM FAILURE reading binary integer." << llendl;
  878. }
  879. break;
  880. }
  881. case 'r':
  882. {
  883. F64 real_nbo = 0.0;
  884. read(istr, (char*)&real_nbo, sizeof(F64));  /*Flawfinder: ignore*/
  885. data = ll_ntohd(real_nbo);
  886. if(istr.fail())
  887. {
  888. llinfos << "STREAM FAILURE reading binary real." << llendl;
  889. }
  890. break;
  891. }
  892. case 'u':
  893. {
  894. LLUUID id;
  895. read(istr, (char*)(&id.mData), UUID_BYTES);  /*Flawfinder: ignore*/
  896. data = id;
  897. if(istr.fail())
  898. {
  899. llinfos << "STREAM FAILURE reading binary uuid." << llendl;
  900. }
  901. break;
  902. }
  903. case ''':
  904. case '"':
  905. {
  906. std::string value;
  907. int cnt = deserialize_string_delim(istr, value, c);
  908. if(PARSE_FAILURE == cnt)
  909. {
  910. parse_count = PARSE_FAILURE;
  911. }
  912. else
  913. {
  914. data = value;
  915. account(cnt);
  916. }
  917. if(istr.fail())
  918. {
  919. llinfos << "STREAM FAILURE reading binary (notation-style) string."
  920. << llendl;
  921. parse_count = PARSE_FAILURE;
  922. }
  923. break;
  924. }
  925. case 's':
  926. {
  927. std::string value;
  928. if(parseString(istr, value))
  929. {
  930. data = value;
  931. }
  932. else
  933. {
  934. parse_count = PARSE_FAILURE;
  935. }
  936. if(istr.fail())
  937. {
  938. llinfos << "STREAM FAILURE reading binary string." << llendl;
  939. parse_count = PARSE_FAILURE;
  940. }
  941. break;
  942. }
  943. case 'l':
  944. {
  945. std::string value;
  946. if(parseString(istr, value))
  947. {
  948. data = LLURI(value);
  949. }
  950. else
  951. {
  952. parse_count = PARSE_FAILURE;
  953. }
  954. if(istr.fail())
  955. {
  956. llinfos << "STREAM FAILURE reading binary link." << llendl;
  957. parse_count = PARSE_FAILURE;
  958. }
  959. break;
  960. }
  961. case 'd':
  962. {
  963. F64 real = 0.0;
  964. read(istr, (char*)&real, sizeof(F64));  /*Flawfinder: ignore*/
  965. data = LLDate(real);
  966. if(istr.fail())
  967. {
  968. llinfos << "STREAM FAILURE reading binary date." << llendl;
  969. parse_count = PARSE_FAILURE;
  970. }
  971. break;
  972. }
  973. case 'b':
  974. {
  975. // We probably have a valid raw binary stream. determine
  976. // the size, and read it.
  977. U32 size_nbo = 0;
  978. read(istr, (char*)&size_nbo, sizeof(U32)); /*Flawfinder: ignore*/
  979. S32 size = (S32)ntohl(size_nbo);
  980. if(mCheckLimits && (size > mMaxBytesLeft))
  981. {
  982. parse_count = PARSE_FAILURE;
  983. }
  984. else
  985. {
  986. std::vector<U8> value;
  987. if(size > 0)
  988. {
  989. value.resize(size);
  990. account(fullread(istr, (char*)&value[0], size));
  991. }
  992. data = value;
  993. }
  994. if(istr.fail())
  995. {
  996. llinfos << "STREAM FAILURE reading binary." << llendl;
  997. parse_count = PARSE_FAILURE;
  998. }
  999. break;
  1000. }
  1001. default:
  1002. parse_count = PARSE_FAILURE;
  1003. llinfos << "Unrecognized character while parsing: int(" << (int)c
  1004. << ")" << llendl;
  1005. break;
  1006. }
  1007. if(PARSE_FAILURE == parse_count)
  1008. {
  1009. data.clear();
  1010. }
  1011. return parse_count;
  1012. }
  1013. S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map) const
  1014. {
  1015. map = LLSD::emptyMap();
  1016. U32 value_nbo = 0;
  1017. read(istr, (char*)&value_nbo, sizeof(U32));  /*Flawfinder: ignore*/
  1018. S32 size = (S32)ntohl(value_nbo);
  1019. S32 parse_count = 0;
  1020. S32 count = 0;
  1021. char c = get(istr);
  1022. while(c != '}' && (count < size) && istr.good())
  1023. {
  1024. std::string name;
  1025. switch(c)
  1026. {
  1027. case 'k':
  1028. if(!parseString(istr, name))
  1029. {
  1030. return PARSE_FAILURE;
  1031. }
  1032. break;
  1033. case ''':
  1034. case '"':
  1035. {
  1036. int cnt = deserialize_string_delim(istr, name, c);
  1037. if(PARSE_FAILURE == cnt) return PARSE_FAILURE;
  1038. account(cnt);
  1039. break;
  1040. }
  1041. }
  1042. LLSD child;
  1043. S32 child_count = doParse(istr, child);
  1044. if(child_count > 0)
  1045. {
  1046. // There must be a value for every key, thus child_count
  1047. // must be greater than 0.
  1048. parse_count += child_count;
  1049. map.insert(name, child);
  1050. }
  1051. else
  1052. {
  1053. return PARSE_FAILURE;
  1054. }
  1055. ++count;
  1056. c = get(istr);
  1057. }
  1058. if((c != '}') || (count < size))
  1059. {
  1060. // Make sure it is correctly terminated and we parsed as many
  1061. // as were said to be there.
  1062. return PARSE_FAILURE;
  1063. }
  1064. return parse_count;
  1065. }
  1066. S32 LLSDBinaryParser::parseArray(std::istream& istr, LLSD& array) const
  1067. {
  1068. array = LLSD::emptyArray();
  1069. U32 value_nbo = 0;
  1070. read(istr, (char*)&value_nbo, sizeof(U32));  /*Flawfinder: ignore*/
  1071. S32 size = (S32)ntohl(value_nbo);
  1072. // *FIX: This would be a good place to reserve some space in the
  1073. // array...
  1074. S32 parse_count = 0;
  1075. S32 count = 0;
  1076. char c = istr.peek();
  1077. while((c != ']') && (count < size) && istr.good())
  1078. {
  1079. LLSD child;
  1080. S32 child_count = doParse(istr, child);
  1081. if(PARSE_FAILURE == child_count)
  1082. {
  1083. return PARSE_FAILURE;
  1084. }
  1085. if(child_count)
  1086. {
  1087. parse_count += child_count;
  1088. array.append(child);
  1089. }
  1090. ++count;
  1091. c = istr.peek();
  1092. }
  1093. c = get(istr);
  1094. if((c != ']') || (count < size))
  1095. {
  1096. // Make sure it is correctly terminated and we parsed as many
  1097. // as were said to be there.
  1098. return PARSE_FAILURE;
  1099. }
  1100. return parse_count;
  1101. }
  1102. bool LLSDBinaryParser::parseString(
  1103. std::istream& istr,
  1104. std::string& value) const
  1105. {
  1106. // *FIX: This is memory inefficient.
  1107. U32 value_nbo = 0;
  1108. read(istr, (char*)&value_nbo, sizeof(U32));  /*Flawfinder: ignore*/
  1109. S32 size = (S32)ntohl(value_nbo);
  1110. if(mCheckLimits && (size > mMaxBytesLeft)) return false;
  1111. std::vector<char> buf;
  1112. if(size)
  1113. {
  1114. buf.resize(size);
  1115. account(fullread(istr, &buf[0], size));
  1116. value.assign(buf.begin(), buf.end());
  1117. }
  1118. return true;
  1119. }
  1120. /**
  1121.  * LLSDFormatter
  1122.  */
  1123. LLSDFormatter::LLSDFormatter() :
  1124. mBoolAlpha(false)
  1125. {
  1126. }
  1127. // virtual
  1128. LLSDFormatter::~LLSDFormatter()
  1129. { }
  1130. void LLSDFormatter::boolalpha(bool alpha)
  1131. {
  1132. mBoolAlpha = alpha;
  1133. }
  1134. void LLSDFormatter::realFormat(const std::string& format)
  1135. {
  1136. mRealFormat = format;
  1137. }
  1138. void LLSDFormatter::formatReal(LLSD::Real real, std::ostream& ostr) const
  1139. {
  1140. std::string buffer = llformat(mRealFormat.c_str(), real);
  1141. ostr << buffer;
  1142. }
  1143. /**
  1144.  * LLSDNotationFormatter
  1145.  */
  1146. LLSDNotationFormatter::LLSDNotationFormatter()
  1147. {
  1148. }
  1149. // virtual
  1150. LLSDNotationFormatter::~LLSDNotationFormatter()
  1151. { }
  1152. // static
  1153. std::string LLSDNotationFormatter::escapeString(const std::string& in)
  1154. {
  1155. std::ostringstream ostr;
  1156. serialize_string(in, ostr);
  1157. return ostr.str();
  1158. }
  1159. // virtual
  1160. S32 LLSDNotationFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
  1161. {
  1162. S32 format_count = 1;
  1163. switch(data.type())
  1164. {
  1165. case LLSD::TypeMap:
  1166. {
  1167. ostr << "{";
  1168. bool need_comma = false;
  1169. LLSD::map_const_iterator iter = data.beginMap();
  1170. LLSD::map_const_iterator end = data.endMap();
  1171. for(; iter != end; ++iter)
  1172. {
  1173. if(need_comma) ostr << ",";
  1174. need_comma = true;
  1175. ostr << ''';
  1176. serialize_string((*iter).first, ostr);
  1177. ostr << "':";
  1178. format_count += format((*iter).second, ostr);
  1179. }
  1180. ostr << "}";
  1181. break;
  1182. }
  1183. case LLSD::TypeArray:
  1184. {
  1185. ostr << "[";
  1186. bool need_comma = false;
  1187. LLSD::array_const_iterator iter = data.beginArray();
  1188. LLSD::array_const_iterator end = data.endArray();
  1189. for(; iter != end; ++iter)
  1190. {
  1191. if(need_comma) ostr << ",";
  1192. need_comma = true;
  1193. format_count += format(*iter, ostr);
  1194. }
  1195. ostr << "]";
  1196. break;
  1197. }
  1198. case LLSD::TypeUndefined:
  1199. ostr << "!";
  1200. break;
  1201. case LLSD::TypeBoolean:
  1202. if(mBoolAlpha ||
  1203. #if( LL_WINDOWS || __GNUC__ > 2)
  1204.    (ostr.flags() & std::ios::boolalpha)
  1205. #else
  1206.    (ostr.flags() & 0x0100)
  1207. #endif
  1208. )
  1209. {
  1210. ostr << (data.asBoolean()
  1211.  ? NOTATION_TRUE_SERIAL : NOTATION_FALSE_SERIAL);
  1212. }
  1213. else
  1214. {
  1215. ostr << (data.asBoolean() ? 1 : 0);
  1216. }
  1217. break;
  1218. case LLSD::TypeInteger:
  1219. ostr << "i" << data.asInteger();
  1220. break;
  1221. case LLSD::TypeReal:
  1222. ostr << "r";
  1223. if(mRealFormat.empty())
  1224. {
  1225. ostr << data.asReal();
  1226. }
  1227. else
  1228. {
  1229. formatReal(data.asReal(), ostr);
  1230. }
  1231. break;
  1232. case LLSD::TypeUUID:
  1233. ostr << "u" << data.asUUID();
  1234. break;
  1235. case LLSD::TypeString:
  1236. ostr << ''';
  1237. serialize_string(data.asString(), ostr);
  1238. ostr << ''';
  1239. break;
  1240. case LLSD::TypeDate:
  1241. ostr << "d"" << data.asDate() << """;
  1242. break;
  1243. case LLSD::TypeURI:
  1244. ostr << "l"";
  1245. serialize_string(data.asString(), ostr);
  1246. ostr << """;
  1247. break;
  1248. case LLSD::TypeBinary:
  1249. {
  1250. // *FIX: memory inefficient.
  1251. std::vector<U8> buffer = data.asBinary();
  1252. ostr << "b(" << buffer.size() << ")"";
  1253. if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
  1254. ostr << """;
  1255. break;
  1256. }
  1257. default:
  1258. // *NOTE: This should never happen.
  1259. ostr << "!";
  1260. break;
  1261. }
  1262. return format_count;
  1263. }
  1264. /**
  1265.  * LLSDBinaryFormatter
  1266.  */
  1267. LLSDBinaryFormatter::LLSDBinaryFormatter()
  1268. {
  1269. }
  1270. // virtual
  1271. LLSDBinaryFormatter::~LLSDBinaryFormatter()
  1272. { }
  1273. // virtual
  1274. S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 options) const
  1275. {
  1276. S32 format_count = 1;
  1277. switch(data.type())
  1278. {
  1279. case LLSD::TypeMap:
  1280. {
  1281. ostr.put('{');
  1282. U32 size_nbo = htonl(data.size());
  1283. ostr.write((const char*)(&size_nbo), sizeof(U32));
  1284. LLSD::map_const_iterator iter = data.beginMap();
  1285. LLSD::map_const_iterator end = data.endMap();
  1286. for(; iter != end; ++iter)
  1287. {
  1288. ostr.put('k');
  1289. formatString((*iter).first, ostr);
  1290. format_count += format((*iter).second, ostr);
  1291. }
  1292. ostr.put('}');
  1293. break;
  1294. }
  1295. case LLSD::TypeArray:
  1296. {
  1297. ostr.put('[');
  1298. U32 size_nbo = htonl(data.size());
  1299. ostr.write((const char*)(&size_nbo), sizeof(U32));
  1300. LLSD::array_const_iterator iter = data.beginArray();
  1301. LLSD::array_const_iterator end = data.endArray();
  1302. for(; iter != end; ++iter)
  1303. {
  1304. format_count += format(*iter, ostr);
  1305. }
  1306. ostr.put(']');
  1307. break;
  1308. }
  1309. case LLSD::TypeUndefined:
  1310. ostr.put('!');
  1311. break;
  1312. case LLSD::TypeBoolean:
  1313. if(data.asBoolean()) ostr.put(BINARY_TRUE_SERIAL);
  1314. else ostr.put(BINARY_FALSE_SERIAL);
  1315. break;
  1316. case LLSD::TypeInteger:
  1317. {
  1318. ostr.put('i');
  1319. U32 value_nbo = htonl(data.asInteger());
  1320. ostr.write((const char*)(&value_nbo), sizeof(U32));
  1321. break;
  1322. }
  1323. case LLSD::TypeReal:
  1324. {
  1325. ostr.put('r');
  1326. F64 value_nbo = ll_htond(data.asReal());
  1327. ostr.write((const char*)(&value_nbo), sizeof(F64));
  1328. break;
  1329. }
  1330. case LLSD::TypeUUID:
  1331. ostr.put('u');
  1332. ostr.write((const char*)(&(data.asUUID().mData)), UUID_BYTES);
  1333. break;
  1334. case LLSD::TypeString:
  1335. ostr.put('s');
  1336. formatString(data.asString(), ostr);
  1337. break;
  1338. case LLSD::TypeDate:
  1339. {
  1340. ostr.put('d');
  1341. F64 value = data.asReal();
  1342. ostr.write((const char*)(&value), sizeof(F64));
  1343. break;
  1344. }
  1345. case LLSD::TypeURI:
  1346. ostr.put('l');
  1347. formatString(data.asString(), ostr);
  1348. break;
  1349. case LLSD::TypeBinary:
  1350. {
  1351. // *FIX: memory inefficient.
  1352. ostr.put('b');
  1353. std::vector<U8> buffer = data.asBinary();
  1354. U32 size_nbo = htonl(buffer.size());
  1355. ostr.write((const char*)(&size_nbo), sizeof(U32));
  1356. if(buffer.size()) ostr.write((const char*)&buffer[0], buffer.size());
  1357. break;
  1358. }
  1359. default:
  1360. // *NOTE: This should never happen.
  1361. ostr.put('!');
  1362. break;
  1363. }
  1364. return format_count;
  1365. }
  1366. void LLSDBinaryFormatter::formatString(
  1367. const std::string& string,
  1368. std::ostream& ostr) const
  1369. {
  1370. U32 size_nbo = htonl(string.size());
  1371. ostr.write((const char*)(&size_nbo), sizeof(U32));
  1372. ostr.write(string.c_str(), string.size());
  1373. }
  1374. /**
  1375.  * local functions
  1376.  */
  1377. int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes)
  1378. {
  1379. int c = istr.get();
  1380. if(istr.fail())
  1381. {
  1382. // No data in stream, bail out but mention the character we
  1383. // grabbed.
  1384. return LLSDParser::PARSE_FAILURE;
  1385. }
  1386. int rv = LLSDParser::PARSE_FAILURE;
  1387. switch(c)
  1388. {
  1389. case ''':
  1390. case '"':
  1391. rv = deserialize_string_delim(istr, value, c);
  1392. break;
  1393. case 's':
  1394. // technically, less than max_bytes, but this is just meant to
  1395. // catch egregious protocol errors. parse errors will be
  1396. // caught in the case of incorrect counts.
  1397. rv = deserialize_string_raw(istr, value, max_bytes);
  1398. break;
  1399. default:
  1400. break;
  1401. }
  1402. if(LLSDParser::PARSE_FAILURE == rv) return rv;
  1403. return rv + 1; // account for the character grabbed at the top.
  1404. }
  1405. int deserialize_string_delim(
  1406. std::istream& istr,
  1407. std::string& value,
  1408. char delim)
  1409. {
  1410. std::ostringstream write_buffer;
  1411. bool found_escape = false;
  1412. bool found_hex = false;
  1413. bool found_digit = false;
  1414. U8 byte = 0;
  1415. int count = 0;
  1416. while (true)
  1417. {
  1418. int next_byte = istr.get();
  1419. ++count;
  1420. if(istr.fail())
  1421. {
  1422. // If our stream is empty, break out
  1423. value = write_buffer.str();
  1424. return LLSDParser::PARSE_FAILURE;
  1425. }
  1426. char next_char = (char)next_byte; // Now that we know it's not EOF
  1427. if(found_escape)
  1428. {
  1429. // next character(s) is a special sequence.
  1430. if(found_hex)
  1431. {
  1432. if(found_digit)
  1433. {
  1434. found_digit = false;
  1435. found_hex = false;
  1436. found_escape = false;
  1437. byte = byte << 4;
  1438. byte |= hex_as_nybble(next_char);
  1439. write_buffer << byte;
  1440. byte = 0;
  1441. }
  1442. else
  1443. {
  1444. // next character is the first nybble of
  1445. //
  1446. found_digit = true;
  1447. byte = hex_as_nybble(next_char);
  1448. }
  1449. }
  1450. else if(next_char == 'x')
  1451. {
  1452. found_hex = true;
  1453. }
  1454. else
  1455. {
  1456. switch(next_char)
  1457. {
  1458. case 'a':
  1459. write_buffer << 'a';
  1460. break;
  1461. case 'b':
  1462. write_buffer << 'b';
  1463. break;
  1464. case 'f':
  1465. write_buffer << 'f';
  1466. break;
  1467. case 'n':
  1468. write_buffer << 'n';
  1469. break;
  1470. case 'r':
  1471. write_buffer << 'r';
  1472. break;
  1473. case 't':
  1474. write_buffer << 't';
  1475. break;
  1476. case 'v':
  1477. write_buffer << 'v';
  1478. break;
  1479. default:
  1480. write_buffer << next_char;
  1481. break;
  1482. }
  1483. found_escape = false;
  1484. }
  1485. }
  1486. else if(next_char == '\')
  1487. {
  1488. found_escape = true;
  1489. }
  1490. else if(next_char == delim)
  1491. {
  1492. break;
  1493. }
  1494. else
  1495. {
  1496. write_buffer << next_char;
  1497. }
  1498. }
  1499. value = write_buffer.str();
  1500. return count;
  1501. }
  1502. int deserialize_string_raw(
  1503. std::istream& istr,
  1504. std::string& value,
  1505. S32 max_bytes)
  1506. {
  1507. int count = 0;
  1508. const S32 BUF_LEN = 20;
  1509. char buf[BUF_LEN]; /* Flawfinder: ignore */
  1510. istr.get(buf, BUF_LEN - 1, ')');
  1511. count += istr.gcount();
  1512. int c = istr.get();
  1513. c = istr.get();
  1514. count += 2;
  1515. if(((c == '"') || (c == ''')) && (buf[0] == '('))
  1516. {
  1517. // We probably have a valid raw string. determine
  1518. // the size, and read it.
  1519. // *FIX: This is memory inefficient.
  1520. S32 len = strtol(buf + 1, NULL, 0);
  1521. if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE;
  1522. std::vector<char> buf;
  1523. if(len)
  1524. {
  1525. buf.resize(len);
  1526. count += fullread(istr, (char *)&buf[0], len);
  1527. value.assign(buf.begin(), buf.end());
  1528. }
  1529. c = istr.get();
  1530. ++count;
  1531. if(!((c == '"') || (c == ''')))
  1532. {
  1533. return LLSDParser::PARSE_FAILURE;
  1534. }
  1535. }
  1536. else
  1537. {
  1538. return LLSDParser::PARSE_FAILURE;
  1539. }
  1540. return count;
  1541. }
  1542. static const char* NOTATION_STRING_CHARACTERS[256] =
  1543. {
  1544. "\x00", // 0
  1545. "\x01", // 1
  1546. "\x02", // 2
  1547. "\x03", // 3
  1548. "\x04", // 4
  1549. "\x05", // 5
  1550. "\x06", // 6
  1551. "\a", // 7
  1552. "\b", // 8
  1553. "\t", // 9
  1554. "\n", // 10
  1555. "\v", // 11
  1556. "\f", // 12
  1557. "\r", // 13
  1558. "\x0e", // 14
  1559. "\x0f", // 15
  1560. "\x10", // 16
  1561. "\x11", // 17
  1562. "\x12", // 18
  1563. "\x13", // 19
  1564. "\x14", // 20
  1565. "\x15", // 21
  1566. "\x16", // 22
  1567. "\x17", // 23
  1568. "\x18", // 24
  1569. "\x19", // 25
  1570. "\x1a", // 26
  1571. "\x1b", // 27
  1572. "\x1c", // 28
  1573. "\x1d", // 29
  1574. "\x1e", // 30
  1575. "\x1f", // 31
  1576. " ", // 32
  1577. "!", // 33
  1578. """, // 34
  1579. "#", // 35
  1580. "$", // 36
  1581. "%", // 37
  1582. "&", // 38
  1583. "\'", // 39
  1584. "(", // 40
  1585. ")", // 41
  1586. "*", // 42
  1587. "+", // 43
  1588. ",", // 44
  1589. "-", // 45
  1590. ".", // 46
  1591. "/", // 47
  1592. "0", // 48
  1593. "1", // 49
  1594. "2", // 50
  1595. "3", // 51
  1596. "4", // 52
  1597. "5", // 53
  1598. "6", // 54
  1599. "7", // 55
  1600. "8", // 56
  1601. "9", // 57
  1602. ":", // 58
  1603. ";", // 59
  1604. "<", // 60
  1605. "=", // 61
  1606. ">", // 62
  1607. "?", // 63
  1608. "@", // 64
  1609. "A", // 65
  1610. "B", // 66
  1611. "C", // 67
  1612. "D", // 68
  1613. "E", // 69
  1614. "F", // 70
  1615. "G", // 71
  1616. "H", // 72
  1617. "I", // 73
  1618. "J", // 74
  1619. "K", // 75
  1620. "L", // 76
  1621. "M", // 77
  1622. "N", // 78
  1623. "O", // 79
  1624. "P", // 80
  1625. "Q", // 81
  1626. "R", // 82
  1627. "S", // 83
  1628. "T", // 84
  1629. "U", // 85
  1630. "V", // 86
  1631. "W", // 87
  1632. "X", // 88
  1633. "Y", // 89
  1634. "Z", // 90
  1635. "[", // 91
  1636. "\\", // 92
  1637. "]", // 93
  1638. "^", // 94
  1639. "_", // 95
  1640. "`", // 96
  1641. "a", // 97
  1642. "b", // 98
  1643. "c", // 99
  1644. "d", // 100
  1645. "e", // 101
  1646. "f", // 102
  1647. "g", // 103
  1648. "h", // 104
  1649. "i", // 105
  1650. "j", // 106
  1651. "k", // 107
  1652. "l", // 108
  1653. "m", // 109
  1654. "n", // 110
  1655. "o", // 111
  1656. "p", // 112
  1657. "q", // 113
  1658. "r", // 114
  1659. "s", // 115
  1660. "t", // 116
  1661. "u", // 117
  1662. "v", // 118
  1663. "w", // 119
  1664. "x", // 120
  1665. "y", // 121
  1666. "z", // 122
  1667. "{", // 123
  1668. "|", // 124
  1669. "}", // 125
  1670. "~", // 126
  1671. "\x7f", // 127
  1672. "\x80", // 128
  1673. "\x81", // 129
  1674. "\x82", // 130
  1675. "\x83", // 131
  1676. "\x84", // 132
  1677. "\x85", // 133
  1678. "\x86", // 134
  1679. "\x87", // 135
  1680. "\x88", // 136
  1681. "\x89", // 137
  1682. "\x8a", // 138
  1683. "\x8b", // 139
  1684. "\x8c", // 140
  1685. "\x8d", // 141
  1686. "\x8e", // 142
  1687. "\x8f", // 143
  1688. "\x90", // 144
  1689. "\x91", // 145
  1690. "\x92", // 146
  1691. "\x93", // 147
  1692. "\x94", // 148
  1693. "\x95", // 149
  1694. "\x96", // 150
  1695. "\x97", // 151
  1696. "\x98", // 152
  1697. "\x99", // 153
  1698. "\x9a", // 154
  1699. "\x9b", // 155
  1700. "\x9c", // 156
  1701. "\x9d", // 157
  1702. "\x9e", // 158
  1703. "\x9f", // 159
  1704. "\xa0", // 160
  1705. "\xa1", // 161
  1706. "\xa2", // 162
  1707. "\xa3", // 163
  1708. "\xa4", // 164
  1709. "\xa5", // 165
  1710. "\xa6", // 166
  1711. "\xa7", // 167
  1712. "\xa8", // 168
  1713. "\xa9", // 169
  1714. "\xaa", // 170
  1715. "\xab", // 171
  1716. "\xac", // 172
  1717. "\xad", // 173
  1718. "\xae", // 174
  1719. "\xaf", // 175
  1720. "\xb0", // 176
  1721. "\xb1", // 177
  1722. "\xb2", // 178
  1723. "\xb3", // 179
  1724. "\xb4", // 180
  1725. "\xb5", // 181
  1726. "\xb6", // 182
  1727. "\xb7", // 183
  1728. "\xb8", // 184
  1729. "\xb9", // 185
  1730. "\xba", // 186
  1731. "\xbb", // 187
  1732. "\xbc", // 188
  1733. "\xbd", // 189
  1734. "\xbe", // 190
  1735. "\xbf", // 191
  1736. "\xc0", // 192
  1737. "\xc1", // 193
  1738. "\xc2", // 194
  1739. "\xc3", // 195
  1740. "\xc4", // 196
  1741. "\xc5", // 197
  1742. "\xc6", // 198
  1743. "\xc7", // 199
  1744. "\xc8", // 200
  1745. "\xc9", // 201
  1746. "\xca", // 202
  1747. "\xcb", // 203
  1748. "\xcc", // 204
  1749. "\xcd", // 205
  1750. "\xce", // 206
  1751. "\xcf", // 207
  1752. "\xd0", // 208
  1753. "\xd1", // 209
  1754. "\xd2", // 210
  1755. "\xd3", // 211
  1756. "\xd4", // 212
  1757. "\xd5", // 213
  1758. "\xd6", // 214
  1759. "\xd7", // 215
  1760. "\xd8", // 216
  1761. "\xd9", // 217
  1762. "\xda", // 218
  1763. "\xdb", // 219
  1764. "\xdc", // 220
  1765. "\xdd", // 221
  1766. "\xde", // 222
  1767. "\xdf", // 223
  1768. "\xe0", // 224
  1769. "\xe1", // 225
  1770. "\xe2", // 226
  1771. "\xe3", // 227
  1772. "\xe4", // 228
  1773. "\xe5", // 229
  1774. "\xe6", // 230
  1775. "\xe7", // 231
  1776. "\xe8", // 232
  1777. "\xe9", // 233
  1778. "\xea", // 234
  1779. "\xeb", // 235
  1780. "\xec", // 236
  1781. "\xed", // 237
  1782. "\xee", // 238
  1783. "\xef", // 239
  1784. "\xf0", // 240
  1785. "\xf1", // 241
  1786. "\xf2", // 242
  1787. "\xf3", // 243
  1788. "\xf4", // 244
  1789. "\xf5", // 245
  1790. "\xf6", // 246
  1791. "\xf7", // 247
  1792. "\xf8", // 248
  1793. "\xf9", // 249
  1794. "\xfa", // 250
  1795. "\xfb", // 251
  1796. "\xfc", // 252
  1797. "\xfd", // 253
  1798. "\xfe", // 254
  1799. "\xff" // 255
  1800. };
  1801. void serialize_string(const std::string& value, std::ostream& str)
  1802. {
  1803. std::string::const_iterator it = value.begin();
  1804. std::string::const_iterator end = value.end();
  1805. U8 c;
  1806. for(; it != end; ++it)
  1807. {
  1808. c = (U8)(*it);
  1809. str << NOTATION_STRING_CHARACTERS[c];
  1810. }
  1811. }
  1812. int deserialize_boolean(
  1813. std::istream& istr,
  1814. LLSD& data,
  1815. const std::string& compare,
  1816. bool value)
  1817. {
  1818. //
  1819. // this method is a little goofy, because it gets the stream at
  1820. // the point where the t or f has already been
  1821. // consumed. Basically, parse for a patch to the string passed in
  1822. // starting at index 1. If it's a match:
  1823. //  * assign data to value
  1824. //  * return the number of bytes read
  1825. // otherwise:
  1826. //  * set data to LLSD::null
  1827. //  * return LLSDParser::PARSE_FAILURE (-1)
  1828. //
  1829. int bytes_read = 0;
  1830. std::string::size_type ii = 0;
  1831. char c = istr.peek();
  1832. while((++ii < compare.size())
  1833.   && (tolower(c) == (int)compare[ii])
  1834.   && istr.good())
  1835. {
  1836. istr.ignore();
  1837. ++bytes_read;
  1838. c = istr.peek();
  1839. }
  1840. if(compare.size() != ii)
  1841. {
  1842. data.clear();
  1843. return LLSDParser::PARSE_FAILURE;
  1844. }
  1845. data = value;
  1846. return bytes_read;
  1847. }
  1848. std::ostream& operator<<(std::ostream& s, const LLSD& llsd)
  1849. {
  1850. s << LLSDNotationStreamer(llsd);
  1851. return s;
  1852. }