17 #include <daw/algorithms/daw_algorithm_accumulate.h>
18 #include <daw/algorithms/daw_algorithm_find.h>
19 #include <daw/daw_cpp_feature_check.h>
20 #include <daw/daw_move.h>
21 #include <daw/iterator/daw_reverse_iterator.h>
25 #include <string_view>
30 namespace json_details {
33 template<
typename T,
typename U>
35 operator( )( T
const &lhs, U
const &rhs )
45 [[nodiscard]]
inline std::vector<json_path_node>
47 char const *doc_start );
50 std::string_view m_name{ };
51 char const *m_value_start =
nullptr;
52 long long m_index = -1;
55 friend std::vector<json_path_node>
57 char const *doc_start );
61 long long Index,
char const *ValueStart )
63 , m_value_start( ValueStart )
74 [[nodiscard]] constexpr std::string_view name( )
const {
79 [[nodiscard]] constexpr
long long index( )
const {
84 [[nodiscard]] constexpr
char const *value_start( )
const {
92 [[nodiscard]] DAW_ATTRIB_NOINLINE
inline std::string
94 return daw::algorithm::accumulate(
95 std::data( path_stack ), daw::data_end( path_stack ), std::string{ },
98 if( sv.index( ) >= 0 ) {
102 }
else if( not sv.name( ).empty( ) ) {
104 state += std::string( sv.name( ) );
106 return DAW_FWD( state );
114 [[nodiscard]]
inline std::vector<json_path_node>
116 char const *doc_start ) {
117 if( parse_location ==
nullptr or doc_start ==
nullptr ) {
120 if( json_details::less{ }( parse_location, doc_start ) ) {
127 std::vector<json_path_node> parse_stack{ };
131 std::optional<json_path_node> last_popped{ };
135 if( parse_stack.empty( ) ) {
136 return JsonBaseParseTypes::None;
138 return parse_stack.back( ).
type( );
141 [[nodiscard]]
bool handle_on_value(
json_pair jp ) {
142 if(
auto const range = jp.
value.get_raw_state( );
143 range.empty( ) or last <= std::data( range ) ) {
146 if(
auto const t = child_of( ); t == JsonBaseParseTypes::Class ) {
147 state.m_name = *jp.
name;
149 }
else if( t == JsonBaseParseTypes::Array ) {
156 state.m_value_start = jp.
value.get_raw_state( ).first;
157 state.m_type = jp.
value.type( );
158 last_popped = std::nullopt;
162 [[nodiscard]]
bool handle_on_array_start(
json_value const & ) {
163 parse_stack.push_back( state );
168 [[nodiscard]]
bool handle_on_array_end( ) {
169 if( not parse_stack.empty( ) ) {
170 last_popped = parse_stack.back( );
171 state = parse_stack.back( );
172 parse_stack.pop_back( );
177 [[nodiscard]]
bool handle_on_class_start(
json_value const & ) {
178 parse_stack.push_back( state );
183 [[nodiscard]]
bool handle_on_class_end( ) {
184 if( not parse_stack.empty( ) ) {
185 last_popped = parse_stack.back( );
186 state = parse_stack.back( );
187 parse_stack.pop_back( );
192 [[nodiscard]]
bool handle_on_number(
json_value jv ) {
193 auto sv = std::string_view( );
194 #if defined( DAW_USE_EXCEPTIONS )
198 #if defined( DAW_USE_EXCEPTIONS )
199 }
catch( json_exception
const & ) {
200 parse_stack.push_back( state );
204 if( std::data( sv ) <= last and last <= daw::data_end( sv ) ) {
205 parse_stack.push_back( state );
211 [[nodiscard]]
bool handle_on_bool(
json_value jv ) {
212 auto sv = std::string_view( );
213 #if defined( DAW_USE_EXCEPTIONS )
217 #if defined( DAW_USE_EXCEPTIONS )
218 }
catch( json_exception
const & ) {
219 parse_stack.push_back( state );
223 if( std::data( sv ) <= last and last <= daw::data_end( sv ) ) {
224 parse_stack.push_back( state );
230 [[nodiscard]]
bool handle_on_string(
json_value jv ) {
231 auto sv = std::string_view( );
232 #if defined( DAW_USE_EXCEPTIONS )
236 #if defined( DAW_USE_EXCEPTIONS )
237 }
catch( json_exception
const & ) {
238 parse_stack.push_back( state );
242 if( std::data( sv ) <= last and last <= daw::data_end( sv ) ) {
243 parse_stack.push_back( state );
249 [[nodiscard]]
bool handle_on_null(
json_value jv ) {
250 auto sv = std::string_view( );
251 #if defined( DAW_USE_EXCEPTIONS )
255 #if defined( DAW_USE_EXCEPTIONS )
256 }
catch( json_exception
const & ) {
257 parse_stack.push_back( state );
261 if( std::data( sv ) <= last and last <= daw::data_end( sv ) ) {
262 parse_stack.push_back( state );
267 } handler{ doc_start, parse_location + 1 };
269 #if defined( DAW_USE_EXCEPTIONS )
273 #if defined( DAW_USE_EXCEPTIONS )
274 }
catch( json_exception
const & ) {
279 if( handler.last_popped ) {
280 handler.parse_stack.push_back( *handler.last_popped );
282 return std::move( handler.parse_stack );
285 [[nodiscard]]
inline std::vector<json_path_node>
287 char const *doc_start ) {
291 [[nodiscard]]
inline std::string
297 [[nodiscard]]
inline std::string
303 [[nodiscard]] constexpr std::size_t
306 ErrorReason::UnexpectedEndOfData );
308 ErrorReason::UnexpectedEndOfData );
310 return daw::algorithm::accumulate( doc_start, doc_pos, std::size_t{ },
311 []( std::size_t count,
char c )
320 [[nodiscard]] constexpr std::size_t
325 [[nodiscard]] constexpr std::size_t
328 ErrorReason::UnexpectedEndOfData );
330 ErrorReason::UnexpectedEndOfData );
332 auto const first = daw::reverse_iterator<char const *>( doc_pos );
333 auto const last = daw::reverse_iterator<char const *>( doc_start );
334 auto const pos = daw::algorithm::find( first, last,
'\n' ) - first;
336 return static_cast<std::size_t
>( pos );
339 [[nodiscard]] constexpr std::size_t
constexpr char const * value_start() const
The beginning of the value's data in JSON document.
constexpr JsonBaseParseTypes type() const
What type of value is represented.
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
#define DAW_JSON_CPP23_STATIC_CALL_OP_DISABLE_WARNING
#define DAW_JSON_CPP23_STATIC_CALL_OP_CONST
#define DAW_JSON_CPP23_STATIC_CALL_OP_ENABLE_WARNING
#define DAW_JSON_CPP23_STATIC_CALL_OP
This is in addition to the parse policy. Always do a full name match instead of sometimes relying on ...
constexpr std::string_view to_string(JsonBaseParseTypes pt)
JsonBaseParseTypes
The fundamental JSON types.
constexpr void json_event_parser(basic_json_value< P, A > bjv, Handler &&handler, options::parse_flags_t< ParseFlags... >)
std::string find_json_path_to(char const *parse_location, char const *doc_start)
DAW_ATTRIB_NOINLINE std::string to_json_path_string(std::vector< json_path_node > const &path_stack)
Convert a json_path_node stack to a JSON Path string.
constexpr std::size_t find_column_number_of(char const *doc_pos, char const *doc_start)
std::vector< json_path_node > find_json_path_stack_to(char const *parse_location, char const *doc_start)
Get the json_path_nodes representing the path to the nearest value's position in the document.
constexpr std::size_t find_line_number_of(char const *doc_pos, char const *doc_start)
Customization point traits.
A name/value pair of string_view/json_value.
basic_json_value< PolicyFlags, Allocator > value
std::optional< std::string_view > name
A non-owning container for arbitrary JSON values that allows movement/iteration through.
constexpr std::string_view get_string_view() const
Construct a string range of the current value. Strings start inside the quotes.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.