@@ -140,13 +140,14 @@ class JSON_Parser
140
140
141
141
JsonParseStatus GetNextToken (Token &);
142
142
143
- web::json::value ParseValue (typename JSON_Parser<CharType>::Token &first)
143
+ web::json::value ParseValue (typename JSON_Parser<CharType>::Token &first, JsonParseStatus& parseStatus )
144
144
{
145
145
#ifndef _MS_WINDOWS
146
146
utility::details::scoped_c_thread_locale locale;
147
147
#endif
148
148
149
- auto _value = _ParseValue (first);
149
+ auto _value = _ParseValue (first, parseStatus);
150
+ if (!parseStatus.didSucceed ) return web::json::value ();
150
151
#ifdef ENABLE_JSON_VALUE_VISUALIZER
151
152
auto type = _value->type ();
152
153
#endif
@@ -172,9 +173,9 @@ class JSON_Parser
172
173
bool CompleteKeywordTrue (Token &token);
173
174
bool CompleteKeywordFalse (Token &token);
174
175
bool CompleteKeywordNull (Token &token);
175
- std::unique_ptr<web::json::details::_Value> _ParseValue (typename JSON_Parser<CharType>::Token &first);
176
- std::unique_ptr<web::json::details::_Object> _ParseObject (typename JSON_Parser<CharType>::Token &tkn);
177
- std::unique_ptr<web::json::details::_Array> _ParseArray (typename JSON_Parser<CharType>::Token &tkn);
176
+ std::unique_ptr<web::json::details::_Value> _ParseValue (typename JSON_Parser<CharType>::Token &first, JsonParseStatus& parseStatus );
177
+ std::unique_ptr<web::json::details::_Object> _ParseObject (typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus );
178
+ std::unique_ptr<web::json::details::_Array> _ParseArray (typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus );
178
179
179
180
JSON_Parser& operator =(const JSON_Parser&);
180
181
@@ -1014,12 +1015,12 @@ JsonParseStatus JSON_Parser<CharType>::GetNextToken(typename JSON_Parser<CharTyp
1014
1015
}
1015
1016
1016
1017
template <typename CharType>
1017
- std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn)
1018
+ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus )
1018
1019
{
1019
- JsonParseStatus parseAttempt = GetNextToken (tkn);
1020
- if (!parseAttempt .didSucceed )
1020
+ parseStatus = GetNextToken (tkn);
1021
+ if (!parseStatus .didSucceed )
1021
1022
{
1022
- CreateError (tkn, parseAttempt. errorMsg ) ;
1023
+ return nullptr ;
1023
1024
}
1024
1025
1025
1026
auto obj = utility::details::make_unique<web::json::details::_Object>(g_keep_json_object_unsorted);
@@ -1042,18 +1043,20 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1042
1043
goto error;
1043
1044
}
1044
1045
1045
- parseAttempt = GetNextToken (tkn);
1046
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1046
+ parseStatus = GetNextToken (tkn);
1047
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1047
1048
1048
1049
// State 2: Looking for a colon.
1049
1050
1050
1051
if ( tkn.kind != JSON_Parser<CharType>::Token::TKN_Colon ) goto done;
1051
1052
1052
- parseAttempt = GetNextToken (tkn);
1053
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1053
+ parseStatus = GetNextToken (tkn);
1054
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1054
1055
// State 3: Looking for an expression.
1055
1056
#ifdef ENABLE_JSON_VALUE_VISUALIZER
1056
- auto fieldValue = _ParseValue (tkn);
1057
+ auto fieldValue = _ParseValue (tkn, parseStatus);
1058
+
1059
+ if (!parseStatus.didSucceed ) goto getNextTokenError;
1057
1060
auto type = fieldValue->type ();
1058
1061
1059
1062
elems.emplace_back (utility::conversions::to_string_t (std::move (fieldName)), json::value (std::move (fieldValue), type));
@@ -1066,8 +1069,8 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1066
1069
switch (tkn.kind )
1067
1070
{
1068
1071
case JSON_Parser<CharType>::Token::TKN_Comma:
1069
- parseAttempt = GetNextToken (tkn);
1070
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1072
+ parseStatus = GetNextToken (tkn);
1073
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1071
1074
break ;
1072
1075
case JSON_Parser<CharType>::Token::TKN_CloseBrace:
1073
1076
goto done;
@@ -1080,7 +1083,7 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1080
1083
done:
1081
1084
1082
1085
GetNextToken (tkn);
1083
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1086
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1084
1087
1085
1088
if (!g_keep_json_object_unsorted) {
1086
1089
::std::sort (elems.begin(), elems.end(), json::object::compare_pairs);
@@ -1089,15 +1092,15 @@ std::unique_ptr<web::json::details::_Object> JSON_Parser<CharType>::_ParseObject
1089
1092
return obj;
1090
1093
1091
1094
error:
1092
-
1093
- CreateError (tkn, _XPLATSTR ( " Malformed object literal " )) ;
1095
+ parseStatus. errorMsg = _XPLATSTR ( " Malformed object literal " );
1096
+ return nullptr ;
1094
1097
1095
1098
getNextTokenError:
1096
- CreateError (tkn, parseAttempt. errorMsg ) ;
1099
+ return nullptr ;
1097
1100
}
1098
1101
1099
1102
template <typename CharType>
1100
- std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn)
1103
+ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus )
1101
1104
{
1102
1105
JsonParseStatus parseAttempt = GetNextToken (tkn);
1103
1106
if (!parseAttempt.didSucceed )
@@ -1112,7 +1115,10 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
1112
1115
while ( true )
1113
1116
{
1114
1117
// State 1: Looking for an expression.
1115
- result->m_array .m_elements .emplace_back (ParseValue (tkn));
1118
+ auto value = ParseValue (tkn, parseStatus);
1119
+ if (!parseAttempt.didSucceed ) goto getNextTokenError;
1120
+
1121
+ result->m_array .m_elements .emplace_back (value);
1116
1122
1117
1123
// State 4: Looking for a comma or a closing bracket
1118
1124
switch (tkn.kind )
@@ -1142,27 +1148,25 @@ std::unique_ptr<web::json::details::_Array> JSON_Parser<CharType>::_ParseArray(t
1142
1148
}
1143
1149
1144
1150
template <typename CharType>
1145
- std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(typename JSON_Parser<CharType>::Token &tkn)
1151
+ std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(typename JSON_Parser<CharType>::Token &tkn, JsonParseStatus& parseStatus )
1146
1152
{
1147
- JsonParseStatus parseAttempt;
1148
1153
switch (tkn.kind )
1149
1154
{
1150
1155
case JSON_Parser<CharType>::Token::TKN_OpenBrace:
1151
1156
{
1152
- return _ParseObject (tkn);
1157
+ return _ParseObject (tkn, parseStatus );
1153
1158
}
1154
1159
case JSON_Parser<CharType>::Token::TKN_OpenBracket:
1155
1160
{
1156
- return _ParseArray (tkn);
1161
+ return _ParseArray (tkn, parseStatus );
1157
1162
}
1158
1163
case JSON_Parser<CharType>::Token::TKN_StringLiteral:
1159
1164
{
1160
1165
auto value = utility::details::make_unique<web::json::details::_String>(std::move (tkn.string_val ), tkn.has_unescape_symbol );
1161
- parseAttempt = GetNextToken (tkn);
1162
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1166
+ parseStatus = GetNextToken (tkn);
1167
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1163
1168
return std::move (value);
1164
1169
}
1165
-
1166
1170
case JSON_Parser<CharType>::Token::TKN_IntegerLiteral:
1167
1171
{
1168
1172
std::unique_ptr<web::json::details::_Number> value;
@@ -1171,42 +1175,40 @@ std::unique_ptr<web::json::details::_Value> JSON_Parser<CharType>::_ParseValue(t
1171
1175
else
1172
1176
value = utility::details::make_unique<web::json::details::_Number>(tkn.uint64_val );
1173
1177
1174
- parseAttempt = GetNextToken (tkn);
1175
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1178
+ parseStatus = GetNextToken (tkn);
1179
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1176
1180
return std::move (value);
1177
1181
}
1178
-
1179
1182
case JSON_Parser<CharType>::Token::TKN_NumberLiteral:
1180
1183
{
1181
1184
auto value = utility::details::make_unique<web::json::details::_Number>(tkn.double_val );
1182
- parseAttempt = GetNextToken (tkn);
1183
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1185
+ parseStatus = GetNextToken (tkn);
1186
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1184
1187
return std::move (value);
1185
1188
}
1186
1189
case JSON_Parser<CharType>::Token::TKN_BooleanLiteral:
1187
1190
{
1188
1191
auto value = utility::details::make_unique<web::json::details::_Boolean>(tkn.boolean_val );
1189
- parseAttempt = GetNextToken (tkn);
1190
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1192
+ parseStatus = GetNextToken (tkn);
1193
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1191
1194
return std::move (value);
1192
1195
}
1193
1196
case JSON_Parser<CharType>::Token::TKN_NullLiteral:
1194
1197
{
1195
- parseAttempt = GetNextToken (tkn);
1196
- if (!parseAttempt .didSucceed ) goto getNextTokenError;
1198
+ parseStatus = GetNextToken (tkn);
1199
+ if (!parseStatus .didSucceed ) goto getNextTokenError;
1197
1200
return utility::details::make_unique<web::json::details::_Null>();
1198
1201
}
1199
-
1200
1202
default :
1201
1203
{
1202
- parseAttempt .didSucceed = false ;
1203
- parseAttempt .errorMsg = _XPLATSTR (" Unexpected token" );
1204
+ parseStatus .didSucceed = false ;
1205
+ parseStatus .errorMsg = _XPLATSTR (" Unexpected token" );
1204
1206
goto getNextTokenError;
1205
1207
}
1206
1208
}
1207
1209
1208
1210
getNextTokenError:
1209
- CreateError (tkn, parseAttempt. errorMsg ) ;
1211
+ return nullptr ;
1210
1212
}
1211
1213
1212
1214
}}}
@@ -1216,9 +1218,20 @@ static web::json::value _parse_stream(utility::istream_t &stream)
1216
1218
web::json::details::JSON_StreamParser<utility::char_t > parser (stream);
1217
1219
1218
1220
web::json::details::JSON_Parser<utility::char_t >::Token tkn;
1219
- parser.GetNextToken (tkn);
1221
+ auto parseStatus = parser.GetNextToken (tkn);
1222
+
1223
+ if (!parseStatus.didSucceed )
1224
+ {
1225
+ web::json::details::CreateError (tkn, parseStatus.errorMsg );
1226
+ }
1227
+
1228
+ auto value = parser.ParseValue (tkn, parseStatus);
1229
+
1230
+ if (!parseStatus.didSucceed )
1231
+ {
1232
+ web::json::details::CreateError (tkn, parseStatus.errorMsg );
1233
+ }
1220
1234
1221
- auto value = parser.ParseValue (tkn);
1222
1235
if ( tkn.kind != web::json::details::JSON_Parser<utility::char_t >::Token::TKN_EOF )
1223
1236
{
1224
1237
web::json::details::CreateError (tkn, _XPLATSTR (" Left-over characters in stream after parsing a JSON value" ));
@@ -1232,9 +1245,19 @@ static web::json::value _parse_narrow_stream(std::istream &stream)
1232
1245
web::json::details::JSON_StreamParser<char > parser (stream);
1233
1246
1234
1247
web::json::details::JSON_StreamParser<char >::Token tkn;
1235
- parser.GetNextToken (tkn);
1248
+ auto parseStatus = parser.GetNextToken (tkn);
1236
1249
1237
- auto value = parser.ParseValue (tkn);
1250
+ if (!parseStatus.didSucceed )
1251
+ {
1252
+ web::json::details::CreateError (tkn, parseStatus.errorMsg );
1253
+ }
1254
+
1255
+ auto value = parser.ParseValue (tkn, parseStatus);
1256
+
1257
+ if (!parseStatus.didSucceed )
1258
+ {
1259
+ web::json::details::CreateError (tkn, parseStatus.errorMsg );
1260
+ }
1238
1261
1239
1262
if ( tkn.kind != web::json::details::JSON_Parser<char >::Token::TKN_EOF )
1240
1263
{
@@ -1249,14 +1272,19 @@ web::json::value web::json::value::parse(const utility::string_t& str)
1249
1272
web::json::details::JSON_StringParser<utility::char_t > parser (str);
1250
1273
1251
1274
web::json::details::JSON_Parser<utility::char_t >::Token tkn;
1252
- auto parseAttempt = parser.GetNextToken (tkn);
1275
+ auto parseStatus = parser.GetNextToken (tkn);
1253
1276
1254
- if (!parseAttempt .didSucceed )
1277
+ if (!parseStatus .didSucceed )
1255
1278
{
1256
- web::json::details::CreateError (tkn, parseAttempt .errorMsg );
1279
+ web::json::details::CreateError (tkn, parseStatus .errorMsg );
1257
1280
}
1258
1281
1259
- auto value = parser.ParseValue (tkn);
1282
+ auto value = parser.ParseValue (tkn, parseStatus);
1283
+
1284
+ if (!parseStatus.didSucceed )
1285
+ {
1286
+ web::json::details::CreateError (tkn, parseStatus.errorMsg );
1287
+ }
1260
1288
1261
1289
if (tkn.kind != web::json::details::JSON_Parser<utility::char_t >::Token::TKN_EOF)
1262
1290
{
@@ -1275,7 +1303,7 @@ web::json::value web::json::value::parse(const utility::string_t& str, std::erro
1275
1303
1276
1304
if (parseAttempt.didSucceed )
1277
1305
{
1278
- returnObject = parser.ParseValue (tkn);
1306
+ returnObject = parser.ParseValue (tkn, parseAttempt );
1279
1307
}
1280
1308
else
1281
1309
{
0 commit comments