1 #include "simdjson.h"
2 #include "test_ondemand.h"
3 
4 using namespace std;
5 using namespace simdjson;
6 using error_code=simdjson::error_code;
7 
8 #if SIMDJSON_EXCEPTIONS
9 
basics_1()10 bool basics_1() {
11   TEST_START();
12 
13   ondemand::parser parser;
14   auto json = padded_string::load("twitter.json");
15   ondemand::document doc = parser.iterate(json); // load and parse a file
16 
17   simdjson_unused auto unused_doc = doc.get_object();
18 
19   TEST_SUCCEED();
20 }
21 
basics_2()22 bool basics_2() {
23   TEST_START();
24 
25   ondemand::parser parser;
26   auto json = "[1,2,3]"_padded; // The _padded suffix creates a simdjson::padded_string instance
27   ondemand::document doc = parser.iterate(json); // parse a string
28 
29   simdjson_unused auto unused_doc = doc.get_array();
30 
31   TEST_SUCCEED();
32 }
33 
basics_3()34 bool basics_3() {
35   TEST_START();
36 
37   ondemand::parser parser;
38   char json[3+SIMDJSON_PADDING];
39   strcpy(json, "[1]");
40   ondemand::document doc = parser.iterate(json, strlen(json), sizeof(json));
41 
42   simdjson_unused auto unused_doc = doc.get_array();
43 
44   TEST_SUCCEED();
45 }
46 
using_the_parsed_json_1()47 bool using_the_parsed_json_1() {
48   TEST_START();
49 
50   try {
51 
52     ondemand::parser parser;
53     auto json = R"(  { "x": 1, "y": 2 }  )"_padded;
54     auto doc = parser.iterate(json);
55     double y = doc.find_field("y"); // The cursor is now after the 2 (at })
56     double x = doc.find_field("x"); // This fails, because there are no more fields after "y"
57 
58     cout << x << ", " << y << endl;
59   } catch (...) {
60     TEST_SUCCEED();
61   }
62   TEST_FAIL("expected an exception");
63 }
64 
using_the_parsed_json_2()65 bool using_the_parsed_json_2() {
66   TEST_START();
67 
68   ondemand::parser parser;
69   auto json = R"(  { "x": 1, "y": 2 }  )"_padded;
70   auto doc = parser.iterate(json);
71   double y = doc["y"]; // The cursor is now after the 2 (at })
72   double x = doc["x"]; // Success: [] loops back around to find "x"
73 
74   cout << x << ", " << y << endl;
75 
76   TEST_SUCCEED();
77 }
78 
using_the_parsed_json_3()79 bool using_the_parsed_json_3() {
80   TEST_START();
81 
82   ondemand::parser parser;
83   auto cars_json = R"( [
84     { "make": "Toyota", "model": "Camry",  "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
85     { "make": "Kia",    "model": "Soul",   "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
86     { "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
87   ] )"_padded;
88 
89   // Iterating through an array of objects
90   for (ondemand::object car : parser.iterate(cars_json)) {
91     // Accessing a field by name
92     cout << "Make/Model: " << std::string_view(car["make"]) << "/" << std::string_view(car["model"]) << endl;
93 
94     // Casting a JSON element to an integer
95     uint64_t year = car["year"];
96     cout << "- This car is " << 2020 - year << "years old." << endl;
97 
98     // Iterating through an array of floats
99     double total_tire_pressure = 0;
100     for (double tire_pressure : car["tire_pressure"]) {
101       total_tire_pressure += tire_pressure;
102     }
103     cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
104   }
105 
106   TEST_SUCCEED();
107 }
108 
using_the_parsed_json_4()109 bool using_the_parsed_json_4() {
110   TEST_START();
111 
112   ondemand::parser parser;
113   auto points_json = R"( [
114       {  "12345" : {"x":12.34, "y":56.78, "z": 9998877}   },
115       {  "12545" : {"x":11.44, "y":12.78, "z": 11111111}  }
116     ] )"_padded;
117 
118   // Parse and iterate through an array of objects
119   for (ondemand::object points : parser.iterate(points_json)) {
120     for (auto point : points) {
121       cout << "id: " << std::string_view(point.unescaped_key()) << ": (";
122       cout << point.value()["x"].get_double() << ", ";
123       cout << point.value()["y"].get_double() << ", ";
124       cout << point.value()["z"].get_int64() << endl;
125     }
126   }
127 
128   TEST_SUCCEED();
129 }
130 
using_the_parsed_json_5()131 bool using_the_parsed_json_5() {
132   TEST_START();
133 
134   auto abstract_json = R"(
135     { "str" : { "123" : {"abc" : 3.14 } } }
136   )"_padded;
137   ondemand::parser parser;
138   auto doc = parser.iterate(abstract_json);
139   cout << doc["str"]["123"]["abc"].get_double() << endl; // Prints 3.14
140 
141   TEST_SUCCEED();
142 }
143 
144 #endif // SIMDJSON_EXCEPTIONS
145 
using_the_parsed_json_6_process()146 int using_the_parsed_json_6_process() {
147   auto abstract_json = R"(
148     { "str" : { "123" : {"abc" : 3.14 } } }
149   )"_padded;
150   ondemand::parser parser;
151 
152   double value;
153   auto doc = parser.iterate(abstract_json);
154   auto error = doc["str"]["123"]["abc"].get(value);
155   if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
156   cout << value << endl; // Prints 3.14
157 
158   return EXIT_SUCCESS;
159 }
using_the_parsed_json_6()160 bool using_the_parsed_json_6() {
161   TEST_START();
162   ASSERT_EQUAL(using_the_parsed_json_6_process(), EXIT_SUCCESS);
163   TEST_SUCCEED();
164 }
165 
main()166 int main() {
167   if (
168     true
169 #if SIMDJSON_EXCEPTIONS
170 //    && basics_1() // Fails because twitter.json isn't in current directory. Compile test only.
171     && basics_2()
172     && using_the_parsed_json_1()
173     && using_the_parsed_json_2()
174     && using_the_parsed_json_3()
175     && using_the_parsed_json_4()
176     && using_the_parsed_json_5()
177 #endif
178     && using_the_parsed_json_6()
179   ) {
180     return 0;
181   } else {
182     return 1;
183   }
184 }
185