17#include <daw/daw_likely.h>
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;
59 UInt32 cp = to_uint32( byte_from_nibbles<is_unchecked_input>( first ) )
61 cp |= byte_from_nibbles<is_unchecked_input>( first );
63 *
it++ =
static_cast<char>(
static_cast<unsigned char>( cp ) );
69 if( 0xD800U <= cp and cp <= 0xDBFFU ) {
70 cp = ( cp - 0xD800U ) * 0x400U;
73 (
parse_state.last - first >= 5 ) and *first ==
'u',
74 ErrorReason::InvalidUTFEscape,
78 to_uint32( byte_from_nibbles<is_unchecked_input>( first ) ) << 8U;
79 trailing |= byte_from_nibbles<is_unchecked_input>( first );
85 if( cp >= 0x10000U ) {
87 char const enc3 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
89 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
91 u32toC( ( ( cp >> 12U ) & 0b0011'1111U ) | 0b1000'0000U );
92 char const enc0 =
u32toC( ( cp >> 18U ) | 0b1111'0000U );
103 char const enc2 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
105 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
106 char const enc0 =
u32toC( ( cp >> 12U ) | 0b1110'0000U );
116 char const enc1 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
117 char const enc0 =
u32toC( ( cp >> 6U ) | 0b1100'0000U );
124 template<
typename ParseState,
typename Appender>
127 constexpr bool is_unchecked_input = ParseState::is_unchecked_input;
130 UInt32 cp = to_uint32( byte_from_nibbles<is_unchecked_input>( first ) )
132 cp |= byte_from_nibbles<is_unchecked_input>( first );
138 if( 0xD800U <= cp and cp <= 0xDBFFU ) {
139 cp = ( cp - 0xD800U ) * 0x400U;
145 to_uint32( byte_from_nibbles<is_unchecked_input>( first ) ) << 8U;
146 trailing |= byte_from_nibbles<is_unchecked_input>( first );
152 if( cp >= 0x10000U ) {
154 char const enc3 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
156 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
158 u32toC( ( ( cp >> 12U ) & 0b0011'1111U ) | 0b1000'0000U );
159 char const enc0 =
u32toC( ( cp >> 18U ) | 0b1111'0000U );
169 char const enc2 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
171 u32toC( ( ( cp >> 6U ) & 0b0011'1111U ) | 0b1000'0000U );
172 char const enc0 =
u32toC( ( cp >> 12U ) | 0b1110'0000U );
181 char const enc1 =
u32toC( ( cp & 0b0011'1111U ) | 0b1000'0000U );
182 char const enc0 =
u32toC( ( cp >> 6U ) | 0b1100'0000U );
188 namespace parse_tokens {
194 template<
bool AllowHighEight,
typename JsonMember,
bool KnownBounds,
196 [[nodiscard, maybe_unused]]
constexpr auto
201 parse_state.get_allocator_for( template_arg<char> ) );
202 char *
it = std::data( result );
204 bool const has_quote =
parse_state.front( ) ==
'"';
209 if(
auto const first_slash =
210 static_cast<std::ptrdiff_t
>(
parse_state.counter ) - 1;
215 constexpr auto pred = [](
auto const &r ) {
216 if constexpr( ParseState::is_unchecked_input ) {
217 return DAW_LIKELY( r.front( ) !=
'"' );
219 return DAW_LIKELY( r.has_more( ) ) and ( r.front( ) !=
'"' );
227 if constexpr( std::is_same<
typename ParseState::exec_tag_t,
231 ErrorReason::UnexpectedEndOfData,
233 while( *first !=
'"' and *first !=
'\\' ) {
236 ErrorReason::UnexpectedEndOfData,
242 ParseState::is_zero_terminated_string ),
243 '"',
'\\'>( ParseState::exec_tag, first,
252 ErrorReason::InvalidUTFCodepoint,
285 if constexpr( not AllowHighEight ) {
288 (
static_cast<unsigned char>(
parse_state.front( ) ) <=
290 ErrorReason::InvalidStringHighASCII,
parse_state );
304 static_cast<std::size_t
>( std::distance( std::data( result ),
it ) );
308 if constexpr( std::is_convertible<string_type,
312 using constructor_t =
typename JsonMember::constructor_t;
315 std::data( result ), daw::data_end( result ) );
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:190
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:179
ParseState & parse_state
Definition: daw_json_parse_class.h:182
Iterator & it
Definition: daw_json_traits.h:251
constexpr char const escape_quotes[]
Definition: daw_json_parse_std_string.h:189
constexpr auto parse_string_known_stdstring(ParseState &parse_state)
Definition: daw_json_parse_std_string.h:197
constexpr UInt16 byte_from_nibbles(char const *&first)
Definition: daw_json_parse_std_string.h:38
DAW_ATTRIB_INLINE CharT * mem_move_to_next_of(runtime_exec_tag, CharT *first, CharT *last)
Definition: daw_not_const_ex_functions.h:353
constexpr UInt8 to_nibble(unsigned char chr)
Definition: daw_json_parse_std_string.h:26
static constexpr char * decode_utf16(ParseState &parse_state, char *it)
Definition: daw_json_parse_std_string.h:53
static constexpr DAW_ATTRIB_FLATINLINE auto construct_value(template_params< Value, Constructor >, ParseState &parse_state, Args &&...args)
Definition: daw_json_parse_common.h:60
typename JsonMember::parse_to_t json_result
Definition: daw_json_parse_common.h:200
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:203
Definition: daw_from_json.h:22
Definition: daw_json_exec_modes.h:19
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16