DAW JSON Link
daw_json_event_parser.h
Go to the documentation of this file.
1// Copyright (c) Darrell Wright
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5//
6// Official repository: https://github.com/beached/daw_json_link
7//
8
9#pragma once
10
11#include "daw_from_json_fwd.h"
13#include "impl/daw_json_value.h"
14#include "impl/version.h"
15
16#include <daw/daw_move.h>
17
18#include <ciso646>
19#include <cstddef>
20#include <string>
21#include <string_view>
22#include <utility>
23#include <vector>
24
25namespace daw::json {
26 inline namespace DAW_JSON_VER {
28 namespace json_details {
31
32 constexpr handler_result_holder( ) = default;
33
34 constexpr handler_result_holder( bool b )
35 : value( b ? Continue : Complete ) {}
36
38 : value( r ) {}
39
40 constexpr explicit operator bool( ) const {
42 }
43 };
44
45 namespace hnd_checks {
46 // On Next Value
47 template<typename Handler, typename ParseState>
49 decltype( std::declval<Handler>( ).handle_on_value(
50 std::declval<basic_json_pair<ParseState>>( ) ) );
51
52 template<typename Handler, typename ParseState>
53 inline constexpr bool has_on_value_handler_v =
54 daw::is_detected<has_on_value_handler_detect, Handler,
55 ParseState>::value;
56
57 // On Array Start
58 template<typename Handler, typename ParseState>
60 decltype( std::declval<Handler>( ).handle_on_array_start(
61 std::declval<basic_json_value<ParseState>>( ) ) );
62
63 template<typename Handler, typename ParseState>
64 inline constexpr bool has_on_array_start_handler_v =
65 daw::is_detected<has_on_array_start_handler_detect, Handler,
66 ParseState>::value;
67
68 // On Array End
69 template<typename Handler>
71 decltype( std::declval<Handler>( ).handle_on_array_end( ) );
72
73 template<typename Handler>
74 inline constexpr bool has_on_array_end_handler_v =
75 daw::is_detected<has_on_array_end_handler_detect, Handler>::value;
76
77 // On Class Start
78 template<typename Handler, typename ParseState>
80 decltype( std::declval<Handler>( ).handle_on_class_start(
81 std::declval<basic_json_value<ParseState>>( ) ) );
82
83 template<typename Handler, typename ParseState>
84 inline constexpr bool has_on_class_start_handler_v =
85 daw::is_detected<has_on_class_start_handler_detect, Handler,
86 ParseState>::value;
87
88 // On Class End
89 template<typename Handler>
91 decltype( std::declval<Handler>( ).handle_on_class_end( ) );
92
93 template<typename Handler>
94 inline constexpr bool has_on_class_end_handler_v =
95 daw::is_detected<has_on_class_end_handler_detect, Handler>::value;
96
97 // On Number
98 template<typename Handler, typename ParseState>
100 decltype( std::declval<Handler>( ).handle_on_number(
101 std::declval<basic_json_value<ParseState>>( ) ) );
102
103 template<typename Handler, typename ParseState>
104 inline constexpr bool has_on_number_handler_jv_v =
105 daw::is_detected<has_on_number_handler_detect_jv, Handler,
106 ParseState>::value;
107
108 template<typename Handler>
110 decltype( std::declval<Handler>( ).handle_on_number( 0.0 ) );
111
112 template<typename Handler>
113 inline constexpr bool has_on_number_handler_dbl_v =
114 daw::is_detected<has_on_number_handler_detect_dbl, Handler>::value;
115
116 // On Bool
117 template<typename Handler, typename ParseState>
119 decltype( std::declval<Handler>( ).handle_on_bool(
120 std::declval<basic_json_value<ParseState>>( ) ) );
121
122 template<typename Handler, typename ParseState>
123 inline constexpr bool has_on_bool_handler_jv_v =
124 daw::is_detected<has_on_bool_handler_detect_jv, Handler,
125 ParseState>::value;
126
127 template<typename Handler>
129 decltype( std::declval<Handler>( ).handle_on_bool( true ) );
130
131 template<typename Handler>
132 inline constexpr bool has_on_bool_handler_bl_v =
133 daw::is_detected<has_on_bool_handler_detect_bl, Handler>::value;
134
135 // On String
136 template<typename Handler, typename ParseState>
138 decltype( std::declval<Handler>( ).handle_on_string(
139 std::declval<basic_json_value<ParseState>>( ) ) );
140
141 template<typename Handler, typename ParseState>
142 inline constexpr bool has_on_string_handler_jv_v =
143 daw::is_detected<has_on_string_handler_detect_jv, Handler,
144 ParseState>::value;
145
146 template<typename Handler>
148 decltype( std::declval<Handler>( ).handle_on_string(
149 std::declval<std::string>( ) ) );
150
151 template<typename Handler>
152 inline constexpr bool has_on_string_handler_str_v =
153 daw::is_detected<has_on_string_handler_detect_str, Handler>::value;
154
155 // On Null
156 template<typename Handler, typename ParseState>
158 decltype( std::declval<Handler>( ).handle_on_null(
159 std::declval<basic_json_value<ParseState>>( ) ) );
160
161 template<typename Handler, typename ParseState>
162 inline constexpr bool has_on_null_handler_jv_v =
163 daw::is_detected<has_on_null_handler_detect_jv, Handler,
164 ParseState>::value;
165
166 template<typename Handler>
168 decltype( std::declval<Handler>( ).handle_on_null( ) );
169
170 template<typename Handler>
171 inline constexpr bool has_on_null_handler_v =
172 daw::is_detected<has_on_null_handler_detect, Handler>::value;
173
174 // On Error
175 template<typename Handler, typename ParseState>
177 decltype( std::declval<Handler>( ).handle_on_error(
178 std::declval<basic_json_value<ParseState>>( ) ) );
179
180 template<typename Handler, typename ParseState>
181 inline constexpr bool has_on_error_handler_v =
182 daw::is_detected<has_on_error_handler_detect, Handler,
183 ParseState>::value;
184 } // namespace hnd_checks
185
186 template<typename T>
187 constexpr daw::remove_cvref_t<T> as_copy( T &&value ) {
188 return value;
189 }
190
191 template<typename Handler, typename ParseState>
192 inline constexpr handler_result_holder
194 if constexpr( hnd_checks::has_on_value_handler_v<Handler,
195 ParseState> ) {
196 return handler.handle_on_value( DAW_MOVE( p ) );
197 } else {
198 (void)p;
199 return handler_result_holder{ };
200 }
201 }
202
203 template<typename Handler, typename ParseState>
204 inline constexpr handler_result_holder
205 handle_on_array_start( Handler &&handler,
207 if constexpr( hnd_checks::has_on_array_start_handler_v<Handler,
208 ParseState> ) {
209 return handler.handle_on_array_start( DAW_MOVE( jv ) );
210 } else {
211 (void)jv;
212 return handler_result_holder{ };
213 }
214 }
215
216 template<typename Handler>
217 inline constexpr handler_result_holder
218 handle_on_array_end( Handler &&handler ) {
219 if constexpr( hnd_checks::has_on_array_end_handler_v<Handler> ) {
220 return handler.handle_on_array_end( );
221 } else {
222 return handler_result_holder{ };
223 }
224 }
225
226 template<typename Handler, typename ParseState>
227 inline constexpr handler_result_holder
228 handle_on_class_start( Handler &&handler,
230 if constexpr( hnd_checks::has_on_class_start_handler_v<Handler,
231 ParseState> ) {
232 return handler.handle_on_class_start( DAW_MOVE( jv ) );
233 } else {
234 (void)jv;
235 return handler_result_holder{ };
236 }
237 }
238
239 template<typename Handler>
240 inline constexpr handler_result_holder
241 handle_on_class_end( Handler &&handler ) {
242 if constexpr( hnd_checks::has_on_class_end_handler_v<Handler> ) {
243 return handler.handle_on_class_end( );
244 } else {
245 return handler_result_holder{ };
246 }
247 }
248
249 template<typename Handler, typename ParseState>
250 inline constexpr handler_result_holder
252 if constexpr( hnd_checks::has_on_number_handler_jv_v<Handler,
253 ParseState> ) {
254 return handler.handle_on_number( as_copy( jv ) );
255 } else if constexpr( hnd_checks::has_on_number_handler_dbl_v<
256 Handler> ) {
257 return handler.handle_on_number( from_json<double>( jv ) );
258 } else {
259 (void)jv;
260 return handler_result_holder{ };
261 }
262 }
263
264 template<typename Handler, typename ParseState>
265 inline constexpr handler_result_holder
267 if constexpr( hnd_checks::has_on_bool_handler_jv_v<Handler,
268 ParseState> ) {
269 return handler.handle_on_bool( as_copy( jv ) );
270 } else if constexpr( hnd_checks::has_on_bool_handler_bl_v<Handler> ) {
271 return handler.handle_on_bool( from_json<bool>( jv ) );
272 } else {
273 (void)jv;
274 return handler_result_holder{ };
275 }
276 }
277
278 template<typename Handler, typename ParseState>
279 inline constexpr handler_result_holder
281 if constexpr( hnd_checks::has_on_string_handler_jv_v<Handler,
282 ParseState> ) {
283 return handler.handle_on_string( as_copy( jv ) );
284 } else if constexpr( hnd_checks::has_on_string_handler_str_v<
285 Handler> ) {
286 return handler.handle_on_string( jv.get_string( ) );
287 } else {
288 (void)jv;
289 return handler_result_holder{ };
290 }
291 }
292
293 template<typename Handler, typename ParseState>
294 inline constexpr handler_result_holder
296 if constexpr( hnd_checks::has_on_null_handler_jv_v<Handler,
297 ParseState> ) {
298 return handler.handle_on_null( as_copy( jv ) );
299 } else if constexpr( hnd_checks::has_on_null_handler_v<Handler> ) {
300 return handler.handle_on_null( );
301 } else {
302 return handler_result_holder{ };
303 }
304 }
305
306 template<typename Handler, typename ParseState>
307 inline constexpr handler_result_holder
309 if constexpr( hnd_checks::has_on_error_handler_v<Handler,
310 ParseState> ) {
311 return handler.handle_on_error( DAW_MOVE( jv ) );
312 } else {
313 (void)jv;
314 return handler_result_holder{ };
315 }
316 }
317
318 } // namespace json_details
320
321 template<typename ParseState>
325 std::pair<iterator, iterator> value;
326 };
327
328 template<typename StackValue>
330 std::vector<StackValue> m_stack{ };
331
332 public:
333 using value_type = StackValue;
334 using reference = StackValue &;
335 using size_type = std::size_t;
336 using difference_type = std::ptrdiff_t;
337
339
341 m_stack.push_back( DAW_MOVE( v ) );
342 }
343
344 [[nodiscard]] CPP20CONSTEXPR inline reference back( ) {
345 return m_stack.back( );
346 }
347
348 CPP20CONSTEXPR inline void clear( ) {
349 m_stack.clear( );
350 }
351
352 CPP20CONSTEXPR inline void pop_back( ) {
353 m_stack.pop_back( );
354 }
355
356 [[nodiscard]] CPP20CONSTEXPR inline bool empty( ) const {
357 return m_stack.empty( );
358 }
359 };
360
361 template<typename ParseState = NoCommentSkippingPolicyChecked,
362 typename StackContainerPolicy = DefaultJsonEventParserStackPolicy<
364 typename Handler>
365 inline constexpr void
367 Handler &&handler ) {
369 using json_value_t = basic_json_pair<ParseState>;
370 using stack_value_t = JsonEventParserStackValue<ParseState>;
371
372 auto parent_stack = StackContainerPolicy( );
373 long long class_depth = 0;
374 long long array_depth = 0;
375
376 auto const move_to_last = [&]( ) {
377 parent_stack.back( ).value.first = parent_stack.back( ).value.second;
378 };
379
380 auto const process_value = [&]( json_value_t p ) {
381 {
382 auto result = json_details::handle_on_value( handler, p );
383 switch( result.value ) {
385 parent_stack.clear( );
386 return;
388 move_to_last( );
389 return;
391 break;
392 }
393 }
394
395 auto &jv = p.value;
396 switch( jv.type( ) ) {
398 ++array_depth;
399 auto result = json_details::handle_on_array_start( handler, jv );
400 switch( result.value ) {
402 parent_stack.clear( );
403 return;
405 move_to_last( );
406 return;
408 break;
409 }
410 parent_stack.push_back(
412 std::pair<iterator, iterator>( jv.begin( ), jv.end( ) ) } );
413 } break;
415 ++class_depth;
416 auto result = json_details::handle_on_class_start( handler, jv );
417 switch( result.value ) {
419 parent_stack.clear( );
420 return;
422 move_to_last( );
423 return;
425 break;
426 }
427 parent_stack.push_back(
429 std::pair<iterator, iterator>( jv.begin( ), jv.end( ) ) } );
430 } break;
432 auto result = json_details::handle_on_number( handler, jv );
433 switch( result.value ) {
435 parent_stack.clear( );
436 return;
438 move_to_last( );
439 return;
441 break;
442 }
443 } break;
445 auto result = json_details::handle_on_bool( handler, jv );
446 switch( result.value ) {
448 parent_stack.clear( );
449 return;
451 move_to_last( );
452 return;
454 break;
455 }
456 } break;
458 auto result = json_details::handle_on_string( handler, jv );
459 switch( result.value ) {
461 parent_stack.clear( );
462 return;
464 move_to_last( );
465 return;
467 break;
468 }
469 } break;
471 auto result = json_details::handle_on_null( handler, jv );
472 switch( result.value ) {
474 parent_stack.clear( );
475 return;
477 move_to_last( );
478 return;
480 break;
481 }
482 } break;
484 default: {
485 auto result = json_details::handle_on_error( handler, jv );
486 switch( result.value ) {
488 parent_stack.clear( );
489 return;
491 move_to_last( );
492 return;
494 break;
495 }
496 } break;
497 }
498 };
499
500 auto const process_range = [&]( stack_value_t v ) {
501 if( v.value.first != v.value.second ) {
502 auto jv = *v.value.first;
503 v.value.first++;
504 parent_stack.push_back( DAW_MOVE( v ) );
505 process_value( DAW_MOVE( jv ) );
506 } else {
507 switch( v.type ) {
510 ( class_depth > 0 ) &
511 ( v.value.first.get_raw_state( ).has_more( ) and
512 v.value.first.get_raw_state( ).front( ) == '}' ),
513 ErrorReason::InvalidEndOfValue );
514 --class_depth;
515 auto result = json_details::handle_on_class_end( handler );
516 switch( result.value ) {
518 parent_stack.clear( );
519 return;
522 break;
523 }
524 } break;
527 ( array_depth > 0 ) &
528 ( v.value.first.get_raw_state( ).has_more( ) and
529 v.value.first.get_raw_state( ).front( ) == ']' ),
530 ErrorReason::InvalidEndOfValue );
531 --array_depth;
532 auto result = json_details::handle_on_array_end( handler );
533 switch( result.value ) {
535 parent_stack.clear( );
536 return;
539 break;
540 }
541 } break;
542 }
543 }
544 };
545
546 process_value( { std::nullopt, DAW_MOVE( jvalue ) } );
547
548 while( not parent_stack.empty( ) ) {
549 auto v = DAW_MOVE( parent_stack.back( ) );
550 parent_stack.pop_back( );
551 process_range( v );
552 }
553 daw_json_assert( class_depth == 0 and array_depth == 0,
554 ErrorReason::InvalidEndOfValue );
555 }
556
557 template<typename ParsePolicy = NoCommentSkippingPolicyChecked,
558 typename Handler>
559 inline void json_event_parser( std::string_view json_document,
560 Handler &&handler ) {
561 return json_event_parser( basic_json_value<ParsePolicy>( json_document ),
562 DAW_FWD2( Handler, handler ) );
563 }
564 } // namespace DAW_JSON_VER
565} // namespace daw::json
Definition: daw_json_event_parser.h:329
std::size_t size_type
Definition: daw_json_event_parser.h:335
StackValue & reference
Definition: daw_json_event_parser.h:334
std::ptrdiff_t difference_type
Definition: daw_json_event_parser.h:336
CPP20CONSTEXPR void push_back(value_type &&v)
Definition: daw_json_event_parser.h:340
CPP20CONSTEXPR bool empty() const
Definition: daw_json_event_parser.h:356
CPP20CONSTEXPR void clear()
Definition: daw_json_event_parser.h:348
CPP20CONSTEXPR void pop_back()
Definition: daw_json_event_parser.h:352
CPP20CONSTEXPR reference back()
Definition: daw_json_event_parser.h:344
StackValue value_type
Definition: daw_json_event_parser.h:333
Definition: daw_json_value.h:320
std::basic_string< char, Traits, Allocator > get_string(Allocator const &alloc=std::allocator< char >()) const
Definition: daw_json_value.h:479
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:190
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:179
#define CPP20CONSTEXPR
Definition: daw_json_parse_value.h:40
decltype(std::declval< Handler >().handle_on_class_end()) has_on_class_end_handler_detect
Definition: daw_json_event_parser.h:91
constexpr bool has_on_array_end_handler_v
Definition: daw_json_event_parser.h:74
decltype(std::declval< Handler >().handle_on_error(std::declval< basic_json_value< ParseState > >())) has_on_error_handler_detect
Definition: daw_json_event_parser.h:178
constexpr bool has_on_bool_handler_jv_v
Definition: daw_json_event_parser.h:123
constexpr bool has_on_number_handler_jv_v
Definition: daw_json_event_parser.h:104
decltype(std::declval< Handler >().handle_on_null(std::declval< basic_json_value< ParseState > >())) has_on_null_handler_detect_jv
Definition: daw_json_event_parser.h:159
decltype(std::declval< Handler >().handle_on_number(0.0)) has_on_number_handler_detect_dbl
Definition: daw_json_event_parser.h:110
decltype(std::declval< Handler >().handle_on_bool(true)) has_on_bool_handler_detect_bl
Definition: daw_json_event_parser.h:129
constexpr bool has_on_null_handler_jv_v
Definition: daw_json_event_parser.h:162
decltype(std::declval< Handler >().handle_on_array_end()) has_on_array_end_handler_detect
Definition: daw_json_event_parser.h:71
decltype(std::declval< Handler >().handle_on_array_start(std::declval< basic_json_value< ParseState > >())) has_on_array_start_handler_detect
Definition: daw_json_event_parser.h:61
decltype(std::declval< Handler >().handle_on_class_start(std::declval< basic_json_value< ParseState > >())) has_on_class_start_handler_detect
Definition: daw_json_event_parser.h:81
constexpr bool has_on_string_handler_str_v
Definition: daw_json_event_parser.h:152
constexpr bool has_on_error_handler_v
Definition: daw_json_event_parser.h:181
decltype(std::declval< Handler >().handle_on_string(std::declval< basic_json_value< ParseState > >())) has_on_string_handler_detect_jv
Definition: daw_json_event_parser.h:139
decltype(std::declval< Handler >().handle_on_value(std::declval< basic_json_pair< ParseState > >())) has_on_value_handler_detect
Definition: daw_json_event_parser.h:50
decltype(std::declval< Handler >().handle_on_number(std::declval< basic_json_value< ParseState > >())) has_on_number_handler_detect_jv
Definition: daw_json_event_parser.h:101
constexpr bool has_on_bool_handler_bl_v
Definition: daw_json_event_parser.h:132
constexpr bool has_on_string_handler_jv_v
Definition: daw_json_event_parser.h:142
constexpr bool has_on_number_handler_dbl_v
Definition: daw_json_event_parser.h:113
decltype(std::declval< Handler >().handle_on_string(std::declval< std::string >())) has_on_string_handler_detect_str
Definition: daw_json_event_parser.h:149
constexpr bool has_on_value_handler_v
Definition: daw_json_event_parser.h:53
constexpr bool has_on_class_end_handler_v
Definition: daw_json_event_parser.h:94
decltype(std::declval< Handler >().handle_on_null()) has_on_null_handler_detect
Definition: daw_json_event_parser.h:168
constexpr bool has_on_null_handler_v
Definition: daw_json_event_parser.h:171
decltype(std::declval< Handler >().handle_on_bool(std::declval< basic_json_value< ParseState > >())) has_on_bool_handler_detect_jv
Definition: daw_json_event_parser.h:120
constexpr bool has_on_array_start_handler_v
Definition: daw_json_event_parser.h:64
constexpr bool has_on_class_start_handler_v
Definition: daw_json_event_parser.h:84
constexpr handler_result_holder handle_on_null(Handler &&handler, basic_json_value< ParseState > &jv)
Definition: daw_json_event_parser.h:295
constexpr daw::remove_cvref_t< T > as_copy(T &&value)
Definition: daw_json_event_parser.h:187
constexpr handler_result_holder handle_on_array_end(Handler &&handler)
Definition: daw_json_event_parser.h:218
constexpr handler_result_holder handle_on_error(Handler &&handler, basic_json_value< ParseState > jv)
Definition: daw_json_event_parser.h:308
constexpr handler_result_holder handle_on_string(Handler &&handler, basic_json_value< ParseState > &jv)
Definition: daw_json_event_parser.h:280
constexpr handler_result_holder handle_on_class_start(Handler &&handler, basic_json_value< ParseState > jv)
Definition: daw_json_event_parser.h:228
constexpr handler_result_holder handle_on_bool(Handler &&handler, basic_json_value< ParseState > jv)
Definition: daw_json_event_parser.h:266
constexpr handler_result_holder handle_on_class_end(Handler &&handler)
Definition: daw_json_event_parser.h:241
constexpr handler_result_holder handle_on_value(Handler &&handler, basic_json_pair< ParseState > p)
Definition: daw_json_event_parser.h:193
constexpr handler_result_holder handle_on_number(Handler &&handler, basic_json_value< ParseState > &jv)
Definition: daw_json_event_parser.h:251
constexpr handler_result_holder handle_on_array_start(Handler &&handler, basic_json_value< ParseState > jv)
Definition: daw_json_event_parser.h:205
json_parse_handler_result
Definition: daw_json_event_parser.h:27
@ Complete
Definition: daw_json_event_parser.h:27
@ SkipClassArray
Definition: daw_json_event_parser.h:27
@ Continue
Definition: daw_json_event_parser.h:27
StackParseStateType
Definition: daw_json_event_parser.h:319
constexpr void json_event_parser(basic_json_value< ParseState > jvalue, Handler &&handler)
Definition: daw_json_event_parser.h:366
BasicParsePolicy<> NoCommentSkippingPolicyChecked
Definition: daw_json_parse_policy.h:550
Definition: daw_from_json.h:22
Definition: daw_json_event_parser.h:322
std::pair< iterator, iterator > value
Definition: daw_json_event_parser.h:325
StackParseStateType type
Definition: daw_json_event_parser.h:324
Definition: daw_json_value.h:42
constexpr handler_result_holder(bool b)
Definition: daw_json_event_parser.h:34
constexpr handler_result_holder(json_parse_handler_result r)
Definition: daw_json_event_parser.h:37
json_parse_handler_result value
Definition: daw_json_event_parser.h:30
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16