PageRenderTime 76ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/Release/src/json/json.cpp

http://casablanca.codeplex.com
C++ | 1809 lines | 1529 code | 232 blank | 48 comment | 159 complexity | 0ae738e68682c2f1376cc0ff210b5408 MD5 | raw file
Possible License(s): Apache-2.0
  1. /***
  2. * ==++==
  3. *
  4. * Copyright (c) Microsoft Corporation. All rights reserved.
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. * ==--==
  17. * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  18. *
  19. * json.cpp
  20. *
  21. * HTTP Library: JSON parser and writer
  22. *
  23. * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  24. ****/
  25. #include "stdafx.h"
  26. using namespace web; using namespace utility;
  27. using namespace web::json;
  28. using namespace utility::conversions;
  29. //
  30. // Template trickery: allow the definition of string literals that can be used within a template
  31. // parameterized by character type
  32. //
  33. struct string_literal_holder
  34. {
  35. const char *n;
  36. const utf16char *w;
  37. };
  38. #ifdef _MS_WINDOWS
  39. #define declare_string_literal(name, value) string_literal_holder name = {value, L##value}
  40. #else
  41. #define declare_string_literal(name, value) string_literal_holder name = {value, u##value}
  42. #endif
  43. template <typename CharType>
  44. struct string_literal_extractor
  45. {
  46. static const utf16char* get(const string_literal_holder& st) { return st.w; }
  47. };
  48. template <>
  49. struct string_literal_extractor<char>
  50. {
  51. static const char* get(const string_literal_holder& st) { return st.n; }
  52. };
  53. template <typename CharType>
  54. struct string_literal_comparer
  55. {
  56. static bool is_equal(const utf16string& str, const string_literal_holder& sh) { return str == sh.w; }
  57. };
  58. template <>
  59. struct string_literal_comparer<char>
  60. {
  61. static bool is_equal(const std::string& str, const string_literal_holder& sh) { return str == sh.n; }
  62. };
  63. // Serialization
  64. namespace _literals
  65. {
  66. static declare_string_literal(open_object, "{ ");
  67. static declare_string_literal(close_object, " }");
  68. static declare_string_literal(open_array, "[ ");
  69. static declare_string_literal(close_array, " ]");
  70. static declare_string_literal(separator, ", ");
  71. static declare_string_literal(quote, "\"");
  72. static declare_string_literal(quote_colon, "\" : ");
  73. }
  74. #ifdef _MS_WINDOWS
  75. void web::json::value::serialize(std::basic_ostream<wchar_t> &stream) const
  76. {
  77. m_value->format(stream);
  78. }
  79. void web::json::value::format(std::basic_string<wchar_t> &string) const
  80. {
  81. m_value->format(string);
  82. }
  83. #endif
  84. void web::json::value::serialize(std::basic_ostream<char>& stream) const
  85. {
  86. m_value->format(stream);
  87. }
  88. void web::json::value::format(std::basic_string<char>& string) const
  89. {
  90. m_value->format(string);
  91. }
  92. template<typename _CharType>
  93. void web::json::details::_Object::format_impl(std::basic_string<_CharType>& os) const
  94. {
  95. os.append(string_literal_extractor<_CharType>::get(_literals::open_object));
  96. bool first = true;
  97. for (auto iter = m_elements.begin(); iter != m_elements.end(); iter++)
  98. {
  99. if (!first) os.append(string_literal_extractor<_CharType>::get(_literals::separator));
  100. os.append(string_literal_extractor<_CharType>::get(_literals::quote));
  101. os.append(utility::conversions::to_basic_string<_CharType>::perform(iter->first.as_string()));
  102. os.append(string_literal_extractor<_CharType>::get(_literals::quote_colon));
  103. iter->second.format(os);
  104. first = false;
  105. }
  106. os.append(string_literal_extractor<_CharType>::get(_literals::close_object));
  107. }
  108. template<typename _CharType>
  109. void web::json::details::_Object::format_impl(std::basic_ostream<_CharType>& os) const
  110. {
  111. os << string_literal_extractor<_CharType>::get(_literals::open_object);
  112. bool first = true;
  113. for (auto iter = m_elements.begin(); iter != m_elements.end(); iter++)
  114. {
  115. if (!first) os << string_literal_extractor<_CharType>::get(_literals::separator);
  116. os << string_literal_extractor<_CharType>::get(_literals::quote)
  117. << utility::conversions::to_basic_string<_CharType>::perform(iter->first.as_string())
  118. << string_literal_extractor<_CharType>::get(_literals::quote_colon);
  119. iter->second.serialize(os);
  120. first = false;
  121. }
  122. os << string_literal_extractor<_CharType>::get(_literals::close_object);
  123. }
  124. template<typename _CharType>
  125. void web::json::details::_Array::format_impl(std::basic_string<_CharType>& os) const
  126. {
  127. os.append(string_literal_extractor<_CharType>::get(_literals::open_array));
  128. bool first = true;
  129. for (auto iter = m_elements.begin(); iter != m_elements.end(); iter++)
  130. {
  131. if (!first) os.append(string_literal_extractor<_CharType>::get(_literals::separator));
  132. iter->second.format(os);
  133. first = false;
  134. }
  135. os.append(string_literal_extractor<_CharType>::get(_literals::close_array));
  136. }
  137. template<typename _CharType>
  138. void web::json::details::_Array::format_impl(std::basic_ostream<_CharType>& os) const
  139. {
  140. os << string_literal_extractor<_CharType>::get(_literals::open_array);
  141. bool first = true;
  142. for (auto iter = m_elements.begin(); iter != m_elements.end(); iter++)
  143. {
  144. if (!first) os <<string_literal_extractor<_CharType>::get(_literals::separator);
  145. iter->second.serialize(os);
  146. first = false;
  147. }
  148. os << string_literal_extractor<_CharType>::get(_literals::close_array);
  149. }
  150. #ifdef _MS_WINDOWS
  151. void web::json::details::_Object::format(std::basic_string<wchar_t>& os) const
  152. {
  153. format_impl(os);
  154. }
  155. void web::json::details::_Object::format(std::basic_ostream<wchar_t>& os) const
  156. {
  157. format_impl(os);
  158. }
  159. void web::json::details::_Array::format(std::basic_string<wchar_t>& os) const
  160. {
  161. format_impl(os);
  162. }
  163. void web::json::details::_Array::format(std::basic_ostream<wchar_t>& os) const
  164. {
  165. format_impl(os);
  166. }
  167. #endif
  168. void web::json::details::_Object::format(std::basic_string<char>& os) const
  169. {
  170. format_impl(os);
  171. }
  172. void web::json::details::_Object::format(std::basic_ostream<char>& os) const
  173. {
  174. format_impl(os);
  175. }
  176. void web::json::details::_Array::format(std::basic_string<char>& os) const
  177. {
  178. format_impl(os);
  179. }
  180. void web::json::details::_Array::format(std::basic_ostream<char>& os) const
  181. {
  182. format_impl(os);
  183. }
  184. int _hexval [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  185. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  186. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  187. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
  188. 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  189. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  190. 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  191. template<typename CharType>
  192. std::basic_string<CharType> unescape_string(const std::basic_string<CharType>* escaped)
  193. {
  194. std::basic_string<CharType> tokenString;
  195. for (auto iter = escaped->begin(); iter != escaped->end(); iter++ )
  196. {
  197. CharType ch = (CharType)*iter;
  198. if ( ch == '\\' )
  199. {
  200. switch ( ch = *(++iter) )
  201. {
  202. case '\"':
  203. case '\\':
  204. case '/':
  205. break;
  206. case 'b':
  207. ch = '\b';
  208. break;
  209. case 'f':
  210. ch = '\f';
  211. break;
  212. case 'r':
  213. ch = U('\r');
  214. break;
  215. case 'n':
  216. ch = '\n';
  217. break;
  218. case 't':
  219. ch = '\t';
  220. break;
  221. case 'u':
  222. {
  223. // A four-hexdigit unicode character
  224. int decoded = 0;
  225. for (int i = 0; i < 4; i++)
  226. {
  227. CharType c = *(++iter);
  228. int val = _hexval[c];
  229. decoded |= (val << (4*(3-i)));
  230. }
  231. ch = static_cast<CharType>(decoded & 0xFFFF);
  232. break;
  233. }
  234. default:
  235. throw json::json_exception(U("invalid escape character in string literal"));
  236. }
  237. }
  238. else if ( ch > CharType(0x0) && ch < CharType(0x20) )
  239. {
  240. throw json::json_exception(U("invalid character in string literal"));
  241. }
  242. tokenString.push_back(ch);
  243. }
  244. return tokenString;
  245. }
  246. utility::string_t web::json::details::_String::as_string() const
  247. {
  248. #ifdef _UTF16_STRINGS
  249. return as_utf16_string();
  250. #else
  251. return as_utf8_string();
  252. #endif
  253. }
  254. std::string web::json::details::_String::as_utf8_string() const
  255. {
  256. if(is_wide())
  257. {
  258. return utf16_to_utf8(unescape_string<utf16char>(m_wstring.get()));
  259. }
  260. else
  261. {
  262. return unescape_string<char>(m_string.get());
  263. }
  264. }
  265. utf16string web::json::details::_String::as_utf16_string() const
  266. {
  267. if(is_wide())
  268. {
  269. return unescape_string<utf16char>(m_wstring.get());
  270. }
  271. else
  272. {
  273. return utf8_to_utf16(unescape_string<char>(m_string.get()));
  274. }
  275. }
  276. web::json::details::_Object::_Object(const _Object& other):web::json::details::_Value(other)
  277. {
  278. m_elements = other.m_elements;
  279. }
  280. web::json::value::value_type json::value::type() const { return m_value->type(); }
  281. json::value& web::json::details::_Object::index(const utility::string_t &key)
  282. {
  283. map_fields();
  284. auto whre = m_fields.find(key);
  285. if ( whre == m_fields.end() )
  286. {
  287. // Insert a new entry.
  288. m_elements.push_back(std::make_pair(json::value::string(key), json::value::null()));
  289. size_t index = m_elements.size()-1;
  290. m_fields[key] = index;
  291. return m_elements[index].second;
  292. }
  293. return m_elements[whre->second].second;
  294. }
  295. const json::value& web::json::details::_Object::cnst_index(const utility::string_t &key) const
  296. {
  297. const_cast<web::json::details::_Object*>(this)->map_fields();
  298. auto whre = m_fields.find(key);
  299. if ( whre == m_fields.end() )
  300. throw json::json_exception(U("invalid field name"));
  301. return m_elements[whre->second].second;
  302. }
  303. void web::json::details::_Object::map_fields()
  304. {
  305. if ( m_fields.size() == 0 )
  306. {
  307. size_t index = 0;
  308. for (auto iter = m_elements.begin(); iter != m_elements.end(); ++iter, ++index)
  309. {
  310. m_fields[iter->first.as_string()] = index;
  311. }
  312. }
  313. }
  314. utility::string_t json::value::to_string() const { return m_value->to_string(); }
  315. bool json::value::operator==(const json::value &other) const
  316. {
  317. if (this->m_value.get() == other.m_value.get())
  318. return true;
  319. if (this->type() != other.type())
  320. return false;
  321. switch(this->type())
  322. {
  323. case Null:
  324. return true;
  325. case Number:
  326. return this->as_double() == other.as_double();
  327. case Boolean:
  328. return this->as_bool() == other.as_bool();
  329. case String:
  330. return this->as_string() == other.as_string();
  331. case Object:
  332. return dynamic_cast<const json::details::_Object*>(this->m_value.get())->is_equal(dynamic_cast<const json::details::_Object*>(other.m_value.get()));
  333. case Array:
  334. return dynamic_cast<const json::details::_Array*>(this->m_value.get())->is_equal(dynamic_cast<const json::details::_Array*>(other.m_value.get()));
  335. }
  336. return false;
  337. }
  338. web::json::value& web::json::value::operator [] (const utility::string_t &key)
  339. {
  340. if ( this->is_null() )
  341. {
  342. m_value.reset(new web::json::details::_Object());
  343. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  344. m_kind = value::Object;
  345. #endif
  346. }
  347. return m_value->index(key);
  348. }
  349. const web::json::value& web::json::value::operator [] (const utility::string_t &key) const
  350. {
  351. if ( this->is_null() )
  352. {
  353. auto _nc_this = const_cast<web::json::value*>(this);
  354. _nc_this->m_value.reset(new web::json::details::_Object());
  355. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  356. _nc_this->m_kind = value::Object;
  357. #endif
  358. }
  359. return m_value->cnst_index(key);
  360. }
  361. web::json::value& web::json::value::operator[](size_t index)
  362. {
  363. if ( this->is_null() )
  364. {
  365. m_value.reset(new web::json::details::_Array());
  366. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  367. m_kind = value::Array;
  368. #endif
  369. }
  370. return m_value->index(index);
  371. }
  372. const web::json::value& web::json::value::operator[](size_t index) const
  373. {
  374. if ( this->is_null() )
  375. {
  376. auto _nc_this = const_cast<web::json::value*>(this);
  377. _nc_this->m_value.reset(new web::json::details::_Array());
  378. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  379. _nc_this->m_kind = value::Array;
  380. #endif
  381. }
  382. return m_value->cnst_index(index);
  383. }
  384. double web::json::value::as_double() const
  385. {
  386. return m_value->as_double();
  387. }
  388. int32_t web::json::value::as_integer() const
  389. {
  390. return m_value->as_integer();
  391. }
  392. bool web::json::value::as_bool() const
  393. {
  394. return m_value->as_bool();
  395. }
  396. utility::string_t web::json::value::as_string() const
  397. {
  398. return m_value->as_string();
  399. }
  400. #pragma region Static Factories
  401. web::json::value web::json::value::null()
  402. {
  403. return web::json::value();
  404. }
  405. web::json::value web::json::value::number(double value)
  406. {
  407. return web::json::value(value);
  408. }
  409. web::json::value web::json::value::number(int32_t value)
  410. {
  411. return web::json::value(value);
  412. }
  413. web::json::value web::json::value::boolean(bool value)
  414. {
  415. return web::json::value(value);
  416. }
  417. web::json::value web::json::value::string(utility::string_t value)
  418. {
  419. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_String>(std::move(value));
  420. return web::json::value(std::move(ptr)
  421. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  422. ,value::String
  423. #endif
  424. );
  425. }
  426. #ifdef _MS_WINDOWS
  427. web::json::value web::json::value::string(std::string value)
  428. {
  429. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_String>(std::move(value));
  430. return web::json::value(std::move(ptr)
  431. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  432. ,value::String
  433. #endif
  434. );
  435. }
  436. #endif
  437. web::json::value web::json::value::object()
  438. {
  439. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Object>();
  440. return web::json::value(std::move(ptr)
  441. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  442. ,value::Object
  443. #endif
  444. );
  445. }
  446. web::json::value web::json::value::object(const web::json::value::field_map &fields)
  447. {
  448. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Object>(fields);
  449. return web::json::value(std::move(ptr)
  450. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  451. ,value::Object
  452. #endif
  453. );
  454. }
  455. web::json::value web::json::value::array()
  456. {
  457. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Array>();
  458. return web::json::value(std::move(ptr)
  459. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  460. ,value::Array
  461. #endif
  462. );
  463. }
  464. web::json::value web::json::value::array(size_t size)
  465. {
  466. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Array>(size);
  467. return web::json::value(std::move(ptr)
  468. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  469. ,value::Array
  470. #endif
  471. );
  472. }
  473. web::json::value web::json::value::array(const json::value::element_vector &elements)
  474. {
  475. std::unique_ptr<details::_Value> ptr = utility::details::make_unique<details::_Array>(elements);
  476. return web::json::value(std::move(ptr)
  477. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  478. ,value::Array
  479. #endif
  480. );
  481. }
  482. #pragma endregion
  483. utility::ostream_t& web::json::operator << (utility::ostream_t &os, const web::json::value &val)
  484. {
  485. val.serialize(os);
  486. return os;
  487. }
  488. utility::istream_t& web::json::operator >> (utility::istream_t &is, json::value &val)
  489. {
  490. val = json::value::parse(is);
  491. return is;
  492. }
  493. #pragma region json::value Constructors
  494. web::json::value::value() :
  495. m_value(utility::details::make_unique<web::json::details::_Null>())
  496. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  497. ,m_kind(value::Null)
  498. #endif
  499. { }
  500. web::json::value::value(int value) :
  501. m_value(utility::details::make_unique<web::json::details::_Number>(value))
  502. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  503. ,m_kind(value::Number)
  504. #endif
  505. { }
  506. web::json::value::value(double value) :
  507. m_value(utility::details::make_unique<web::json::details::_Number>(value))
  508. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  509. ,m_kind(value::Number)
  510. #endif
  511. { }
  512. web::json::value::value(bool value) :
  513. m_value(utility::details::make_unique<web::json::details::_Boolean>(value))
  514. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  515. ,m_kind(value::Boolean)
  516. #endif
  517. { }
  518. web::json::value::value(utility::string_t value) :
  519. m_value(utility::details::make_unique<web::json::details::_String>(std::move(value)))
  520. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  521. ,m_kind(value::String)
  522. #endif
  523. { }
  524. web::json::value::value(const utility::char_t* value) :
  525. m_value(utility::details::make_unique<web::json::details::_String>(utility::string_t(value)))
  526. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  527. ,m_kind(value::String)
  528. #endif
  529. { }
  530. web::json::value::value(const value &other) :
  531. m_value(other.m_value->_copy_value())
  532. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  533. ,m_kind(other.m_kind)
  534. #endif
  535. { }
  536. web::json::value &web::json::value::operator=(const value &other)
  537. {
  538. if(this != &other)
  539. {
  540. m_value = std::unique_ptr<details::_Value>(other.m_value->_copy_value());
  541. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  542. m_kind = other.m_kind;
  543. #endif
  544. }
  545. return *this;
  546. }
  547. web::json::value::value(value &&other) :
  548. m_value(std::move(other.m_value))
  549. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  550. ,m_kind(other.m_kind)
  551. #endif
  552. {}
  553. web::json::value &web::json::value::operator=(web::json::value &&other)
  554. {
  555. if(this != &other)
  556. {
  557. m_value.swap(other.m_value);
  558. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  559. m_kind = other.m_kind;
  560. #endif
  561. }
  562. return *this;
  563. }
  564. #pragma endregion
  565. namespace web {
  566. namespace json
  567. {
  568. namespace details
  569. {
  570. //
  571. // JSON Parsing
  572. //
  573. template <typename CharType>
  574. class JSON_Parser
  575. {
  576. public:
  577. JSON_Parser()
  578. : m_currentLine(1),
  579. m_eof(std::char_traits<CharType>::eof()),
  580. m_currentColumn(1),
  581. m_currentParsingDepth(0)
  582. {
  583. declare_string_literal(n, "null");
  584. declare_string_literal(t, "true");
  585. declare_string_literal(f, "false");
  586. m_null = n;
  587. m_true = t;
  588. m_false = f;
  589. }
  590. struct Location
  591. {
  592. size_t m_line;
  593. size_t m_column;
  594. };
  595. struct Token
  596. {
  597. enum Kind
  598. {
  599. TKN_EOF,
  600. TKN_OpenBrace,
  601. TKN_CloseBrace,
  602. TKN_OpenBracket,
  603. TKN_CloseBracket,
  604. TKN_Comma,
  605. TKN_Colon,
  606. TKN_StringLiteral,
  607. TKN_NumberLiteral,
  608. TKN_IntegerLiteral,
  609. TKN_BooleanLiteral,
  610. TKN_NullLiteral
  611. };
  612. Token() : kind(TKN_EOF) {}
  613. Token(Kind kind) : kind(kind) {}
  614. Kind kind;
  615. std::basic_string<CharType> spelling;
  616. typename JSON_Parser<CharType>::Location start;
  617. typename JSON_Parser<CharType>::Location end;
  618. };
  619. void GetNextToken(Token &);
  620. web::json::value ParseValue(typename JSON_Parser<CharType>::Token &first)
  621. {
  622. auto _value = _ParseValue(first);
  623. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  624. auto type = _value->type();
  625. #endif
  626. return web::json::value(std::move(_value)
  627. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  628. ,type
  629. #endif
  630. );
  631. }
  632. protected:
  633. virtual bool IsEOF()
  634. {
  635. return false;
  636. }
  637. virtual CharType NextCharacter() = 0;
  638. virtual CharType PeekCharacter() = 0;
  639. virtual bool CompleteKeyword(const CharType *expected, size_t expected_size, typename Token::Kind kind, Token &token);
  640. virtual bool CompleteNumberLiteral(CharType first, Token &token);
  641. virtual bool CompleteStringLiteral(CharType first, Token &token);
  642. private:
  643. std::unique_ptr<web::json::details::_Value> _ParseValue(typename JSON_Parser<CharType>::Token &first);
  644. std::unique_ptr<web::json::details::_Object> _ParseObject(typename JSON_Parser<CharType>::Token &tkn);
  645. std::unique_ptr<web::json::details::_Array> _ParseArray(typename JSON_Parser<CharType>::Token &tkn);
  646. JSON_Parser& operator=(const JSON_Parser&);
  647. CharType EatWhitespace();
  648. void CreateToken(typename JSON_Parser<CharType>::Token& tk, typename Token::Kind kind, Location &start)
  649. {
  650. tk.kind = kind;
  651. tk.start = start;
  652. tk.end = start;
  653. tk.end.m_column++;
  654. tk.spelling.clear();
  655. }
  656. void CreateToken(typename JSON_Parser<CharType>::Token& tk, typename Token::Kind kind, Location &start, Location &end)
  657. {
  658. tk.kind = kind;
  659. tk.start = start;
  660. tk.end = end;
  661. tk.spelling.clear();
  662. }
  663. void CreateToken(typename JSON_Parser<CharType>::Token& tk, typename Token::Kind kind)
  664. {
  665. tk.kind = kind;
  666. tk.start.m_line = m_currentLine;
  667. tk.start.m_column = m_currentColumn;
  668. tk.end = tk.start;
  669. tk.spelling.clear();
  670. }
  671. #ifdef _MS_WINDOWS
  672. __declspec(noreturn)
  673. #else
  674. __attribute__((noreturn))
  675. #endif
  676. void CreateError(const typename JSON_Parser<CharType>::Token &tk, const utility::string_t &message);
  677. protected:
  678. size_t m_currentLine;
  679. size_t m_currentColumn;
  680. size_t m_currentParsingDepth;
  681. static const size_t maxParsingDepth = 128;
  682. typename std::char_traits<CharType>::int_type m_eof;
  683. private:
  684. string_literal_holder m_null;
  685. string_literal_holder m_true;
  686. string_literal_holder m_false;
  687. };
  688. template <typename CharType>
  689. class JSON_StreamParser : public JSON_Parser<CharType>
  690. {
  691. public:
  692. JSON_StreamParser(std::basic_istream<CharType> &stream)
  693. : m_streambuf(stream.rdbuf())
  694. {
  695. }
  696. protected:
  697. virtual CharType NextCharacter();
  698. virtual CharType PeekCharacter();
  699. private:
  700. typename std::basic_streambuf<CharType, std::char_traits<CharType>>* m_streambuf;
  701. };
  702. template <typename CharType>
  703. class JSON_StringParser : public JSON_Parser<CharType>
  704. {
  705. public:
  706. JSON_StringParser(const std::basic_string<CharType>& string)
  707. : m_string(string),
  708. m_position(&string[0])
  709. {
  710. m_startpos = m_position;
  711. m_endpos = m_position+string.size();
  712. }
  713. protected:
  714. virtual CharType NextCharacter();
  715. virtual CharType PeekCharacter();
  716. virtual bool CompleteKeyword(const CharType *expected, size_t expected_size, typename JSON_Parser<CharType>::Token::Kind kind, typename JSON_Parser<CharType>::Token &token);
  717. virtual bool CompleteNumberLiteral(CharType first, typename JSON_Parser<CharType>::Token &token);
  718. virtual bool CompleteStringLiteral(CharType first, typename JSON_Parser<CharType>::Token &token);
  719. private:
  720. const CharType* m_position;
  721. const CharType* m_startpos;
  722. const CharType* m_endpos;
  723. const std::basic_string<CharType>& m_string;
  724. };
  725. template <typename CharType>
  726. void JSON_Parser<CharType>::CreateError(const typename JSON_Parser<CharType>::Token &tk, const utility::string_t &message)
  727. {
  728. utility::ostringstream_t os;
  729. os << message << U(" near line ") << tk.start.m_line << U(", column ") << tk.start.m_column;
  730. throw web::json::json_exception(os.str().c_str());
  731. }
  732. template <typename CharType>
  733. CharType JSON_StreamParser<CharType>::NextCharacter()
  734. {
  735. CharType ch = (CharType)m_streambuf->sbumpc();
  736. if ( this->IsEOF() || ch == this->m_eof ) return (CharType)ch;
  737. if ( ch == '\n' )
  738. {
  739. this->m_currentLine += 1;
  740. this->m_currentColumn = 0;
  741. }
  742. else
  743. {
  744. this->m_currentColumn += 1;
  745. }
  746. return (CharType)ch;
  747. }
  748. template <typename CharType>
  749. CharType JSON_StreamParser<CharType>::PeekCharacter()
  750. {
  751. return (CharType)m_streambuf->sgetc();
  752. }
  753. template <typename CharType>
  754. CharType JSON_StringParser<CharType>::NextCharacter()
  755. {
  756. if ( m_position == m_endpos ) return (CharType)this->m_eof;
  757. CharType ch = *m_position;
  758. m_position += 1;
  759. if ( m_position == m_endpos ) return (CharType)ch;
  760. if ( ch == '\n' )
  761. {
  762. this->m_currentLine += 1;
  763. this->m_currentColumn = 0;
  764. }
  765. else
  766. {
  767. this->m_currentColumn += 1;
  768. }
  769. return (CharType)ch;
  770. }
  771. template <typename CharType>
  772. CharType JSON_StringParser<CharType>::PeekCharacter()
  773. {
  774. if ( m_position == m_endpos ) return (CharType)this->m_eof;
  775. return (CharType)*m_position;
  776. }
  777. //
  778. // Consume whitespace characters and return the first non-space character or EOF
  779. //
  780. template <typename CharType>
  781. CharType JSON_Parser<CharType>::EatWhitespace()
  782. {
  783. CharType ch = NextCharacter();
  784. while ( !IsEOF() && ch != m_eof && iswspace((int)ch) )
  785. {
  786. ch = NextCharacter();
  787. }
  788. return ch;
  789. }
  790. template <typename CharType>
  791. bool JSON_Parser<CharType>::CompleteKeyword(const CharType *expected, size_t expected_size, typename Token::Kind kind, Token &token)
  792. {
  793. UNREFERENCED_PARAMETER(expected_size);
  794. token.spelling.push_back(expected[0]);
  795. const CharType *ptr = expected+1;
  796. CharType ch = NextCharacter();
  797. while ( !IsEOF() && ch != m_eof && *ptr != '\0')
  798. {
  799. if ( ch != *ptr )
  800. {
  801. return false;
  802. }
  803. ptr++;
  804. token.spelling.push_back(ch);
  805. if ( *ptr == '\0' ) break;
  806. ch = NextCharacter();
  807. }
  808. token.kind = kind;
  809. token.end.m_column = m_currentColumn;
  810. token.end.m_line = m_currentLine;
  811. return true;
  812. }
  813. template <typename CharType>
  814. bool JSON_StringParser<CharType>::CompleteKeyword(const CharType *expected, size_t expected_size, typename JSON_Parser<CharType>::Token::Kind kind, typename JSON_Parser<CharType>::Token &token)
  815. {
  816. const CharType *ptr = expected+1;
  817. CharType ch = NextCharacter();
  818. while ( !this->IsEOF() && ch != this->m_eof && *ptr != '\0')
  819. {
  820. if ( ch != *ptr )
  821. {
  822. return false;
  823. }
  824. ptr++;
  825. if ( *ptr == '\0' ) break;
  826. ch = NextCharacter();
  827. }
  828. token.spelling.resize(expected_size);
  829. memcpy(&token.spelling[0], expected, (expected_size)*sizeof(CharType));
  830. token.kind = kind;
  831. token.end.m_column = this->m_currentColumn;
  832. token.end.m_line = this->m_currentLine;
  833. return true;
  834. }
  835. template <typename CharType>
  836. bool JSON_Parser<CharType>::CompleteNumberLiteral(CharType first, Token &token)
  837. {
  838. //
  839. // First, find the boundaries of the literal. Then, validate that it has the right format.
  840. //
  841. token.spelling.push_back(first);
  842. bool could_be_integer = true;
  843. CharType ch = first;
  844. while ( !IsEOF() && ch != m_eof)
  845. {
  846. ch = PeekCharacter();
  847. switch ( ch )
  848. {
  849. default:
  850. goto boundary_found;
  851. case '0':
  852. case '1':
  853. case '2':
  854. case '3':
  855. case '4':
  856. case '5':
  857. case '6':
  858. case '7':
  859. case '8':
  860. case '9':
  861. case 'e':
  862. case 'E':
  863. case '.':
  864. case '-':
  865. case '+':
  866. break;
  867. }
  868. token.spelling.push_back(ch);
  869. ch = NextCharacter();
  870. }
  871. boundary_found:
  872. size_t idx = 0;
  873. size_t end = token.spelling.size();
  874. if ( token.spelling[idx] == '-' )
  875. {
  876. idx = 1;
  877. }
  878. if ( token.spelling[idx] == '0' )
  879. {
  880. if ( idx == end-1) goto done;
  881. switch(token.spelling[idx+1])
  882. {
  883. default:
  884. return false;
  885. case '.':
  886. idx += 2;
  887. could_be_integer = false;
  888. goto found_decimal_point;
  889. }
  890. }
  891. switch ( token.spelling[idx] )
  892. {
  893. default:
  894. return false;
  895. case '0':
  896. case '1':
  897. case '2':
  898. case '3':
  899. case '4':
  900. case '5':
  901. case '6':
  902. case '7':
  903. case '8':
  904. case '9':
  905. idx += 1;
  906. break;
  907. }
  908. for (; idx < end; idx++)
  909. {
  910. switch ( token.spelling[idx] )
  911. {
  912. default:
  913. return false;
  914. case '0':
  915. case '1':
  916. case '2':
  917. case '3':
  918. case '4':
  919. case '5':
  920. case '6':
  921. case '7':
  922. case '8':
  923. case '9':
  924. break;
  925. case '.':
  926. idx += 1;
  927. could_be_integer = false;
  928. goto found_decimal_point;
  929. case 'e':
  930. case 'E':
  931. idx += 1;
  932. could_be_integer = false;
  933. goto found_exponent;
  934. }
  935. }
  936. goto done;
  937. found_decimal_point:
  938. if ( idx == end ) return false;
  939. for (; idx < end; idx++)
  940. {
  941. switch ( token.spelling[idx] )
  942. {
  943. default:
  944. return false;
  945. case '0':
  946. case '1':
  947. case '2':
  948. case '3':
  949. case '4':
  950. case '5':
  951. case '6':
  952. case '7':
  953. case '8':
  954. case '9':
  955. break;
  956. case 'e':
  957. case 'E':
  958. idx += 1;
  959. goto found_exponent;
  960. }
  961. }
  962. goto done;
  963. found_exponent:
  964. if ( idx == end ) return false;
  965. if ( token.spelling[idx] == '-' || token.spelling[idx] == '+' )
  966. {
  967. idx += 1;
  968. }
  969. if ( idx == end ) return false;
  970. for (; idx < end; idx++)
  971. {
  972. switch ( token.spelling[idx] )
  973. {
  974. default:
  975. return false;
  976. case '0':
  977. case '1':
  978. case '2':
  979. case '3':
  980. case '4':
  981. case '5':
  982. case '6':
  983. case '7':
  984. case '8':
  985. case '9':
  986. break;
  987. }
  988. }
  989. done:
  990. token.kind = could_be_integer ? Token::TKN_IntegerLiteral : Token::TKN_NumberLiteral;
  991. token.end.m_column = m_currentColumn;
  992. token.end.m_line = m_currentLine;
  993. return true;
  994. }
  995. template <typename CharType>
  996. bool JSON_StringParser<CharType>::CompleteNumberLiteral(CharType first, typename JSON_Parser<CharType>::Token &token)
  997. {
  998. //
  999. // First, find the boundaries of the literal. Then, validate that it has the right format.
  1000. //
  1001. auto first_pos = m_position-1;
  1002. bool could_be_integer = true;
  1003. CharType ch = first;
  1004. while ( !this->IsEOF() && ch != this->m_eof)
  1005. {
  1006. ch = PeekCharacter();
  1007. switch ( ch )
  1008. {
  1009. default:
  1010. goto boundary_found;
  1011. case '0':
  1012. case '1':
  1013. case '2':
  1014. case '3':
  1015. case '4':
  1016. case '5':
  1017. case '6':
  1018. case '7':
  1019. case '8':
  1020. case '9':
  1021. case 'e':
  1022. case 'E':
  1023. case '.':
  1024. case '-':
  1025. case '+':
  1026. break;
  1027. }
  1028. ch = NextCharacter();
  1029. }
  1030. boundary_found:
  1031. // This is the index of the first character **not** in the literal.
  1032. auto last_pos = m_position;
  1033. auto idx = first_pos;
  1034. if ( idx[0] == '-' )
  1035. {
  1036. idx += 1;
  1037. }
  1038. if ( idx[0] == '0' )
  1039. {
  1040. if ( idx == last_pos-1) goto done;
  1041. switch(idx[1])
  1042. {
  1043. default:
  1044. return false;
  1045. case '.':
  1046. idx += 2;
  1047. could_be_integer = false;
  1048. goto found_decimal_point;
  1049. }
  1050. }
  1051. switch ( idx[0] )
  1052. {
  1053. default:
  1054. return false;
  1055. case '0':
  1056. case '1':
  1057. case '2':
  1058. case '3':
  1059. case '4':
  1060. case '5':
  1061. case '6':
  1062. case '7':
  1063. case '8':
  1064. case '9':
  1065. idx += 1;
  1066. break;
  1067. }
  1068. for (; idx < last_pos; idx++)
  1069. {
  1070. switch ( idx[0] )
  1071. {
  1072. default:
  1073. return false;
  1074. case '0':
  1075. case '1':
  1076. case '2':
  1077. case '3':
  1078. case '4':
  1079. case '5':
  1080. case '6':
  1081. case '7':
  1082. case '8':
  1083. case '9':
  1084. break;
  1085. case '.':
  1086. idx += 1;
  1087. could_be_integer = false;
  1088. goto found_decimal_point;
  1089. case 'e':
  1090. case 'E':
  1091. idx += 1;
  1092. could_be_integer = false;
  1093. goto found_exponent;
  1094. }
  1095. }
  1096. goto done;
  1097. found_decimal_point:
  1098. if ( idx == last_pos ) return false;
  1099. for (; idx < last_pos; idx++)
  1100. {
  1101. switch ( idx[0] )
  1102. {
  1103. default:
  1104. return false;
  1105. case '0':
  1106. case '1':
  1107. case '2':
  1108. case '3':
  1109. case '4':
  1110. case '5':
  1111. case '6':
  1112. case '7':
  1113. case '8':
  1114. case '9':
  1115. break;
  1116. case 'e':
  1117. case 'E':
  1118. idx += 1;
  1119. goto found_exponent;
  1120. }
  1121. }
  1122. goto done;
  1123. found_exponent:
  1124. if ( idx == last_pos ) return false;
  1125. if ( idx[0] == '-' || idx[0] == '+' )
  1126. {
  1127. idx += 1;
  1128. }
  1129. if ( idx == last_pos ) return false;
  1130. for (; idx < last_pos; idx++)
  1131. {
  1132. switch ( idx[0] )
  1133. {
  1134. default:
  1135. return false;
  1136. case '0':
  1137. case '1':
  1138. case '2':
  1139. case '3':
  1140. case '4':
  1141. case '5':
  1142. case '6':
  1143. case '7':
  1144. case '8':
  1145. case '9':
  1146. break;
  1147. }
  1148. }
  1149. done:
  1150. token.spelling.resize(last_pos-first_pos);
  1151. memcpy(&token.spelling[0], first_pos, (last_pos-first_pos)*sizeof(CharType));
  1152. token.kind = could_be_integer ? (JSON_Parser<CharType>::Token::TKN_IntegerLiteral) : (JSON_Parser<CharType>::Token::TKN_NumberLiteral);
  1153. token.end.m_column = this->m_currentColumn;
  1154. token.end.m_line = this->m_currentLine;
  1155. return true;
  1156. }
  1157. template <typename CharType>
  1158. bool JSON_Parser<CharType>::CompleteStringLiteral(CharType first, Token &token)
  1159. {
  1160. UNREFERENCED_PARAMETER(first);
  1161. CharType ch = NextCharacter();
  1162. while ( !IsEOF() && ch != m_eof && ch != '"')
  1163. {
  1164. if ( ch == '\\' )
  1165. {
  1166. token.spelling.push_back(ch);
  1167. switch ( ch = NextCharacter() )
  1168. {
  1169. case '\"':
  1170. case '\\':
  1171. case '/':
  1172. case 'b':
  1173. case 'f':
  1174. case 'r':
  1175. case 'n':
  1176. case 't':
  1177. break;
  1178. case 'u':
  1179. {
  1180. // A four-hexdigit unicode character
  1181. for (int i = 0; i < 4; i++)
  1182. {
  1183. token.spelling.push_back(ch);
  1184. ch = NextCharacter();
  1185. if ( !isxdigit((unsigned char)(ch))) return false;
  1186. }
  1187. break;
  1188. }
  1189. default:
  1190. return false;
  1191. }
  1192. }
  1193. else if ( ch > CharType(0x0) && ch < CharType(0x20) )
  1194. {
  1195. return false;
  1196. }
  1197. token.spelling.push_back(ch);
  1198. ch = NextCharacter();
  1199. }
  1200. if ( ch == '"' )
  1201. {
  1202. token.kind = Token::TKN_StringLiteral;
  1203. token.end.m_column = m_currentColumn;
  1204. token.end.m_line = m_currentLine;
  1205. }
  1206. else
  1207. {
  1208. return false;
  1209. }
  1210. return true;
  1211. }
  1212. template <typename CharType>
  1213. bool JSON_StringParser<CharType>::CompleteStringLiteral(CharType first, typename JSON_Parser<CharType>::Token &token)
  1214. {
  1215. // This function is specialized for the string parser, since we can be slightly more
  1216. // efficient in copying data from the input to the token: do a memcpy() rather than
  1217. // one character at a time.
  1218. // first is expected to contain "\""
  1219. UNREFERENCED_PARAMETER(first);
  1220. auto start = m_position;
  1221. CharType ch = NextCharacter();
  1222. while ( !this->IsEOF() && ch != this->m_eof && ch != '"')
  1223. {
  1224. if ( ch == '\\' )
  1225. {
  1226. m_position = start;
  1227. return JSON_Parser<CharType>::CompleteStringLiteral(first, token);
  1228. }
  1229. else if ( ch > CharType(0x0) && ch < CharType(0x20) )
  1230. {
  1231. return false;
  1232. }
  1233. ch = NextCharacter();
  1234. }
  1235. if ( ch == '"' )
  1236. {
  1237. token.spelling.resize(m_position-start-1);
  1238. if ( token.spelling.size() > 0 )
  1239. memcpy(&token.spelling[0], start, (m_position-start-1)*sizeof(CharType));
  1240. token.kind = JSON_Parser<CharType>::Token::TKN_StringLiteral;
  1241. token.end.m_column = this->m_currentColumn;
  1242. token.end.m_line = this->m_currentLine;
  1243. }
  1244. else
  1245. {
  1246. return false;
  1247. }
  1248. return true;
  1249. }
  1250. template <typename CharType>
  1251. void JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharType>::Token& result)
  1252. {
  1253. CharType ch = EatWhitespace();
  1254. CreateToken(result, Token::TKN_EOF);
  1255. if ( IsEOF() || ch == m_eof ) return;
  1256. switch ( ch )
  1257. {
  1258. case '{':
  1259. case '[':
  1260. {
  1261. if(++m_currentParsingDepth >= JSON_Parser<CharType>::maxParsingDepth)
  1262. {
  1263. CreateError(result, U("Nesting too deep!"));
  1264. break;
  1265. }
  1266. typename JSON_Parser<CharType>::Token::Kind tk = ch == '{' ? Token::TKN_OpenBrace : Token::TKN_OpenBracket;
  1267. CreateToken(result, tk, result.start);
  1268. break;
  1269. }
  1270. case '}':
  1271. case ']':
  1272. {
  1273. if((signed int)(--m_currentParsingDepth) < 0)
  1274. {
  1275. CreateError(result, U("Mismatched braces!"));
  1276. break;
  1277. }
  1278. typename JSON_Parser<CharType>::Token::Kind tk = ch == '}' ? Token::TKN_CloseBrace : Token::TKN_CloseBracket;
  1279. CreateToken(result, tk, result.start);
  1280. break;
  1281. }
  1282. case ',':
  1283. CreateToken(result, Token::TKN_Comma, result.start);
  1284. break;
  1285. case ':':
  1286. CreateToken(result, Token::TKN_Colon, result.start);
  1287. break;
  1288. case 't':
  1289. if ( !CompleteKeyword(string_literal_extractor<CharType>::get(m_true), 4, Token::TKN_BooleanLiteral, result) ) CreateError(result, U("Malformed literal"));
  1290. break;
  1291. case 'f':
  1292. if ( !CompleteKeyword(string_literal_extractor<CharType>::get(m_false), 5, Token::TKN_BooleanLiteral, result) ) CreateError(result, U("Malformed literal"));
  1293. break;
  1294. case 'n':
  1295. if ( !CompleteKeyword(string_literal_extractor<CharType>::get(m_null), 4, Token::TKN_NullLiteral, result) ) CreateError(result, U("Malformed literal"));
  1296. break;
  1297. case '"':
  1298. result.spelling.reserve(32);
  1299. if ( !CompleteStringLiteral(ch, result) ) CreateError(result, U("Malformed string literal"));
  1300. break;
  1301. case '-':
  1302. case '0':
  1303. case '1':
  1304. case '2':
  1305. case '3':
  1306. case '4':
  1307. case '5':
  1308. case '6':
  1309. case '7':
  1310. case '8':
  1311. case '9':
  1312. if ( !CompleteNumberLiteral(ch, result) ) CreateError(result, U("Malformed numeric literal"));
  1313. break;
  1314. default:
  1315. CreateError(result, U("Malformed token"));
  1316. break;
  1317. }
  1318. }
  1319. template <typename CharType>
  1320. std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn)
  1321. {
  1322. GetNextToken(tkn);
  1323. auto obj = utility::details::make_unique<web::json::details::_Object>();
  1324. if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBrace )
  1325. {
  1326. while ( true )
  1327. {
  1328. // State 1: New field or end of object, looking for field name or closing brace
  1329. std::basic_string<CharType> fieldName;
  1330. switch ( tkn.kind )
  1331. {
  1332. case JSON_Parser<CharType>::Token::TKN_StringLiteral:
  1333. fieldName = std::move(tkn.spelling);
  1334. break;
  1335. default:
  1336. goto error;
  1337. }
  1338. GetNextToken(tkn);
  1339. // State 2: Looking for a colon.
  1340. if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_Colon ) goto done;
  1341. GetNextToken(tkn);
  1342. // State 3: Looking for an expression.
  1343. auto fieldValue = _ParseValue(tkn);
  1344. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  1345. auto type = fieldValue->type();
  1346. #endif
  1347. obj->m_elements.push_back(std::make_pair(
  1348. json::value::string(to_string_t(fieldName)),
  1349. #ifdef ENABLE_JSON_VALUE_VISUALIZER
  1350. json::value(std::move(fieldValue), type)));
  1351. #else
  1352. json::value(std::move(fieldValue))));
  1353. #endif
  1354. // State 4: Looking for a comma or a closing brace
  1355. switch (tkn.kind)
  1356. {
  1357. case JSON_Parser<CharType>::Token::TKN_Comma:
  1358. GetNextToken(tkn);
  1359. break;
  1360. case JSON_Parser<CharType>::Token::TKN_CloseBrace:
  1361. goto done;
  1362. default:
  1363. goto error;
  1364. }
  1365. }
  1366. }
  1367. done:
  1368. GetNextToken(tkn);
  1369. return obj;
  1370. error:
  1371. CreateError(tkn, U("Malformed object literal"));
  1372. }
  1373. template <typename CharType>
  1374. std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn)
  1375. {
  1376. GetNextToken(tkn);
  1377. auto result = utility::details::make_unique<web::json::details::_Array>();
  1378. if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_CloseBracket )
  1379. {
  1380. int index = 0;
  1381. while ( true )
  1382. {
  1383. // State 1: Looking for an expression.
  1384. json::value elementValue = ParseValue(tkn);
  1385. result->m_elements.push_back(std::make_pair<json::value,json::value>(json::value::number(index++), std::move(elementValue)));
  1386. // State 4: Looking for a comma or a closing bracket
  1387. switch (tkn.kind)
  1388. {
  1389. case JSON_Parser<CharType>::Token::TKN_Comma:
  1390. GetNextToken(tkn);
  1391. break;
  1392. case JSON_Parser<CharType>::Token::TKN_CloseBracket:
  1393. goto done;
  1394. default:
  1395. goto error;
  1396. }
  1397. }
  1398. }
  1399. done:
  1400. GetNextToken(tkn);
  1401. return result;
  1402. error:
  1403. CreateError(tkn, U("Malformed array literal"));
  1404. }
  1405. template <typename CharType>
  1406. std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(typename JSON_Parser<CharType>::Token &tkn)
  1407. {
  1408. switch (tkn.kind)
  1409. {
  1410. case JSON_Parser<CharType>::Token::TKN_OpenBrace:
  1411. return _ParseObject(tkn);
  1412. case JSON_Parser<CharType>::Token::TKN_OpenBracket:
  1413. return _ParseArray(tkn);
  1414. case JSON_Parser<CharType>::Token::TKN_StringLiteral:
  1415. {
  1416. auto value = utility::details::make_unique<web::json::details::_String>(std::move(tkn.spelling));
  1417. GetNextToken(tkn);
  1418. return std::move(value);
  1419. }
  1420. case JSON_Parser<CharType>::Token::TKN_IntegerLiteral:
  1421. {
  1422. try
  1423. {
  1424. std::basic_istringstream<CharType> is(std::move(tkn.spelling));
  1425. int32_t i;
  1426. is >> i;
  1427. auto value = utility::details::make_unique<web::json::details::_Number>(i);
  1428. GetNextToken(tkn);
  1429. return std::move(value);
  1430. }
  1431. catch(...)
  1432. {
  1433. std::basic_istringstream<CharType> is(std::move(tkn.spelling));
  1434. double d;
  1435. is >> d;
  1436. auto value = utility::details::make_unique<web::json::details::_Number>(d);
  1437. GetNextToken(tkn);
  1438. return std::move(value);
  1439. }
  1440. }
  1441. case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
  1442. {
  1443. std::basic_istringstream<CharType> is(std::move(tkn.spelling));
  1444. double d;
  1445. is >> d;
  1446. auto value = utility::details::make_unique<web::json::details::_Number>(d);
  1447. GetNextToken(tkn);
  1448. return std::move(value);
  1449. }
  1450. case JSON_Parser<CharType>::Token::TKN_BooleanLiteral:
  1451. {
  1452. auto value = utility::details::make_unique<web::json::details::_Boolean>(string_literal_comparer<CharType>::is_equal(tkn.spelling,m_true));
  1453. GetNextToken(tkn);
  1454. return std::move(value);
  1455. }
  1456. case JSON_Parser<CharType>::Token::TKN_NullLiteral:
  1457. {
  1458. auto value = utility::details::make_unique<web::json::details::_Null>();
  1459. GetNextToken(tkn);
  1460. return std::move(value);
  1461. }
  1462. default:
  1463. CreateError(tkn, U("Unexpected token"));
  1464. }
  1465. }
  1466. }}}
  1467. static web::json::value _parse_stream(utility::istream_t &stream)
  1468. {
  1469. web::json::details::JSON_StreamParser<utility::char_t> parser(stream);
  1470. web::json::details::JSON_Parser<utility::char_t>::Token tkn;
  1471. parser.GetNextToken(tkn);
  1472. auto value = parser.ParseValue(tkn);
  1473. if ( tkn.kind != web::json::details::JSON_Parser<utility::char_t>::Token::TKN_EOF )
  1474. {
  1475. throw web::json::json_exception(U("Left-over characters in stream after parsing a JSON value."));
  1476. }
  1477. return value;
  1478. }
  1479. #ifdef _MS_WINDOWS
  1480. static web::json::value _parse_narrow_stream(std::istream &stream)
  1481. {
  1482. web::json::details::JSON_StreamParser<char> parser(stream);
  1483. web::json::details::JSON_StreamParser<char>::Token tkn;
  1484. parser.GetNextToken(tkn);
  1485. auto value = parser.ParseValue(tkn);
  1486. if ( tkn.kind != web::json::details::JSON_Parser<char>::Token::TKN_EOF )
  1487. {
  1488. throw web::json::json_exception(U("Left-over characters in stream after parsing a JSON value."));
  1489. }
  1490. return value;
  1491. }
  1492. #endif
  1493. static web::json::value _parse_string(utility::string_t str)
  1494. {
  1495. web::json::details::JSON_StringParser<utility::char_t> parser(str);
  1496. web::json::details::JSON_Parser<utility::char_t>::Token tkn;
  1497. parser.GetNextToken(tkn);
  1498. auto value = parser.ParseValue(tkn);
  1499. if ( tkn.kind != web::json::details::JSON_Parser<utility::char_t>::Token::TKN_EOF )
  1500. {
  1501. throw web::json::json_exception(U("Left-over characters in stream after parsing a JSON value."));
  1502. }
  1503. return value;
  1504. }
  1505. web::json::value web::json::value::parse(utility::string_t value)
  1506. {
  1507. return _parse_string(std::move(value));
  1508. }
  1509. web::json::value web::json::value::parse(utility::istream_t &stream)
  1510. {
  1511. return _parse_stream(stream);
  1512. }
  1513. #ifdef _MS_WINDOWS
  1514. web::json::value web::json::value::parse(std::istream& stream)
  1515. {
  1516. return _parse_narrow_stream(stream);
  1517. }
  1518. #endif