20 #include <daw/daw_attributes.h>
21 #include <daw/daw_bit_cast.h>
22 #include <daw/daw_is_any_of.h>
23 #include <daw/daw_likely.h>
24 #include <daw/daw_unreachable.h>
26 #if defined( DAW_CX_BIT_CAST )
34 namespace json_details {
38 template<
typename ParseState>
39 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static inline constexpr ParseState
40 skip_string_nq( ParseState &parse_state ) {
41 auto result = parse_state;
43 string_quote::string_quote_parser::parse_nq( parse_state );
46 ErrorReason::InvalidString, parse_state );
47 result.last = parse_state.first;
48 parse_state.remove_prefix( );
55 template<
bool KeepQuotes = false,
typename ParseState>
56 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static inline constexpr ParseState
57 skip_string( ParseState &parse_state ) {
58 if( parse_state.empty( ) ) {
62 ErrorReason::InvalidString, parse_state );
63 parse_state.remove_prefix( );
66 ErrorReason::InvalidString, parse_state );
67 auto result = skip_string_nq( parse_state );
68 if constexpr( KeepQuotes ) {
75 template<
typename ParseState>
76 [[nodiscard]]
static inline constexpr ParseState
77 skip_true( ParseState &parse_state ) {
78 auto result = parse_state;
80 ParseState::is_unchecked_input ) ) {
81 parse_state.remove_prefix( 4 );
83 parse_state.remove_prefix( );
85 ErrorReason::InvalidTrue, parse_state );
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, parse_state );
93 result.counter =
static_cast<bool>( true );
97 template<
typename ParseState>
98 [[nodiscard]]
static inline constexpr ParseState
99 skip_false( ParseState &parse_state ) {
100 auto result = parse_state;
102 ParseState::is_unchecked_input ) ) {
103 parse_state.remove_prefix( 5 );
105 parse_state.remove_prefix( );
107 ErrorReason::InvalidFalse, parse_state );
108 parse_state.remove_prefix( 4 );
110 result.last = parse_state.first;
111 parse_state.trim_left( );
113 parse_state.is_at_token_after_value( ),
114 ErrorReason::InvalidEndOfValue, parse_state );
115 result.counter =
static_cast<bool>( false );
119 template<
typename ParseState>
120 [[nodiscard]]
static inline constexpr ParseState
121 skip_null( ParseState &parse_state ) {
123 ParseState::is_unchecked_input ) ) {
124 parse_state.remove_prefix( 4 );
126 parse_state.remove_prefix( );
128 ErrorReason::InvalidNull, parse_state );
129 parse_state.remove_prefix( 3 );
132 ErrorReason::UnexpectedEndOfData, parse_state );
133 parse_state.trim_left( );
135 parse_state.is_at_token_after_value( ),
136 ErrorReason::UnexpectedEndOfData, parse_state );
137 auto result = parse_state;
138 result.first =
nullptr;
139 result.last =
nullptr;
143 template<
bool skip_end_check,
typename CharT>
144 DAW_ATTRIB_NONNULL( )
145 DAW_ATTRIB_RET_NONNULL DAW_ATTRIB_FLATINLINE
146 [[nodiscard]]
static inline constexpr CharT *skip_digits(
147 CharT *first, CharT *
const last ) {
149 unsigned dig = parse_digit( *first );
152 if constexpr( not skip_end_check ) {
153 if( DAW_UNLIKELY( first >= last ) ) {
157 dig = parse_digit( *first );
167 #if false and defined( DAW_CX_BIT_CAST )
169 ParseState::is_unchecked_input or
173 [[nodiscard]]
static constexpr ParseState
174 skip_number( ParseState &parse_state ) {
175 using CharT =
typename ParseState::CharT;
177 auto result = parse_state;
178 CharT *first = parse_state.first;
179 CharT *
const last = parse_state.last;
181 if( *first ==
'-' ) {
185 first = count_digits( first, last );
187 CharT *decimal =
nullptr;
188 if( *first ==
'.' ) {
190 first = count_digits( first, last );
193 CharT *exp =
nullptr;
194 char const maybe_e = *first;
195 if( ( maybe_e ==
'e' ) | ( maybe_e ==
'E' ) ) {
197 char const maybe_sign = *first;
198 if( ( maybe_sign ==
'+' ) | ( maybe_sign ==
'-' ) ) {
201 first = count_digits( first, last );
206 parse_state.first = first;
208 result.class_first = decimal;
209 result.class_last = exp;
214 not( ParseState::is_unchecked_input or
219 template<
typename ParseState>
221 [[nodiscard]]
static constexpr ParseState
222 skip_number( ParseState &parse_state ) {
223 using CharT =
typename ParseState::CharT;
225 ErrorReason::UnexpectedEndOfData, parse_state );
227 auto result = parse_state;
228 CharT *first = parse_state.first;
229 CharT *
const last = parse_state.last;
230 if constexpr( ParseState::allow_leading_zero_plus ) {
231 if( *first ==
'-' ) {
242 if( last - first > 1 ) {
245 ErrorReason::InvalidNumberStart, parse_state );
251 if( DAW_LIKELY( first < last ) ) {
255 ParseState::is_unchecked_input )>( first, last );
258 CharT *decimal =
nullptr;
260 ParseState::is_unchecked_input ) or
262 ( *first ==
'.' ) ) {
265 if( DAW_LIKELY( first < last ) ) {
269 ParseState::is_unchecked_input )>( first, last );
272 CharT *exp =
nullptr;
276 return parse_digit( *first );
281 if( ( dig == parsed_constants::e_char ) |
282 ( dig == parsed_constants::E_char ) ) {
287 auto r = parse_state;
291 dig = parse_digit( *first );
292 if( ( dig == parsed_constants::plus_char ) |
293 ( dig == parsed_constants::minus_char ) ) {
297 ErrorReason::InvalidNumber );
299 if( DAW_LIKELY( first < last ) ) {
303 ParseState::is_unchecked_input )>( first, last );
307 parse_state.first = first;
309 result.class_first = decimal;
310 result.class_last = exp;
320 template<
bool KeepInitialQuote = false,
typename ParseState>
321 [[nodiscard]] DAW_ATTRIB_NOINLINE constexpr ParseState
322 skip_value( ParseState &parse_state ) {
324 ErrorReason::UnexpectedEndOfData, parse_state );
327 parse_state.counter = 0;
328 switch( parse_state.front( ) ) {
330 return skip_string<KeepInitialQuote>( parse_state );
332 return parse_state.skip_array( );
334 return parse_state.skip_class( );
336 return skip_true( parse_state );
338 return skip_false( parse_state );
340 return skip_null( parse_state );
352 return skip_number( parse_state );
355 if constexpr( ParseState::is_unchecked_input ) {
356 if( DAW_UNLIKELY( parse_state.front( ) ==
'\0' ) ) {
369 template<
typename JsonMember,
typename ParseState>
370 [[nodiscard]] DAW_ATTRIB_FLATINLINE
static inline constexpr ParseState
371 skip_known_value( ParseState &parse_state ) {
373 ErrorReason::UnexpectedEndOfData, parse_state );
374 if constexpr( JsonMember::expected_type == JsonParseTypes::Date or
375 JsonMember::expected_type == JsonParseTypes::StringRaw or
376 JsonMember::expected_type ==
377 JsonParseTypes::StringEscaped or
378 JsonMember::expected_type == JsonParseTypes::Custom ) {
381 ErrorReason::InvalidString, parse_state );
382 parse_state.remove_prefix( );
383 return json_details::skip_string_nq( parse_state );
384 }
else if constexpr( daw::is_any_of_v<
385 JsonMember::expected_type, JsonParseTypes::Real,
386 JsonParseTypes::Signed, JsonParseTypes::Unsigned,
387 JsonParseTypes::Bool, JsonParseTypes::Null> ) {
389 return skip_number( parse_state );
390 }
else if constexpr( JsonMember::expected_type ==
391 JsonParseTypes::Array ) {
393 ErrorReason::InvalidArrayStart, parse_state );
394 return parse_state.skip_array( );
395 }
else if constexpr( JsonMember::expected_type ==
396 JsonParseTypes::Class ) {
398 ErrorReason::InvalidClassStart, parse_state );
399 return parse_state.skip_class( );
401 return skip_value( parse_state );
405 template<
typename ParseState>
406 [[nodiscard]]
static inline constexpr ParseState
407 skip_literal( ParseState &parse_state ) {
409 ErrorReason::UnexpectedEndOfData, parse_state );
412 parse_state.counter = 0;
413 switch( parse_state.front( ) ) {
415 return skip_true( parse_state );
417 return skip_false( parse_state );
419 return skip_null( parse_state );
431 return skip_number( parse_state );
435 if constexpr( ParseState::is_unchecked_input ) {
#define daw_json_assert_weak(Bool,...)
Assert that Bool is true when in Checked Input mode If false pass rest of args to daw_json_error.
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
#define DAW_JSON_ENABLEIF(...)
DAW_ATTRIB_NOINLINE void daw_json_error(ErrorReason reason)
constexpr bool is_number(char c)
std::bool_constant< is_zero_terminated_string_v< T > > is_zero_terminated_string
Customization point traits.
DAW_JSON_REQUIRES(boost::describe::has_describe_members< T >::value and use_boost_describe_v< T >) struct json_data_contract< T >
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.