1 #ifndef STAN__IO__JSON__JSON_PARSER_HPP
2 #define STAN__IO__JSON__JSON_PARSER_HPP
10 #include <boost/lexical_cast.hpp>
20 const unsigned int MIN_HIGH_SURROGATE = 0xD800;
21 const unsigned int MAX_HIGH_SURROGATE = 0xDBFF;
22 const unsigned int MIN_LOW_SURROGATE = 0xDC00;
23 const unsigned int MAX_LOW_SURROGATE = 0xDFFF;
24 const unsigned int MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
26 inline bool is_high_surrogate(
unsigned int cp) {
27 return (cp >= MIN_HIGH_SURROGATE && cp <= MAX_HIGH_SURROGATE);
30 inline bool is_low_surrogate(
unsigned int cp) {
31 return (cp >= MIN_LOW_SURROGATE && cp <= MAX_LOW_SURROGATE);
34 inline bool is_whitespace(
char c) {
35 return c ==
' ' || c ==
'\n' || c ==
'\t' || c ==
'\r';
44 template <
typename Handler,
bool Val
idate_UTF_8>
69 json_error json_exception(
const std::string& msg)
const {
71 ss <<
"Error in JSON parsing at"
76 return json_error(ss.str());
81 char c = get_non_ws_char();
84 parse_object_members_end_object();
86 }
else if (c ==
'[') {
89 parse_array_values_end_array();
92 throw json_exception(
"expecting start of object ({) or array ([)");
99 char c = get_non_ws_char();
102 parse_false_literal();
103 }
else if (c ==
'n') {
105 parse_null_literal();
106 }
else if (c ==
't') {
108 parse_true_literal();
109 }
else if (c ==
'"') {
111 h_.string(parse_string_chars_quotation_mark());
112 }
else if (c ==
'{' || c ==
'[') {
116 }
else if (c ==
'-' ||
117 (c >=
'0' && c <=
'9') ) {
121 throw json_exception(
"illegal value, expecting object, array, number, string, or literal true/false/null");
125 void parse_number() {
126 bool is_positive =
true;
128 std::stringstream ss;
129 char c = get_non_ws_char();
139 if (c < '0' || c >
'9')
140 throw json_exception(
"expecting int part of number");
144 bool leading_zero = (c ==
'0');
146 if (leading_zero && (c ==
'0'))
147 throw json_exception(
"zero padded numbers not allowed");
148 while (c >=
'0' && c <=
'9') {
154 bool is_integer =
true;
159 if (c < '0' || c >
'9')
160 throw json_exception(
"expected digit after decimal");
163 while (c >=
'0' && c <=
'9') {
170 if (c ==
'e' || c ==
'E') {
175 if (c ==
'+' || c ==
'-') {
180 if (c < '0' || c >
'9')
181 throw json_exception(
"expected digit after e/E");
182 while (c >=
'0' && c <=
'9') {
193 n = boost::lexical_cast<
unsigned long>(ss.str());
194 }
catch (
const boost::bad_lexical_cast & ) {
195 throw json_exception(
"number exceeds integer range");
198 h_.number_unsigned_long(n);
202 n = boost::lexical_cast<
unsigned long>(ss.str());
203 }
catch (
const boost::bad_lexical_cast & ) {
204 throw json_exception(
"number exceeds integer range");
212 x = boost::lexical_cast<
double>(ss.str());
213 }
catch (
const boost::bad_lexical_cast & ) {
214 throw json_exception(
"number exceeds double range");
221 std::string parse_string_chars_quotation_mark() {
227 }
else if (c ==
'\\') {
229 if (c ==
'\\' || c ==
'/' || c ==
'"') {
231 }
else if (c ==
'b') {
233 }
else if (c ==
'f') {
235 }
else if (c ==
'n') {
237 }
else if (c ==
'r') {
239 }
else if (c ==
't') {
241 }
else if (c ==
'u') {
242 get_escaped_unicode(s);
244 throw json_exception(
"expecting legal escape");
247 }
else if (c > 0 && c < 0x20) {
248 throw json_exception(
"found control character, "
249 "char values less than U+0020 must be \\u escaped");
255 void parse_true_literal() {
260 void parse_false_literal() {
265 void parse_null_literal() {
270 void get_escaped_unicode(std::stringstream& s) {
271 unsigned int codepoint = get_int_as_hex_chars();
272 if (!(is_high_surrogate(codepoint) || is_low_surrogate(codepoint))) {
273 putCodepoint(s,codepoint);
274 }
else if (!is_high_surrogate(codepoint)) {
275 throw json_exception(
"illegal unicode values, "
276 "found low-surrogate, missing high-surrogate");
280 throw json_exception(
"illegal unicode values, "
281 "found high-surrogate, expecting low-surrogate");
284 throw json_exception(
"illegal unicode values, "
285 "found high-surrogate, expecting low-surrogate");
286 unsigned int codepoint2 = get_int_as_hex_chars();
287 unsigned int supplemental
288 = ((codepoint - MIN_HIGH_SURROGATE) << 10)
289 + (codepoint2 - MIN_LOW_SURROGATE)
290 + MIN_SUPPLEMENTARY_CODE_POINT;
291 putCodepoint(s,supplemental);
295 unsigned int get_int_as_hex_chars() {
298 for (
int i=0; i<4; i++) {
300 if (! ((c >=
'a' && c<=
'f')
301 || (c >=
'A' && c<=
'F')
302 || (c >=
'0' && c<=
'9')))
303 throw json_exception(
"illegal unicode code point");
311 void putCodepoint(std::stringstream& s,
unsigned int codepoint){
312 if (codepoint <= 0x7f)
314 else if (codepoint <= 0x7ff) {
315 s.put(0xc0 | ((codepoint >> 6) & 0x1f));
316 s.put(0x80 | (codepoint & 0x3f));
317 }
else if (codepoint <= 0xffff) {
318 s.put(0xe0 | ((codepoint >> 12) & 0x0f));
319 s.put(0x80 | ((codepoint >> 6) & 0x3f));
320 s.put(0x80 | (codepoint & 0x3f));
322 s.put(0xf0 | ((codepoint >> 18) & 0x07));
323 s.put(0x80 | ((codepoint >> 12) & 0x3f));
324 s.put(0x80 | ((codepoint >> 6) & 0x3f));
325 s.put(0x80 | (codepoint & 0x3f));
329 void get_chars(
const std::string& s) {
330 for (
size_t i = 0; i < s.size(); ++i) {
333 throw json_exception(
"expecting rest of literal: "
338 void parse_array_values_end_array() {
339 char c = get_non_ws_char();
340 if (c ==
']')
return;
344 char c = get_non_ws_char();
345 if (c ==
']')
return;
347 throw json_exception(
"in array, expecting ] or ,");
349 c = get_non_ws_char();
351 throw json_exception(
"in array, expecting value");
356 void parse_object_members_end_object() {
357 char c = get_non_ws_char();
358 if (c ==
'}')
return;
362 throw json_exception(
"expecting member key"
363 " or end of object marker (})");
364 std::string key = parse_string_chars_quotation_mark();
367 c = get_non_ws_char();
369 throw json_exception(
"expecting key-value separator :");
374 c = get_non_ws_char();
378 throw json_exception(
"expecting end of object } or separator ,");
379 c = get_non_ws_char();
386 throw json_exception(
"unexpected end of stream");
396 char get_non_ws_char() {
399 if (is_whitespace(c))
continue;
428 template <
bool Val
idate_UTF_8,
typename Handler>
431 parser<Handler,Validate_UTF_8>(handler,in).
parse();
444 template <
typename Handler>
447 parse<false>(in,handler);
void parse(std::istream &in, Handler &handler)
Parse the JSON text represented by the specified input stream, sending events to the specified handle...