36 namespace json_details {
40 template<
typename ParseState>
41 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
42 skip_string_nq( ParseState &parse_state ) {
43 auto result = parse_state;
45 string_quote::string_quote_parser::parse_nq( parse_state );
48 ErrorReason::InvalidString,
50 result.last = parse_state.first;
51 parse_state.remove_prefix( );
58 template<
bool KeepQuotes = false,
typename ParseState>
59 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
60 skip_string( ParseState &parse_state ) {
61 if( parse_state.empty( ) ) {
65 ErrorReason::InvalidString,
67 parse_state.remove_prefix( );
70 parse_state.has_more( ), ErrorReason::InvalidString, parse_state );
71 auto result = skip_string_nq( parse_state );
72 if constexpr( KeepQuotes ) {
79 template<
typename ParseState>
80 [[nodiscard]]
static constexpr ParseState
81 skip_true( ParseState &parse_state ) {
82 auto result = parse_state;
83 if constexpr( ( ParseState::is_zero_terminated_string or
84 ParseState::is_unchecked_input ) ) {
85 parse_state.remove_prefix( 4 );
87 parse_state.remove_prefix( );
89 ErrorReason::InvalidTrue,
91 parse_state.remove_prefix( 3 );
93 result.last = parse_state.first;
94 parse_state.trim_left( );
96 parse_state.is_at_token_after_value( ),
97 ErrorReason::InvalidEndOfValue,
99 result.counter =
static_cast<bool>( true );
103 template<
typename ParseState>
104 [[nodiscard]]
static constexpr ParseState
105 skip_false( ParseState &parse_state ) {
106 auto result = parse_state;
107 if constexpr( ( ParseState::is_zero_terminated_string or
108 ParseState::is_unchecked_input ) ) {
109 parse_state.remove_prefix( 5 );
111 parse_state.remove_prefix( );
113 ErrorReason::InvalidFalse,
115 parse_state.remove_prefix( 4 );
117 result.last = parse_state.first;
118 parse_state.trim_left( );
120 parse_state.is_at_token_after_value( ),
121 ErrorReason::InvalidEndOfValue,
123 result.counter =
static_cast<bool>( false );
127 template<
typename ParseState>
128 [[nodiscard]]
static constexpr ParseState
129 skip_null( ParseState &parse_state ) {
130 if constexpr( ( ParseState::is_zero_terminated_string or
131 ParseState::is_unchecked_input ) ) {
132 parse_state.remove_prefix( 4 );
134 parse_state.remove_prefix( );
136 ErrorReason::InvalidNull,
138 parse_state.remove_prefix( 3 );
141 ErrorReason::UnexpectedEndOfData,
143 parse_state.trim_left( );
145 parse_state.is_at_token_after_value( ),
146 ErrorReason::UnexpectedEndOfData,
148 auto result = parse_state;
149 result.first =
nullptr;
150 result.last =
nullptr;
154 template<
bool skip_end_check,
typename iterator>
155 DAW_ATTRIB_FLATINLINE [[nodiscard]]
constexpr daw::not_null<iterator>
156 skip_digits( daw::not_null<iterator> first,
157 daw::not_null<iterator>
const last ) {
159 unsigned dig = parse_digit( *first );
162 if constexpr( not skip_end_check ) {
163 if( DAW_UNLIKELY( first >= last ) ) {
167 dig = parse_digit( *first );
175 template<
typename ParseState>
176 [[nodiscard]]
static constexpr ParseState
177 skip_number( ParseState &parse_state ) {
179 ErrorReason::UnexpectedEndOfData,
182 auto result = parse_state;
183 daw::not_null<char const *> first = parse_state.first;
184 daw::not_null<char const *>
const last = parse_state.last;
185 if constexpr( ParseState::allow_leading_zero_plus ) {
186 if( *first ==
'-' ) {
196 true, ErrorReason::InvalidNumberStart, parse_state );
198 if( last - first > 1 ) {
200 not parse_policy_details::is_number( *std::next( first ) ),
201 ErrorReason::InvalidNumberStart,
208 if( DAW_LIKELY( first < last ) ) {
211 skip_digits<( ParseState::is_zero_terminated_string or
212 ParseState::is_unchecked_input )>( first, last );
215 char const *decimal =
nullptr;
216 if( ( ( ParseState::is_zero_terminated_string or
217 ParseState::is_unchecked_input ) or
219 ( *first ==
'.' ) ) {
222 if( DAW_LIKELY( first < last ) ) {
225 skip_digits<( ParseState::is_zero_terminated_string or
226 ParseState::is_unchecked_input )>( first, last );
229 char const *exp =
nullptr;
232 if( ParseState::is_zero_terminated_string or first < last ) {
233 return parse_digit( *first );
238 if( ( dig == parsed_constants::e_char ) |
239 ( dig == parsed_constants::E_char ) ) {
243 first < last, ErrorReason::UnexpectedEndOfData, [&] {
244 auto r = parse_state;
245 r.first = input_pointer( r.first, first.get( ) );
248 dig = parse_digit( *first );
249 if( ( dig == parsed_constants::plus_char ) |
250 ( dig == parsed_constants::minus_char ) ) {
254 ErrorReason::InvalidNumber );
256 if( DAW_LIKELY( first < last ) ) {
259 skip_digits<( ParseState::is_zero_terminated_string or
260 ParseState::is_unchecked_input )>( first, last );
264 parse_state.first = input_pointer( parse_state.first, first.get( ) );
265 result.last = input_pointer( result.first, first.get( ) );
266 result.class_first = input_pointer( result.first, decimal );
267 result.class_last = input_pointer( result.first, exp );
277 template<
bool KeepInitialQuote = false,
typename ParseState>
278 [[nodiscard]] DAW_ATTRIB_NOINLINE
constexpr ParseState
279 skip_value( ParseState &parse_state ) {
281 ErrorReason::UnexpectedEndOfData,
285 parse_state.counter = 0;
286 switch( parse_state.front( ) ) {
288 return skip_string<KeepInitialQuote>( parse_state );
290 return parse_state.skip_array( );
292 return parse_state.skip_class( );
294 return skip_true( parse_state );
296 return skip_false( parse_state );
298 return skip_null( parse_state );
310 return skip_number( parse_state );
313 if constexpr( ParseState::is_unchecked_input ) {
314 if( DAW_UNLIKELY( parse_state.front( ) ==
'\0' ) ) {
316 true, ErrorReason::InvalidStartOfValue, parse_state );
320 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
328 template<
typename JsonMember,
typename ParseState>
329 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
330 skip_known_value( ParseState &parse_state ) {
332 ErrorReason::UnexpectedEndOfData,
334 if constexpr( JsonMember::expected_type == JsonParseTypes::Date or
335 JsonMember::expected_type == JsonParseTypes::StringRaw or
336 JsonMember::expected_type ==
337 JsonParseTypes::StringEscaped or
338 JsonMember::expected_type ==
339 JsonParseTypes::StringInsitu or
340 JsonMember::expected_type == JsonParseTypes::Custom ) {
343 ErrorReason::InvalidString,
345 parse_state.remove_prefix( );
346 return json_details::skip_string_nq( parse_state );
347 }
else if constexpr( daw::is_any_of_v<JsonMember::expected_type,
348 JsonParseTypes::Real,
349 JsonParseTypes::Signed,
350 JsonParseTypes::Unsigned,
351 JsonParseTypes::Bool,
352 JsonParseTypes::Null> ) {
354 return skip_number( parse_state );
355 }
else if constexpr( JsonMember::expected_type ==
356 JsonParseTypes::Array ) {
358 ErrorReason::InvalidArrayStart,
360 return parse_state.skip_array( );
361 }
else if constexpr( JsonMember::expected_type ==
362 JsonParseTypes::Class ) {
364 ErrorReason::InvalidClassStart,
366 return parse_state.skip_class( );
368 return skip_value( parse_state );
372 template<
typename ParseState>
373 [[nodiscard]]
static constexpr ParseState
374 skip_literal( ParseState &parse_state ) {
376 ErrorReason::UnexpectedEndOfData,
380 parse_state.counter = 0;
381 switch( parse_state.front( ) ) {
383 return skip_true( parse_state );
385 return skip_false( parse_state );
387 return skip_null( parse_state );
399 return skip_number( parse_state );
401 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );
403 if constexpr( ParseState::is_unchecked_input ) {
406 daw_json_error(
true, ErrorReason::InvalidStartOfValue, parse_state );