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 
25 namespace 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
251  handle_on_number( Handler &&handler, basic_json_value<ParseState> &jv ) {
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
266  handle_on_bool( Handler &&handler, basic_json_value<ParseState> jv ) {
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
280  handle_on_string( Handler &&handler, basic_json_value<ParseState> &jv ) {
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
295  handle_on_null( Handler &&handler, basic_json_value<ParseState> &jv ) {
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
319  enum class StackParseStateType { Class, Array };
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 
340  CPP20CONSTEXPR inline void push_back( value_type &&v ) {
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 ) {
368  using iterator = basic_json_value_iterator<ParseState>;
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:316
std::basic_string< char, Traits, Allocator > get_string(Allocator const &alloc=std::allocator< char >()) const
Definition: daw_json_value.h:471
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:189
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:178
#define CPP20CONSTEXPR
Definition: daw_json_parse_common.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 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
constexpr daw::remove_cvref_t< T > as_copy(T &&value)
Definition: daw_json_event_parser.h:187
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:540
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:41
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
Definition: version.h:11