17 #include <daw/daw_likely.h>
21 #include <type_traits>
25 namespace json_details {
26 [[nodiscard]]
inline constexpr UInt8
to_nibble(
unsigned char chr ) {
27 int const b =
static_cast<int>( chr );
28 int const maskLetter = ( (
'9' - b ) >> 31 );
29 int const maskSmall = ( (
'Z' - b ) >> 31 );
30 int const offset =
'0' + ( maskLetter & int(
'A' -
'0' - 10 ) ) +
31 ( maskSmall &
int(
'a' -
'A' ) );
32 auto const result =
static_cast<unsigned>( b - offset );
33 return to_uint8( result );
36 template<
bool is_unchecked_input>
37 [[nodiscard]]
inline constexpr UInt16
39 auto const n0 =
to_nibble(
static_cast<unsigned char>( *first++ ) );
40 auto const n1 =
to_nibble(
static_cast<unsigned char>( *first++ ) );
41 if constexpr( is_unchecked_input ) {
44 return to_uint16( ( n0 << 4U ) | n1 );
47 constexpr
char u32toC( UInt32 value ) {
48 return static_cast<char>(
static_cast<unsigned char>( value ) );
51 template<
typename ParseState>
52 [[nodiscard]]
static constexpr
char *
54 constexpr
bool is_unchecked_input = ParseState::is_unchecked_input;
57 UInt32 cp = to_uint32( byte_from_nibbles<is_unchecked_input>( first ) )
59 cp |= byte_from_nibbles<is_unchecked_input>( first );
61 *
it++ =
static_cast<char>(
static_cast<unsigned char>( cp ) );
67 if( 0xD800U <= cp and cp <= 0xDBFFU ) {
68 cp = ( cp - 0xD800U ) * 0x400U;
71 *first ==
'u', ErrorReason::InvalidUTFEscape,
75 to_uint32( byte_from_nibbles<is_unchecked_input>( first ) ) << 8U;
76 trailing |= byte_from_nibbles<is_unchecked_input>( first );
82 if( cp >= 0x10000U ) {
84 char const enc3 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
86 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
88 u32toC( ( ( cp >> 12U ) & 0b0011'1111U ) | 0b1000'0000U );
89 char const enc0 =
u32toC( ( cp >> 18U ) | 0b1111'0000U );
100 char const enc2 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
102 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
103 char const enc0 =
u32toC( ( cp >> 12U ) | 0b1110'0000U );
113 char const enc1 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
114 char const enc0 =
u32toC( ( cp >> 6U ) | 0b1100'0000U );
121 template<
typename ParseState,
typename Appender>
124 constexpr
bool is_unchecked_input = ParseState::is_unchecked_input;
127 UInt32 cp = to_uint32( byte_from_nibbles<is_unchecked_input>( first ) )
129 cp |= byte_from_nibbles<is_unchecked_input>( first );
135 if( 0xD800U <= cp and cp <= 0xDBFFU ) {
136 cp = ( cp - 0xD800U ) * 0x400U;
142 to_uint32( byte_from_nibbles<is_unchecked_input>( first ) ) << 8U;
143 trailing |= byte_from_nibbles<is_unchecked_input>( first );
149 if( cp >= 0x10000U ) {
151 char const enc3 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
153 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
155 u32toC( ( ( cp >> 12U ) & 0b0011'1111U ) | 0b1000'0000U );
156 char const enc0 =
u32toC( ( cp >> 18U ) | 0b1111'0000U );
166 char const enc2 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
168 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
169 char const enc0 =
u32toC( ( cp >> 12U ) | 0b1110'0000U );
178 char const enc1 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
179 char const enc0 =
u32toC( ( cp >> 6U ) | 0b1100'0000U );
185 namespace parse_tokens {
191 template<
bool AllowHighEight,
typename JsonMember,
bool KnownBounds,
193 [[nodiscard, maybe_unused]] constexpr
auto
198 parse_state.get_allocator_for( template_arg<char> ) );
199 char *
it = std::data( result );
201 bool const has_quote =
parse_state.front( ) ==
'"';
206 if(
auto const first_slash =
207 static_cast<std::ptrdiff_t
>(
parse_state.counter ) - 1;
212 constexpr
auto pred = [](
auto const &r ) {
213 if constexpr( ParseState::is_unchecked_input ) {
214 return DAW_LIKELY( r.front( ) !=
'"' );
216 return DAW_LIKELY( r.has_more( ) ) & ( r.front( ) !=
'"' );
224 if constexpr( std::is_same<
typename ParseState::exec_tag_t,
228 ErrorReason::UnexpectedEndOfData,
230 while( *first !=
'"' and *first !=
'\\' ) {
233 ErrorReason::UnexpectedEndOfData,
239 ParseState::is_zero_terminated_string ),
240 '"',
'\\'>( ParseState::exec_tag, first,
249 ErrorReason::InvalidUTFCodepoint,
282 if constexpr( not AllowHighEight ) {
285 (
static_cast<unsigned char>(
parse_state.front( ) ) <=
287 ErrorReason::InvalidStringHighASCII,
parse_state );
301 static_cast<std::size_t
>( std::distance( std::data( result ),
it ) );
305 if constexpr( std::is_convertible<string_type,
309 using constructor_t =
typename JsonMember::constructor_t;
312 std::data( result ), daw::data_end( result ) );
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:189
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:178
ParseState & parse_state
Definition: daw_json_parse_class.h:201
Iterator & it
Definition: daw_json_traits.h:231
constexpr char const escape_quotes[]
Definition: daw_json_parse_std_string.h:186
DAW_ATTRIB_FLATINLINE CharT * mem_move_to_next_of(runtime_exec_tag, CharT *first, CharT *last)
Definition: daw_not_const_ex_functions.h:323
constexpr auto parse_string_known_stdstring(ParseState &parse_state)
Definition: daw_json_parse_std_string.h:194
static constexpr char * decode_utf16(ParseState &parse_state, char *it)
Definition: daw_json_parse_std_string.h:53
constexpr UInt16 byte_from_nibbles(char const *&first)
Definition: daw_json_parse_std_string.h:38
constexpr UInt8 to_nibble(unsigned char chr)
Definition: daw_json_parse_std_string.h:26
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value(template_params< Value, Constructor >, ParseState &parse_state, Args &&...args)
Definition: daw_json_parse_common.h:63
typename JsonMember::parse_to_t json_result
Definition: daw_json_parse_common.h:205
constexpr char u32toC(UInt32 value)
Definition: daw_json_parse_std_string.h:47
typename JsonMember::base_type json_base_type
Definition: daw_json_parse_common.h:208
Definition: daw_from_json.h:22
Definition: daw_json_exec_modes.h:19
#define DAW_JSON_VER
Definition: version.h:11