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 * HTTP Library: JSON parser and writer
20 *
21 * For the latest on this and related APIs, please see http://casablanca.codeplex.com.
22 *
23 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
24 ****/
25 #pragma once
26
27 #ifndef _CASA_JSON_H
28 #define _CASA_JSON_H
29
30 #include <memory>
31 #include <string>
32 #include <sstream>
33 #include <vector>
34 #include <unordered_map>
35 #include <cstdint>
36 #include "cpprest/details/basic_types.h"
37 #include "cpprest/asyncrt_utils.h"
38
40 {
43 {
44 // Various forward declarations.
45 namespace details
46 {
47 class _Value;
48 class _Number;
49 class _Null;
50 class _Boolean;
51 class _String;
52 class _Object;
53 class _Array;
55 }
56
57 namespace details
58 {
59 extern bool g_keep_json_object_unsorted;
60 }
61
69
70 #ifdef _WIN32
71 #ifdef _DEBUG
72 #define ENABLE_JSON_VALUE_VISUALIZER
73 #endif
74 #endif
75
79
84 {
85 public:
90 {
103 };
104
109
115
121
127
133
139
145
154 _ASYNCRTIMP
explicit value(utility::string_t
value);
155
165 _ASYNCRTIMP
explicit value(utility::string_t
value,
bool has_escape_chars);
166
182 _ASYNCRTIMP
explicit value(
const utility::char_t*
value);
183
199 _ASYNCRTIMP
explicit value(
const utility::char_t*
value,
bool has_escape_chars);
200
205
209 _ASYNCRTIMP
value(
value &&) CPPREST_NOEXCEPT ;
210
216
221 _ASYNCRTIMP value &operator=(value &&) CPPREST_NOEXCEPT ;
222
223 // Static factories
224
229 static _ASYNCRTIMP value __cdecl
null();
230
236 static _ASYNCRTIMP value __cdecl
number(
double value);
237
243 static _ASYNCRTIMP value __cdecl
number(int32_t value);
244
250 static _ASYNCRTIMP value __cdecl
number(uint32_t value);
251
257 static _ASYNCRTIMP value __cdecl
number(int64_t value);
258
264 static _ASYNCRTIMP value __cdecl
number(uint64_t value);
265
271 static _ASYNCRTIMP value __cdecl boolean(bool value);
272
282 static _ASYNCRTIMP value __cdecl
string(
utility::string_t value);
283
294 static _ASYNCRTIMP value __cdecl
string(
utility::string_t value,
bool has_escape_chars);
295
296 #ifdef _WIN32
297 private:
298 // Only used internally by JSON parser.
299 static _ASYNCRTIMP value __cdecl
string(
const std::string &value);
300 public:
301 #endif
302
309
316 static _ASYNCRTIMP
json::value __cdecl
object(std::vector<std::pair<::utility::string_t, value>> fields,
bool keep_order =
false);
317
323
330
337
343
349
355
365
375
381
387
393
399
405
410 _ASYNCRTIMP
static value __cdecl
parse(
const utility::string_t &value);
411
418 _ASYNCRTIMP
static value __cdecl
parse(
const utility::string_t &value, std::error_code &errorCode);
419
424 _ASYNCRTIMP utility::string_t
serialize()
const;
425
430 CASABLANCA_DEPRECATED("This API is deprecated and has been renamed to avoid confusion with as_string(), use ::web::json::value::serialize() instead.")
431 _ASYNCRTIMP
utility::string_t to_string() const;
432
438 _ASYNCRTIMP static value __cdecl
parse(
utility::istream_t &input);
439
446 _ASYNCRTIMP static value __cdecl
parse(
utility::istream_t &input, std::error_code &errorCode);
447
453
454 #ifdef _WIN32
455 _ASYNCRTIMP
static value __cdecl
parse(std::istream& stream);
460
467 _ASYNCRTIMP
static value __cdecl
parse(std::istream& stream, std::error_code& error);
468
473 _ASYNCRTIMP
void serialize(std::ostream& stream)
const;
474 #endif
475
482
489
496
501 _ASYNCRTIMP
bool as_bool()
const;
502
509
516
522
528
533 _ASYNCRTIMP
const utility::string_t&
as_string()
const;
534
540 _ASYNCRTIMP
bool operator==(
const value& other)
const;
541
548 {
549 return !((*this) == other);
550 }
551
557 bool has_field(
const utility::string_t &key)
const;
558
564 CASABLANCA_DEPRECATED("This API is deprecated and will be removed in a future release, use json::value::at() instead.")
565 value
get(const
utility::string_t &key) const;
566
571 _ASYNCRTIMP
void erase(
size_t index);
572
578
584 _ASYNCRTIMP json::value&
at(
size_t index);
585
591 _ASYNCRTIMP const json::value&
at(
size_t index) const;
592
598 _ASYNCRTIMP json::value&
at(const
utility::string_t& key);
599
605 _ASYNCRTIMP const json::value&
at(const
utility::string_t& key) const;
606
612 _ASYNCRTIMP value & operator [] (const
utility::string_t &key);
613
614 #ifdef _WIN32
615 private:
616 // Only used internally by JSON parser
617 _ASYNCRTIMP value &
operator [] (
const std::string &key)
618 {
619 // JSON object stores its field map as a unordered_map of string_t, so this conversion is hard to avoid
621 }
622 public:
623 #endif
624
630 CASABLANCA_DEPRECATED("This API is deprecated and will be removed in a future release, use json::value::at() instead.")
631 value
get(
size_t index) const;
632
638 _ASYNCRTIMP value & operator [] (size_t index);
639
640 private:
641 friend class
web::json::details::_Object;
642 friend class
web::json::details::_Array;
643 template<typename CharType> friend class
web::json::details::JSON_Parser;
644
645 #ifdef _WIN32
646 _ASYNCRTIMP void format(std::basic_string<utf16char> &string) const;
651 #endif
652 _ASYNCRTIMP void format(std::basic_string<char>& string) const;
657
658 #ifdef ENABLE_JSON_VALUE_VISUALIZER
659 explicit value(std::unique_ptr<details::_Value> v,
value_type kind) : m_value(std::move(v)), m_kind(kind)
660 #else
661 explicit value(std::unique_ptr<details::_Value> v) : m_value(std::move(v))
662 #endif
663 {}
664
665 std::unique_ptr<details::_Value> m_value;
666 #ifdef ENABLE_JSON_VALUE_VISUALIZER
668 #endif
669 };
670
676 {
677 private:
678 std::string _message;
679 public:
681
682 // Must be narrow string because it derives from std::exception
683 const char* what() const CPPREST_NOEXCEPT
684 {
685 return _message.c_str();
686 }
687 };
688
689 namespace details
690 {
691 enum json_error
692 {
693 left_over_character_in_stream = 1,
694 malformed_array_literal,
695 malformed_comment,
696 malformed_literal,
697 malformed_object_literal,
698 malformed_numeric_literal,
699 malformed_string_literal,
700 malformed_token,
701 mismatched_brances,
702 nesting,
703 unexpected_token
704 };
705
707 {
708 public:
709 virtual const char* name() const CPPREST_NOEXCEPT override
710 {
711 return "json";
712 }
713
714 virtual std::string message(int ev) const override
715 {
716 switch (ev)
717 {
718 case json_error::left_over_character_in_stream:
719 return "Left-over characters in stream after parsing a JSON value";
720 case json_error::malformed_array_literal:
721 return "Malformed array literal";
722 case json_error::malformed_comment:
723 return "Malformed comment";
724 case json_error::malformed_literal:
725 return "Malformed literal";
726 case json_error::malformed_object_literal:
727 return "Malformed object literal";
728 case json_error::malformed_numeric_literal:
729 return "Malformed numeric literal";
730 case json_error::malformed_string_literal:
731 return "Malformed string literal";
732 case json_error::malformed_token:
733 return "Malformed token";
734 case json_error::mismatched_brances:
735 return "Mismatched braces";
736 case json_error::nesting:
737 return "Nesting too deep";
738 case json_error::unexpected_token:
739 return "Unexpected token";
740 default:
741 return "Unknown json error";
742 }
743 }
744 };
745
747 }
748
753 {
754 typedef std::vector<json::value> storage_type;
755
756 public:
757 typedef storage_type::iterator iterator;
758 typedef storage_type::const_iterator const_iterator;
759 typedef storage_type::reverse_iterator reverse_iterator;
760 typedef storage_type::const_reverse_iterator const_reverse_iterator;
761 typedef storage_type::size_type size_type;
762
763 private:
764 array() : m_elements() { }
765 array(size_type
size) : m_elements(size) { }
766 array(storage_type elements) : m_elements(std::move(elements)) { }
767
768 public:
774 {
775 return m_elements.begin();
776 }
777
783 {
784 return m_elements.cbegin();
785 }
786
792 {
793 return m_elements.end();
794 }
795
800 const_iterator
end()
const
801 {
802 return m_elements.cend();
803 }
804
810 {
811 return m_elements.rbegin();
812 }
813
819 {
820 return m_elements.rbegin();
821 }
822
828 {
829 return m_elements.rend();
830 }
831
836 const_reverse_iterator
rend()
const
837 {
838 return m_elements.crend();
839 }
840
846 {
847 return m_elements.cbegin();
848 }
849
855 {
856 return m_elements.cend();
857 }
858
864 {
865 return m_elements.crbegin();
866 }
867
872 const_reverse_iterator
crend()
const
873 {
874 return m_elements.crend();
875 }
876
884 {
885 return m_elements.erase(position);
886 }
887
893 {
894 if (index >= m_elements.size())
895 {
897 }
898 m_elements.erase(m_elements.begin() + index);
899 }
900
907 {
908 if (index >= m_elements.size())
910
911 return m_elements[index];
912 }
913
920 {
921 if (index >= m_elements.size())
923
924 return m_elements[index];
925 }
926
933 {
935 nMinSize += 1;
937 if (nlastSize < nMinSize)
938 m_elements.resize(nMinSize);
939
940 return m_elements[index];
941 }
942
948 {
949 return m_elements.size();
950 }
951
952 private:
953 storage_type m_elements;
954
957 };
958
963 {
964 typedef std::vector<std::pair<utility::string_t, json::value>> storage_type;
965
966 public:
967 typedef storage_type::iterator iterator;
968 typedef storage_type::const_iterator const_iterator;
969 typedef storage_type::reverse_iterator reverse_iterator;
970 typedef storage_type::const_reverse_iterator const_reverse_iterator;
971 typedef storage_type::size_type size_type;
972
973 private:
974 object(
bool keep_order =
false) : m_elements(), m_keep_order(keep_order) { }
975 object(storage_type elements,
bool keep_order =
false) : m_elements(std::move(elements)), m_keep_order(keep_order)
976 {
977 if (!keep_order) {
978 sort(m_elements.begin(), m_elements.end(), compare_pairs);
979 }
980 }
981
982 public:
988 {
989 return m_elements.begin();
990 }
991
997 {
998 return m_elements.cbegin();
999 }
1000
1006 {
1007 return m_elements.end();
1008 }
1009
1015 {
1016 return m_elements.cend();
1017 }
1018
1024 {
1025 return m_elements.rbegin();
1026 }
1027
1033 {
1034 return m_elements.rbegin();
1035 }
1036
1042 {
1043 return m_elements.rend();
1044 }
1045
1050 const_reverse_iterator
rend()
const
1051 {
1052 return m_elements.crend();
1053 }
1054
1060 {
1061 return m_elements.cbegin();
1062 }
1063
1069 {
1070 return m_elements.cend();
1071 }
1072
1078 {
1079 return m_elements.crbegin();
1080 }
1081
1087 {
1088 return m_elements.crend();
1089 }
1090
1098 {
1099 return m_elements.erase(position);
1100 }
1101
1106 void erase(
const utility::string_t &key)
1107 {
1108 auto iter = find_by_key(key);
1109 if (iter == m_elements.end())
1110 {
1112 }
1113
1114 m_elements.erase(iter);
1115 }
1116
1123 {
1124 auto iter = find_by_key(key);
1125 if (iter == m_elements.end())
1126 {
1128 }
1129
1130 return iter->second;
1131 }
1132
1139 {
1140 auto iter = find_by_key(key);
1141 if (iter == m_elements.end())
1142 {
1144 }
1145
1146 return iter->second;
1147 }
1148
1155 {
1156 auto iter = find_insert_location(key);
1157
1158 if (iter == m_elements.end() || key != iter->first)
1159 {
1160 return m_elements.insert(iter, std::pair<utility::string_t, value>(key, value()))->second;
1161 }
1162
1163 return iter->second;
1164 }
1165
1171 const_iterator
find(
const utility::string_t& key)
const
1172 {
1173 return find_by_key(key);
1174 }
1175
1181 {
1182 return m_elements.size();
1183 }
1184
1190 {
1191 return m_elements.empty();
1192 }
1193 private:
1194
1195 static bool compare_pairs(const std::pair<utility::string_t, value>& p1, const std::pair<utility::string_t, value>& p2)
1196 {
1197 return p1.first < p2.first;
1198 }
1199 static bool compare_with_key(const std::pair<utility::string_t, value>& p1, const utility::string_t& key)
1200 {
1201 return p1.first < key;
1202 }
1203
1204 storage_type::iterator find_insert_location(const utility::string_t &key)
1205 {
1206 if (m_keep_order)
1207 {
1208 return std::find_if(m_elements.begin(), m_elements.end(),
1209 [&key](const std::pair<utility::string_t, value>& p) {
1210 return p.first == key;
1211 });
1212 }
1213 else
1214 {
1215 return std::lower_bound(m_elements.begin(), m_elements.end(), key, compare_with_key);
1216 }
1217 }
1218
1219 storage_type::const_iterator find_by_key(const utility::string_t& key) const
1220 {
1221 if (m_keep_order)
1222 {
1223 return std::find_if(m_elements.begin(), m_elements.end(),
1224 [&key](const std::pair<utility::string_t, value>& p) {
1225 return p.first == key;
1226 });
1227 }
1228 else
1229 {
1230 auto iter = std::lower_bound(m_elements.begin(), m_elements.end(), key, compare_with_key);
1231 if (iter != m_elements.end() && key != iter->first)
1232 {
1233 return m_elements.end();
1234 }
1235 return iter;
1236 }
1237 }
1238
1239 storage_type::iterator find_by_key(const utility::string_t& key)
1240 {
1241 auto iter = find_insert_location(key);
1242 if (iter != m_elements.end() && key != iter->first)
1243 {
1244 return m_elements.end();
1245 }
1246 return iter;
1247 }
1248
1249 storage_type m_elements;
1250 bool m_keep_order;
1251 friend class details::_Object;
1252
1253 template<typename CharType> friend class json::details::JSON_Parser;
1254 };
1255
1260 {
1261 // Note that these constructors make sure that only negative integers are stored as signed int64 (while others convert to unsigned int64).
1262 // This helps handling number objects e.g. comparing two numbers.
1263
1264 number(
double value) : m_value(value), m_type(double_type) { }
1265 number(int32_t value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) { }
1266 number(uint32_t value) : m_intval(value), m_type(unsigned_type) { }
1267 number(int64_t value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) { }
1268 number(uint64_t value) : m_uintval(value), m_type(unsigned_type) { }
1269
1270 public:
1271
1277
1283
1289
1295 {
1296 switch (m_type)
1297 {
1298 case signed_type : return m_intval >= 0;
1299 case unsigned_type : return true;
1300 case double_type :
1301 default :
1302 return false;
1303 }
1304 }
1305
1311 {
1312 switch (m_type)
1313 {
1314 case double_type : return m_value;
1315 case signed_type : return static_cast<double>(m_intval);
1316 case unsigned_type : return static_cast<double>(m_uintval);
1317 default : return false;
1318 }
1319 }
1320
1326 {
1327 if (m_type == double_type)
1328 return static_cast<int32_t>(m_value);
1329 else
1330 return static_cast<int32_t>(m_intval);
1331 }
1332
1338 {
1339 if (m_type == double_type)
1340 return static_cast<uint32_t>(m_value);
1341 else
1342 return static_cast<uint32_t>(m_intval);
1343 }
1344
1350 {
1351 if (m_type == double_type)
1352 return static_cast<int64_t>(m_value);
1353 else
1354 return static_cast<int64_t>(m_intval);
1355 }
1356
1362 {
1363 if (m_type == double_type)
1364 return static_cast<uint64_t>(m_value);
1365 else
1366 return static_cast<uint64_t>(m_intval);
1367 }
1368
1374 {
1375 return m_type != double_type;
1376 }
1377
1384 {
1385 if (m_type != other.m_type)
1386 return false;
1387
1388 switch (m_type)
1389 {
1390 case json::number::type::signed_type :
1391 return m_intval == other.m_intval;
1392 case json::number::type::unsigned_type :
1393 return m_uintval == other.m_uintval;
1394 case json::number::type::double_type :
1395 return m_value == other.m_value;
1396 }
1397 __assume(0);
1398 }
1399
1400 private:
1401 union
1402 {
1403 int64_t m_intval;
1404 uint64_t m_uintval;
1405 double m_value;
1406 };
1407
1408 enum type
1409 {
1410 signed_type=0, unsigned_type, double_type
1411 } m_type;
1412
1413 friend class details::_Number;
1414 };
1415
1416 namespace details
1417 {
1419 {
1420 public:
1421 virtual std::unique_ptr<_Value> _copy_value() = 0;
1422
1423 virtual bool has_field(const utility::string_t &) const { return false; }
1424 virtual value get_field(
const utility::string_t &)
const {
throw json_exception(_XPLATSTR(
"not an object")); }
1425 virtual value get_element(array::size_type)
const {
throw json_exception(_XPLATSTR(
"not an array")); }
1426
1427 virtual value &index(
const utility::string_t &) {
throw json_exception(_XPLATSTR(
"not an object")); }
1428 virtual value &index(array::size_type) {
throw json_exception(_XPLATSTR(
"not an array")); }
1429
1430 virtual const value &cnst_index(
const utility::string_t &)
const {
throw json_exception(_XPLATSTR(
"not an object")); }
1431 virtual const value &cnst_index(array::size_type)
const {
throw json_exception(_XPLATSTR(
"not an array")); }
1432
1433 // Common function used for serialization to strings and streams.
1434 virtual void serialize_impl(std::string& str) const
1435 {
1436 format(str);
1437 }
1438 #ifdef _WIN32
1439 virtual void serialize_impl(std::wstring& str) const
1440 {
1441 format(str);
1442 }
1443 #endif
1444
1445 virtual utility::string_t to_string() const
1446 {
1447 utility::string_t str;
1448 serialize_impl(str);
1449 return str;
1450 }
1451
1453
1454 virtual bool is_integer()
const {
throw json_exception(_XPLATSTR(
"not a number")); }
1455 virtual bool is_double()
const {
throw json_exception(_XPLATSTR(
"not a number")); }
1456
1458 virtual double as_double()
const {
throw json_exception(_XPLATSTR(
"not a number")); }
1459 virtual int as_integer()
const {
throw json_exception(_XPLATSTR(
"not a number")); }
1460 virtual bool as_bool()
const {
throw json_exception(_XPLATSTR(
"not a boolean")); }
1465 virtual const utility::string_t& as_string()
const {
throw json_exception(_XPLATSTR(
"not a string")); }
1466
1467 virtual size_t size() const { return 0; }
1468
1470
1471 protected:
1473
1474 virtual void format(std::basic_string<char>& stream) const
1475 {
1476 stream.append("null");
1477 }
1478 #ifdef _WIN32
1479 virtual void format(std::basic_string<wchar_t>& stream) const
1480 {
1481 stream.append(L"null");
1482 }
1483 #endif
1484 private:
1485
1487 };
1488
1490 {
1491 public:
1492 virtual std::unique_ptr<_Value> _copy_value()
1493 {
1494 return utility::details::make_unique<_Null>();
1495 }
1497 };
1498
1500 {
1501 public:
1502 _Number(
double value) : m_number(value) { }
1503 _Number(int32_t value) : m_number(value) { }
1504 _Number(uint32_t value) : m_number(value) { }
1505 _Number(int64_t value) : m_number(value) { }
1506 _Number(uint64_t value) : m_number(value) { }
1507
1508 virtual std::unique_ptr<_Value> _copy_value()
1509 {
1510 return utility::details::make_unique<_Number>(*this);
1511 }
1512
1514
1515 virtual bool is_integer()
const {
return m_number.
is_integral(); }
1516 virtual bool is_double()
const {
return !m_number.
is_integral(); }
1517
1518 virtual double as_double() const
1519 {
1521 }
1522
1523 virtual int as_integer() const
1524 {
1526 }
1527
1528 virtual const number& as_number() {
return m_number; }
1529
1530 protected:
1531 virtual void format(std::basic_string<char>& stream) const ;
1532 #ifdef _WIN32
1533 virtual void format(std::basic_string<wchar_t>& stream) const;
1534 #endif
1535 private:
1537
1539 };
1540
1542 {
1543 public:
1544 _Boolean(
bool value) : m_value(value) { }
1545
1546 virtual std::unique_ptr<_Value> _copy_value()
1547 {
1548 return utility::details::make_unique<_Boolean>(*this);
1549 }
1550
1552
1553 virtual bool as_bool() const { return m_value; }
1554
1555 protected:
1556 virtual void format(std::basic_string<char>& stream) const
1557 {
1558 stream.append(m_value ? "true" : "false");
1559 }
1560
1561 #ifdef _WIN32
1562 virtual void format(std::basic_string<wchar_t>& stream) const
1563 {
1564 stream.append(m_value ? L"true" : L"false");
1565 }
1566 #endif
1567 private:
1569 bool m_value;
1570 };
1571
1573 {
1574 public:
1575
1576 _String(utility::string_t value) : m_string(std::move(value))
1577 {
1578 m_has_escape_char = has_escape_chars(*this);
1579 }
1580 _String(utility::string_t value,
bool escaped_chars)
1581 : m_string(std::move(value)),
1582 m_has_escape_char(escaped_chars)
1583 { }
1584
1585 #ifdef _WIN32
1587 {
1588 m_has_escape_char = has_escape_chars(*this);
1589 }
1590 _String(std::string &&value,
bool escape_chars)
1592 m_has_escape_char(escape_chars)
1593 { }
1594 #endif
1595
1596 virtual std::unique_ptr<_Value> _copy_value()
1597 {
1598 return utility::details::make_unique<_String>(*this);
1599 }
1600
1602
1603 virtual const utility::string_t & as_string() const;
1604
1605 virtual void serialize_impl(std::string& str) const
1606 {
1607 serialize_impl_char_type(str);
1608 }
1609 #ifdef _WIN32
1610 virtual void serialize_impl(std::wstring& str) const
1611 {
1612 serialize_impl_char_type(str);
1613 }
1614 #endif
1615
1616 protected:
1617 virtual void format(std::basic_string<char>& str) const;
1618 #ifdef _WIN32
1619 virtual void format(std::basic_string<wchar_t>& str) const;
1620 #endif
1621
1622 private:
1625
1626 size_t get_reserve_size() const
1627 {
1628 return m_string.size() + 2;
1629 }
1630
1631 template <typename CharType>
1632 void serialize_impl_char_type(std::basic_string<CharType>& str) const
1633 {
1634 // To avoid repeated allocations reserve some space all up front.
1635 // size of string + 2 for quotes
1636 str.reserve(get_reserve_size());
1637 format(str);
1638 }
1639
1640 std::string as_utf8_string() const;
1641 utf16string as_utf16_string() const;
1642
1643 utility::string_t m_string;
1644
1645 // There are significant performance gains that can be made by knowning whether
1646 // or not a character that requires escaping is present.
1647 bool m_has_escape_char;
1648 static bool has_escape_chars(
const _String &str);
1649 };
1650
1651 template<typename CharType>
1652 _ASYNCRTIMP void append_escape_string(std::basic_string<CharType>& str, const std::basic_string<CharType>& escaped);
1653
1654 void format_string(const utility::string_t& key, utility::string_t& str);
1655
1656 #ifdef _WIN32
1657 void format_string(const utility::string_t& key, std::string& str);
1658 #endif
1659
1661 {
1662 public:
1663
1664 _Object(
bool keep_order) : m_object(keep_order) { }
1665 _Object(object::storage_type fields,
bool keep_order) : m_object(std::move(fields), keep_order) { }
1666
1667 virtual std::unique_ptr<_Value> _copy_value()
1668 {
1669 return utility::details::make_unique<_Object>(*this);
1670 }
1671
1673
1674 virtual const json::object& as_object()
const {
return m_object; }
1675
1677
1678 virtual bool has_field(const utility::string_t &) const;
1679
1680 virtual json::value &index(
const utility::string_t &key);
1681
1682 bool is_equal(
const _Object* other)
const
1683 {
1684 if (m_object.
size() != other->m_object.
size())
1685 return false;
1686
1687 return std::equal(std::begin(m_object), std::end(m_object), std::begin(other->m_object));
1688 }
1689
1690 virtual void serialize_impl(std::string& str) const
1691 {
1692 // To avoid repeated allocations reserve some space all up front.
1693 str.reserve(get_reserve_size());
1694 format(str);
1695 }
1696 #ifdef _WIN32
1697 virtual void serialize_impl(std::wstring& str) const
1698 {
1699 // To avoid repeated allocations reserve some space all up front.
1700 str.reserve(get_reserve_size());
1701 format(str);
1702 }
1703 #endif
1704 size_t size()
const {
return m_object.
size(); }
1705
1706 protected:
1707 virtual void format(std::basic_string<char>& str) const
1708 {
1709 format_impl(str);
1710 }
1711 #ifdef _WIN32
1712 virtual void format(std::basic_string<wchar_t>& str) const
1713 {
1714 format_impl(str);
1715 }
1716 #endif
1717
1718 private:
1720
1722
1723 template<typename CharType>
1724 void format_impl(std::basic_string<CharType>& str) const
1725 {
1726 str.push_back('{');
1727 if(!m_object.
empty())
1728 {
1729 auto lastElement = m_object.
end() - 1;
1730 for (
auto iter = m_object.
begin(); iter != lastElement; ++iter)
1731 {
1732 format_string(iter->first, str);
1733 str.push_back(':');
1734 iter->second.format(str);
1735 str.push_back(',');
1736 }
1737 format_string(lastElement->first, str);
1738 str.push_back(':');
1739 lastElement->second.format(str);
1740 }
1741 str.push_back('}');
1742 }
1743
1744 size_t get_reserve_size() const
1745 {
1746 // This is a heuristic we can tune more in the future:
1747 // Basically size of string plus
1748 // sum size of value if an object, array, or string.
1749 size_t reserveSize = 2; // For brackets {}
1750 for(
auto iter = m_object.
begin(); iter != m_object.
end(); ++iter)
1751 {
1752 reserveSize += iter->first.length() + 2; // 2 for quotes
1753 size_t valueSize = iter->second.size() * 20; // Multipler by each object/array element
1754 if(valueSize == 0)
1755 {
1757 {
1758 valueSize =
static_cast<_String *
>(iter->second.m_value.get())->get_reserve_size();
1759 }
1760 else
1761 {
1762 valueSize = 5; // true, false, or null
1763 }
1764 }
1765 reserveSize += valueSize;
1766 }
1767 return reserveSize;
1768 }
1769 };
1770
1772 {
1773 public:
1775 _Array(array::size_type size) : m_array(size) {}
1776 _Array(array::storage_type elements) : m_array(std::move(elements)) { }
1777
1778 virtual std::unique_ptr<_Value> _copy_value()
1779 {
1780 return utility::details::make_unique<_Array>(*this);
1781 }
1782
1784
1785 virtual json::array& as_array() {
return m_array; }
1786 virtual const json::array& as_array()
const {
return m_array; }
1787
1788 virtual json::value &index(json::array::size_type index)
1789 {
1790 return m_array[index];
1791 }
1792
1793 bool is_equal(
const _Array* other)
const
1794 {
1795 if ( m_array.
size() != other->m_array.
size())
1796 return false;
1797
1798 auto iterT = m_array.
cbegin();
1799 auto iterO = other->m_array.
cbegin();
1800 auto iterTe = m_array.
cend();
1801 auto iterOe = other->m_array.
cend();
1802
1803 for (; iterT != iterTe && iterO != iterOe; ++iterT, ++iterO)
1804 {
1805 if ( *iterT != *iterO )
1806 return false;
1807 }
1808
1809 return true;
1810 }
1811
1812 virtual void serialize_impl(std::string& str) const
1813 {
1814 // To avoid repeated allocations reserve some space all up front.
1815 str.reserve(get_reserve_size());
1816 format(str);
1817 }
1818 #ifdef _WIN32
1819 virtual void serialize_impl(std::wstring& str) const
1820 {
1821 // To avoid repeated allocations reserve some space all up front.
1822 str.reserve(get_reserve_size());
1823 format(str);
1824 }
1825 #endif
1826 size_t size()
const {
return m_array.
size(); }
1827
1828 protected:
1829 virtual void format(std::basic_string<char>& str) const
1830 {
1831 format_impl(str);
1832 }
1833 #ifdef _WIN32
1834 virtual void format(std::basic_string<wchar_t>& str) const
1835 {
1836 format_impl(str);
1837 }
1838 #endif
1839 private:
1841
1843
1844 template<typename CharType>
1845 void format_impl(std::basic_string<CharType>& str) const
1846 {
1847 str.push_back('[');
1848 if(!m_array.m_elements.empty())
1849 {
1850 auto lastElement = m_array.m_elements.end() - 1;
1851 for (auto iter = m_array.m_elements.begin(); iter != lastElement; ++iter)
1852 {
1853 iter->format(str);
1854 str.push_back(',');
1855 }
1856 lastElement->format(str);
1857 }
1858 str.push_back(']');
1859 }
1860
1861 size_t get_reserve_size() const
1862 {
1863 // This is a heuristic we can tune more in the future:
1864 // Basically sum size of each value if an object, array, or string by a multiplier.
1865 size_t reserveSize = 2; // For brackets []
1866 for(
auto iter = m_array.
cbegin(); iter != m_array.
cend(); ++iter)
1867 {
1868 size_t valueSize = iter->size() * 20; // Per each nested array/object
1869
1870 if(valueSize == 0)
1871 valueSize = 5; // true, false, or null
1872
1873 reserveSize += valueSize;
1874 }
1875 return reserveSize;
1876 }
1877 };
1878 } // namespace details
1879
1885 {
1886 return m_value->size();
1887 }
1888
1895 {
1896 return m_value->has_field(key);
1897 }
1898
1905 {
1906 return m_value->get_field(key);
1907 }
1908
1915 {
1916 return m_value->get_element(index);
1917 }
1918
1925 _ASYNCRTIMP utility::ostream_t& __cdecl
operator << (utility::ostream_t &os,
const json::value &val);
1926
1933 _ASYNCRTIMP utility::istream_t& __cdecl
operator >> (utility::istream_t &is, json::value &val);
1934 }}
1935
1936 #endif
bool operator==(const number &other) const
Compares two JSON numbers for equality.
Definition: json.h:1383
bool is_integral() const
Is the number represented internally as an integral type?
Definition: json.h:1373
A JSON array represented as a C++ class.
Definition: json.h:752
Boolean value.
Definition: json.h:94
_ASYNCRTIMP bool is_uint32() const
Does the number fit into unsigned int32?
Number value.
Definition: json.h:92
int32_t to_int32() const
Converts the JSON number to int32.
Definition: json.h:1325
const_reverse_iterator crbegin() const
Gets the beginning const reverse iterator element of the object.
Definition: json.h:1077
json::value & operator[](size_type index)
Accesses an element of a JSON array.
Definition: json.h:932
static _ASYNCRTIMP json::value __cdecl object(bool keep_order=false)
Creates an object value
value get(const utility::string_t &key) const
Accesses a field of a JSON object.
const json::value & at(size_type index) const
Accesses an element of a JSON array. Throws when index out of bounds.
Definition: json.h:919
reverse_iterator rbegin()
Gets the beginning reverse iterator element of the object
Definition: json.h:1023
Object value.
Definition: json.h:98
void erase(const utility::string_t &key)
Deletes an element of the JSON object. If the key doesn't exist, this method throws.
Definition: json.h:1106
const_iterator end() const
Gets the end const iterator element of the object.
Definition: json.h:1014
size_type size() const
Gets the number of elements of the array.
Definition: json.h:947
_ASYNCRTIMP int as_integer() const
Converts the JSON value to a C++ integer, if and only if it is a number value. Throws json_exception ...
const_iterator cend() const
Gets the end const iterator element of the array.
Definition: json.h:854
_ASYNCRTIMP bool is_int64() const
Does the number fit into int64?
bool has_field(const utility::string_t &key) const
Tests for the presence of a field.
Definition: json.h:1894
iterator begin()
Gets the beginning iterator element of the object
Definition: json.h:987
Null value.
Definition: json.h:102
const_reverse_iterator crend() const
Gets the end const reverse iterator element of the object.
Definition: json.h:1086
bool is_string() const
Is the current value a string value?
Definition: json.h:386
bool is_number() const
Is the current value a number value?
Definition: json.h:354
_ASYNCRTIMP json::array & as_array()
Converts the JSON value to a json array, if and only if it is an array value.
reverse_iterator rend()
Gets the end reverse iterator element of the array
Definition: json.h:827
A JSON number represented as a C++ class.
Definition: json.h:1259
uint64_t to_uint64() const
Converts the JSON number to unsigned int64.
Definition: json.h:1361
The web namespace contains functionality common to multiple protocols like HTTP and WebSockets...
Definition: base_uri.h:37
_ASYNCRTIMP json::object & as_object()
Converts the JSON value to a json object, if and only if it is an object value.
const_iterator find(const utility::string_t &key) const
Gets an iterator to an element of a JSON object.
Definition: json.h:1171
bool is_null() const
Is the current value a null value?
Definition: json.h:348
value_type
This enumeration represents the various kinds of JSON values.
Definition: json.h:89
_ASYNCRTIMP bool as_bool() const
Converts the JSON value to a C++ bool, if and only if it is a Boolean value.
bool is_array() const
Is the current value an array?
Definition: json.h:392
iterator erase(iterator position)
Deletes an element of the JSON array.
Definition: json.h:883
size_t size() const
Gets the number of children of the value.
Definition: json.h:1884
iterator begin()
Gets the beginning iterator element of the array
Definition: json.h:773
_ASYNCRTIMP utility::ostream_t &__cdecl operator<<(utility::ostream_t &os, const json::value &val)
A standard std::ostream operator to facilitate writing JSON values to streams.
iterator end()
Gets the end iterator element of the array
Definition: json.h:791
bool is_uint64() const
Does the number fit into unsigned int64?
Definition: json.h:1294
_ASYNCRTIMP utility::string_t serialize() const
Serializes the current JSON value to a C++ string.
_ASYNCRTIMP utility::string_t __cdecl to_string_t(std::string &&s)
Converts to a platform dependent Unicode string type.
const_iterator cbegin() const
Gets the beginning const iterator element of the object.
Definition: json.h:1059
const_reverse_iterator crend() const
Gets the end const reverse iterator element of the array.
Definition: json.h:872
const_reverse_iterator rend() const
Gets the end const reverse iterator element of the object
Definition: json.h:1050
reverse_iterator rend()
Gets the end reverse iterator element of the object
Definition: json.h:1041
bool operator!=(const value &other) const
Compares two JSON values for inequality.
Definition: json.h:547
bool empty() const
Checks if there are any elements in the JSON object.
Definition: json.h:1189
_ASYNCRTIMP bool is_int32() const
Does the number fit into int32?
_ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string &value)
Converts to a UTF-16 from string.
json::value & operator[](const utility::string_t &key)
Accesses an element of a JSON object.
Definition: json.h:1154
const json::value & at(const utility::string_t &key) const
Accesses an element of a JSON object. If the key doesn't exist, this method throws.
Definition: json.h:1138
_ASYNCRTIMP json::value & at(size_t index)
Accesses an element of a JSON array. Throws when index out of bounds.
void _ASYNCRTIMP __cdecl keep_object_element_order(bool keep_order)
Preserve the order of the name/value pairs when parsing a JSON object. The default is false...
static _ASYNCRTIMP value __cdecl parse(const utility::string_t &value)
Parses a string and construct a JSON value.
const_reverse_iterator rbegin() const
Gets the beginning const reverse iterator element of the array
Definition: json.h:818
reverse_iterator rbegin()
Gets the beginning reverse iterator element of the array
Definition: json.h:809
bool is_boolean() const
Is the current value a Boolean value?
Definition: json.h:380
A JSON object represented as a C++ class.
Definition: json.h:962
iterator erase(iterator position)
Deletes an element of the JSON object.
Definition: json.h:1097
const_iterator begin() const
Gets the beginning const iterator element of the array.
Definition: json.h:782
_ASYNCRTIMP bool is_integer() const
Is the current value represented as an integer number value?
A JSON value represented as a C++ class.
Definition: json.h:83
static _ASYNCRTIMP value __cdecl null()
Creates a null value
A single exception type to represent errors in parsing, converting, and accessing elements of JSON va...
Definition: json.h:675
const_reverse_iterator rend() const
Gets the end const reverse iterator element of the array
Definition: json.h:836
const_iterator end() const
Gets the end const iterator element of the array.
Definition: json.h:800
static _ASYNCRTIMP value __cdecl string(utility::string_t value)
Creates a string value
bool is_object() const
Is the current value an object?
Definition: json.h:398
static _ASYNCRTIMP json::value __cdecl array()
Creates an empty JSON array
_ASYNCRTIMP double as_double() const
Converts the JSON value to a C++ double, if and only if it is a number value. Throws json_exception i...
const_reverse_iterator crbegin() const
Gets the beginning const reverse iterator element of the array.
Definition: json.h:863
iterator end()
Gets the end iterator element of the object
Definition: json.h:1005
const_iterator cend() const
Gets the end const iterator element of the object.
Definition: json.h:1068
json::value & at(size_type index)
Accesses an element of a JSON array. Throws when index out of bounds.
Definition: json.h:906
_ASYNCRTIMP utility::istream_t &__cdecl operator>>(utility::istream_t &is, json::value &val)
A standard std::istream operator to facilitate reading JSON values from streams.
double to_double() const
Converts the JSON number to a C++ double.
Definition: json.h:1310
_ASYNCRTIMP bool is_double() const
Is the current value represented as an double number value?
String value.
Definition: json.h:96
_ASYNCRTIMP json::value::value_type type() const
Accesses the type of JSON value the current value instance is
_ASYNCRTIMP const json::number & as_number() const
Converts the JSON value to a number class, if and only if it is a number value. Throws json_exception...
_ASYNCRTIMP bool operator==(const value &other) const
Compares two JSON values for equality.
_ASYNCRTIMP value & operator[](const utility::string_t &key)
Accesses a field of a JSON object.
size_type size() const
Gets the number of elements of the object.
Definition: json.h:1180
_ASYNCRTIMP value()
Constructor creating a null value
Array value.
Definition: json.h:100
Definition: SafeInt3.hpp:5564
uint32_t to_uint32() const
Converts the JSON number to unsigned int32.
Definition: json.h:1337
_ASYNCRTIMP std::string __cdecl to_utf8string(std::string value)
Converts to a UTF-8 string.
Various utilities for string conversions and date and time manipulation.
Definition: asyncrt_utils.h:50
int64_t to_int64() const
Converts the JSON number to int64.
Definition: json.h:1349
_ASYNCRTIMP void erase(size_t index)
Erases an element of a JSON array. Throws if index is out of bounds.
const_iterator cbegin() const
Gets the beginning const iterator element of the array.
Definition: json.h:845
json::value & at(const utility::string_t &key)
Accesses an element of a JSON object. If the key doesn't exist, this method throws.
Definition: json.h:1122
_ASYNCRTIMP const utility::string_t & as_string() const
Converts the JSON value to a C++ STL string, if and only if it is a string value. ...
const_reverse_iterator rbegin() const
Gets the beginning const reverse iterator element of the object
Definition: json.h:1032
const_iterator begin() const
Gets the beginning const iterator element of the object.
Definition: json.h:996
void erase(size_type index)
Deletes the element at an index of the JSON array.
Definition: json.h:892