32 namespace json_details {
36 template<
typename ParseState>
37 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
38 skip_string_nq( ParseState &parse_state ) {
39 auto result = parse_state;
41 string_quote::string_quote_parser::parse_nq( parse_state );
44 ErrorReason::InvalidString,
46 result.last = parse_state.first;
47 parse_state.remove_prefix( );
54 template<
bool KeepQuotes = false,
typename ParseState>
55 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
56 skip_string( ParseState &parse_state ) {
57 if( parse_state.empty( ) ) {
61 ErrorReason::InvalidString,
63 parse_state.remove_prefix( );
66 parse_state.has_more( ), ErrorReason::InvalidString, parse_state );
67 auto result = skip_string_nq( parse_state );
68 if constexpr( KeepQuotes ) {
75 template<
typename ParseState>
76 [[nodiscard]]
static constexpr ParseState
77 skip_true( ParseState &parse_state ) {
78 auto result = parse_state;
79 if constexpr( ParseState::is_unchecked_input ) {
80 parse_state.remove_prefix( 4 );
82 parse_state.remove_prefix( );
84 ErrorReason::InvalidTrue,
86 parse_state.remove_prefix( 3 );
88 result.last = parse_state.first;
89 parse_state.trim_left( );
91 parse_state.is_at_token_after_value( ),
92 ErrorReason::InvalidEndOfValue,
94 result.counter =
static_cast<bool>( true );
98 template<
typename ParseState>
99 [[nodiscard]]
static constexpr ParseState
100 skip_false( ParseState &parse_state ) {
101 auto result = parse_state;
102 if constexpr( ParseState::is_unchecked_input ) {
103 parse_state.remove_prefix( 5 );
105 parse_state.remove_prefix( );
107 ErrorReason::InvalidFalse,
109 parse_state.remove_prefix( 4 );
111 result.last = parse_state.first;
112 parse_state.trim_left( );
114 parse_state.is_at_token_after_value( ),
115 ErrorReason::InvalidEndOfValue,
117 result.counter =
static_cast<bool>( false );
121 template<
typename ParseState>
122 [[nodiscard]]
static constexpr ParseState
123 skip_null( ParseState &parse_state ) {
124 if constexpr( ParseState::is_unchecked_input ) {
125 parse_state.remove_prefix( 4 );
127 parse_state.remove_prefix( );
129 ErrorReason::InvalidNull,
131 parse_state.remove_prefix( 3 );
134 ErrorReason::UnexpectedEndOfData,
136 parse_state.trim_left( );
138 parse_state.is_at_token_after_value( ),
139 ErrorReason::UnexpectedEndOfData,
141 auto result = parse_state;
142 result.first =
nullptr;
143 result.last =
nullptr;
147 template<
bool skip_end_check,
typename iterator>
148 DAW_ATTRIB_FLATINLINE [[nodiscard]]
constexpr daw::not_null<iterator>
149 skip_digits( daw::not_null<iterator> first,
150 daw::not_null<iterator>
const last ) {
152 unsigned dig = parse_digit( *first );
155 if constexpr( not skip_end_check ) {
156 if( DAW_UNLIKELY( first >= last ) ) {
160 dig = parse_digit( *first );
168 template<
typename ParseState>
169 [[nodiscard]]
static constexpr ParseState
170 skip_number( ParseState &parse_state ) {
172 ErrorReason::UnexpectedEndOfData,
175 auto result = parse_state;
176 daw::not_null<char const *> first = parse_state.first;
177 daw::not_null<char const *>
const last = parse_state.last;
178 if constexpr( ParseState::allow_leading_zero_plus ) {
179 if( *first ==
'-' ) {
189 true, ErrorReason::InvalidNumberStart, parse_state );
191 if( last - first > 1 ) {
193 not parse_policy_details::is_number( *std::next( first ) ),
194 ErrorReason::InvalidNumberStart,
201 if( DAW_LIKELY( first < last ) ) {
203 first = skip_digits<ParseState::is_unchecked_input>( first, last );
206 char const *decimal =
nullptr;
207 if( ( ( ParseState::is_zero_terminated_string or
208 ParseState::is_unchecked_input ) or
210 ( *first ==
'.' ) ) {
213 if( DAW_LIKELY( first < last ) ) {
216 skip_digits<( ParseState::is_zero_terminated_string or
217 ParseState::is_unchecked_input )>( first, last );
220 char const *exp =
nullptr;
223 if( ParseState::is_zero_terminated_string or first < last ) {
224 return parse_digit( *first );
229 if( ( dig == parsed_constants::e_char ) |
230 ( dig == parsed_constants::E_char ) ) {
234 first < last, ErrorReason::UnexpectedEndOfData, [&] {
235 auto r = parse_state;
236 r.first = input_pointer( r.first, first.get( ) );
239 dig = parse_digit( *first );
240 if( ( dig == parsed_constants::plus_char ) |
241 ( dig == parsed_constants::minus_char ) ) {
245 ErrorReason::InvalidNumber );
247 if( DAW_LIKELY( first < last ) ) {
250 skip_digits<( ParseState::is_zero_terminated_string or
251 ParseState::is_unchecked_input )>( first, last );
255 parse_state.first = input_pointer( parse_state.first, first.get( ) );
256 result.last = input_pointer( result.first, first.get( ) );
257 result.class_first = input_pointer( result.first, decimal );
258 result.class_last = input_pointer( result.first, exp );
268 template<
bool KeepInitialQuote = false,
typename ParseState>
269 [[nodiscard]] DAW_ATTRIB_NOINLINE
constexpr ParseState
270 skip_value( ParseState &parse_state ) {
272 ErrorReason::UnexpectedEndOfData,
276 parse_state.counter = 0;
277 switch( parse_state.front( ) ) {
279 return skip_string<KeepInitialQuote>( parse_state );
281 return parse_state.skip_array( );
283 return parse_state.skip_class( );
285 return skip_true( parse_state );
287 return skip_false( parse_state );
289 return skip_null( parse_state );
301 return skip_number( parse_state );
304 if constexpr( ParseState::is_unchecked_input ) {
305 if( DAW_UNLIKELY( parse_state.front( ) ==
'\0' ) ) {
307 true, ErrorReason::InvalidStartOfValue, parse_state );
311 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
319 template<
typename JsonMember,
typename ParseState>
320 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
321 skip_known_value( ParseState &parse_state ) {
323 ErrorReason::UnexpectedEndOfData,
325 if constexpr( JsonMember::expected_type == JsonParseTypes::Date or
326 JsonMember::expected_type == JsonParseTypes::StringRaw or
327 JsonMember::expected_type ==
328 JsonParseTypes::StringEscaped or
329 JsonMember::expected_type ==
330 JsonParseTypes::StringInsitu or
331 JsonMember::expected_type == JsonParseTypes::Custom ) {
334 ErrorReason::InvalidString,
336 parse_state.remove_prefix( );
337 return json_details::skip_string_nq( parse_state );
338 }
else if constexpr( daw::is_any_of_v<JsonMember::expected_type,
339 JsonParseTypes::Real,
340 JsonParseTypes::Signed,
341 JsonParseTypes::Unsigned,
342 JsonParseTypes::Bool,
343 JsonParseTypes::Null> ) {
345 return skip_number( parse_state );
346 }
else if constexpr( JsonMember::expected_type ==
347 JsonParseTypes::Array ) {
349 ErrorReason::InvalidArrayStart,
351 return parse_state.skip_array( );
352 }
else if constexpr( JsonMember::expected_type ==
353 JsonParseTypes::Class ) {
355 ErrorReason::InvalidClassStart,
357 return parse_state.skip_class( );
359 return skip_value( parse_state );
363 template<
typename ParseState>
364 [[nodiscard]]
static constexpr ParseState
365 skip_literal( ParseState &parse_state ) {
367 ErrorReason::UnexpectedEndOfData,
371 parse_state.counter = 0;
372 switch( parse_state.front( ) ) {
374 return skip_true( parse_state );
376 return skip_false( parse_state );
378 return skip_null( parse_state );
390 return skip_number( parse_state );
392 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
394 if constexpr( ParseState::is_unchecked_input ) {
397 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );