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>
155 DAW_ATTRIB_FLATINLINE [[nodiscard]]
constexpr daw::not_null<char const *>
156 skip_digits( daw::not_null<char const *> first,
157 daw::not_null<char const *>
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 );
177#if false and defined( DAW_CX_BIT_CAST )
178 template<
typename ParseState DAW_ENABLEIF(
179 ParseState::is_unchecked_input or
180 ParseState::is_zero_terminated_string )>
182 ParseState::is_zero_terminated_string )
183 [[nodiscard]]
static constexpr ParseState
184 skip_number( ParseState &parse_state ) {
186 auto result = parse_state;
187 char const *first = parse_state.first;
188 char const *
const last = parse_state.last;
190 if( *first ==
'-' ) {
194 first = count_digits( first, last );
196 char const *decimal =
nullptr;
197 if( *first ==
'.' ) {
199 first = count_digits( first, last );
202 char const *exp =
nullptr;
203 char const maybe_e = *first;
204 if( ( maybe_e ==
'e' ) | ( maybe_e ==
'E' ) ) {
206 char const maybe_sign = *first;
207 if( ( maybe_sign ==
'+' ) | ( maybe_sign ==
'-' ) ) {
210 first = count_digits( first, last );
215 parse_state.first = first;
217 result.class_first = decimal;
218 result.class_last = exp;
222 template<
typename ParseState DAW_ENABLEIF(
223 not( ParseState::is_unchecked_input or
224 ParseState::is_zero_terminated_string ) )>
226 ParseState::is_zero_terminated_string ) )
228 template<
typename ParseState>
230 [[nodiscard]]
static constexpr ParseState
231 skip_number( ParseState &parse_state ) {
233 ErrorReason::UnexpectedEndOfData,
236 auto result = parse_state;
237 daw::not_null<char const *> first = parse_state.first;
238 daw::not_null<char const *>
const last = parse_state.last;
239 if constexpr( ParseState::allow_leading_zero_plus ) {
240 if( *first ==
'-' ) {
251 if( last - first > 1 ) {
253 not parse_policy_details::is_number( *std::next( first ) ),
254 ErrorReason::InvalidNumberStart,
261 if( DAW_LIKELY( first < last ) ) {
264 skip_digits<( ParseState::is_zero_terminated_string or
265 ParseState::is_unchecked_input )>( first, last );
268 char const *decimal =
nullptr;
269 if( ( ( ParseState::is_zero_terminated_string or
270 ParseState::is_unchecked_input ) or
272 ( *first ==
'.' ) ) {
275 if( DAW_LIKELY( first < last ) ) {
278 skip_digits<( ParseState::is_zero_terminated_string or
279 ParseState::is_unchecked_input )>( first, last );
282 char const *exp =
nullptr;
285 if( ParseState::is_zero_terminated_string or first < last ) {
286 return parse_digit( *first );
291 if( ( dig == parsed_constants::e_char ) |
292 ( dig == parsed_constants::E_char ) ) {
296 first < last, ErrorReason::UnexpectedEndOfData, [&] {
297 auto r = parse_state;
301 dig = parse_digit( *first );
302 if( ( dig == parsed_constants::plus_char ) |
303 ( dig == parsed_constants::minus_char ) ) {
307 ErrorReason::InvalidNumber );
309 if( DAW_LIKELY( first < last ) ) {
312 skip_digits<( ParseState::is_zero_terminated_string or
313 ParseState::is_unchecked_input )>( first, last );
317 parse_state.first = first;
319 result.class_first = decimal;
320 result.class_last = exp;
330 template<
bool KeepInitialQuote = false,
typename ParseState>
331 [[nodiscard]] DAW_ATTRIB_NOINLINE
constexpr ParseState
332 skip_value( ParseState &parse_state ) {
334 ErrorReason::UnexpectedEndOfData,
338 parse_state.counter = 0;
339 switch( parse_state.front( ) ) {
341 return skip_string<KeepInitialQuote>( parse_state );
343 return parse_state.skip_array( );
345 return parse_state.skip_class( );
347 return skip_true( parse_state );
349 return skip_false( parse_state );
351 return skip_null( parse_state );
363 return skip_number( parse_state );
366 if constexpr( ParseState::is_unchecked_input ) {
367 if( DAW_UNLIKELY( parse_state.front( ) ==
'\0' ) ) {
380 template<
typename JsonMember,
typename ParseState>
381 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static constexpr ParseState
382 skip_known_value( ParseState &parse_state ) {
384 ErrorReason::UnexpectedEndOfData,
386 if constexpr( JsonMember::expected_type == JsonParseTypes::Date or
387 JsonMember::expected_type == JsonParseTypes::StringRaw or
388 JsonMember::expected_type ==
389 JsonParseTypes::StringEscaped or
390 JsonMember::expected_type == JsonParseTypes::Custom ) {
393 ErrorReason::InvalidString,
395 parse_state.remove_prefix( );
396 return json_details::skip_string_nq( parse_state );
397 }
else if constexpr( daw::is_any_of_v<JsonMember::expected_type,
398 JsonParseTypes::Real,
399 JsonParseTypes::Signed,
400 JsonParseTypes::Unsigned,
401 JsonParseTypes::Bool,
402 JsonParseTypes::Null> ) {
404 return skip_number( parse_state );
405 }
else if constexpr( JsonMember::expected_type ==
406 JsonParseTypes::Array ) {
408 ErrorReason::InvalidArrayStart,
410 return parse_state.skip_array( );
411 }
else if constexpr( JsonMember::expected_type ==
412 JsonParseTypes::Class ) {
414 ErrorReason::InvalidClassStart,
416 return parse_state.skip_class( );
418 return skip_value( parse_state );
422 template<
typename ParseState>
423 [[nodiscard]]
static constexpr ParseState
424 skip_literal( ParseState &parse_state ) {
426 ErrorReason::UnexpectedEndOfData,
430 parse_state.counter = 0;
431 switch( parse_state.front( ) ) {
433 return skip_true( parse_state );
435 return skip_false( parse_state );
437 return skip_null( parse_state );
449 return skip_number( parse_state );
453 if constexpr( ParseState::is_unchecked_input ) {