DAW JSON Link
daw_json_parse_policy_hash_comments.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_json_assert.h"
15#include "version.h"
16
17#include <daw/daw_attributes.h>
18#include <daw/daw_likely.h>
19#include <daw/daw_traits.h>
20
21#include <ciso646>
22#include <cstddef>
23#include <cstdint>
24#include <type_traits>
25
26namespace daw::json {
27 inline namespace DAW_JSON_VER {
29 template<typename ParseState>
30 DAW_ATTRIB_FLATINLINE static constexpr void
31 skip_comments_unchecked( ParseState &parse_state ) {
32 while( parse_state.front( ) == '#' ) {
33 parse_state.remove_prefix( );
34 parse_state.template move_to_next_of_unchecked<'\n'>( );
35 parse_state.remove_prefix( );
36 }
37 }
38
39 template<typename ParseState>
40 DAW_ATTRIB_FLATINLINE static constexpr void
41 skip_comments_checked( ParseState &parse_state ) {
42 while( parse_state.has_more( ) and parse_state.front( ) == '#' ) {
43 parse_state.remove_prefix( );
44 parse_state.template move_to_next_of_checked<'\n'>( );
45 if( parse_state.front( ) == '\n' ) {
46 parse_state.remove_prefix( );
47 }
48 }
49 }
50
51 template<typename ParseState>
52 DAW_ATTRIB_FLATINLINE static constexpr void
53 skip_comments( ParseState &parse_state ) {
54 if constexpr( ParseState::is_unchecked_input ) {
55 skip_comments_unchecked( parse_state );
56 } else {
57 skip_comments_checked( parse_state );
58 }
59 }
60
61 public:
62 template<typename ParseState>
63 DAW_ATTRIB_FLATINLINE static constexpr void
65 skip_comments_checked( parse_state );
66 while( parse_state.has_more( ) and parse_state.is_space_unchecked( ) ) {
67 parse_state.remove_prefix( );
68 skip_comments_checked( parse_state );
69 }
70 }
71
72 template<typename ParseState>
73 DAW_ATTRIB_FLATINLINE static constexpr void
75 skip_comments_unchecked( parse_state );
76 while( parse_state.is_space_unchecked( ) ) {
77 parse_state.remove_prefix( );
78 }
79 }
80
81 template<typename ParseState>
82 DAW_ATTRIB_FLATINLINE static constexpr void
84 parse_state.move_next_member_or_end_unchecked( );
85 }
86
87 template<char... keys, typename ParseState>
88 DAW_ATTRIB_FLATINLINE static constexpr void
90 skip_comments( parse_state );
91
93 ErrorReason::UnexpectedEndOfData, parse_state );
94 while( not parse_policy_details::in<keys...>( parse_state.front( ) ) ) {
96 ErrorReason::UnexpectedEndOfData, parse_state );
97 parse_state.remove_prefix( );
98 skip_comments( parse_state );
99 }
100 }
101
102 DAW_ATTRIB_FLATINLINE static constexpr bool is_literal_end( char c ) {
103 return c == '\0' or c == ',' or c == ']' or c == '}' or c == '#';
104 }
105
106 template<char PrimLeft, char PrimRight, char SecLeft, char SecRight,
107 typename ParseState>
108 DAW_ATTRIB_FLATINLINE static constexpr ParseState
110 using CharT = typename ParseState::CharT;
111 // Not checking for Left as it is required to be skipped already
112 auto result = parse_state;
113 std::size_t cnt = 0;
114 std::uint32_t prime_bracket_count = 1;
115 std::uint32_t second_bracket_count = 0;
116 CharT *ptr_first = parse_state.first;
117 CharT *const ptr_last = parse_state.last;
118 if( DAW_UNLIKELY( ptr_first >= ptr_last ) ) {
119 return result;
120 }
121 if( *ptr_first == PrimLeft ) {
122 ++ptr_first;
123 }
124 while( DAW_LIKELY( ptr_first < ptr_last ) ) {
125 // TODO: use if/else if or put switch into IILE
126 switch( *ptr_first ) {
127 case '\\':
128 ++ptr_first;
129 break;
130 case '"':
131 ++ptr_first;
132 if constexpr( traits::not_same_v<typename ParseState::exec_tag_t,
135 ParseState::is_unchecked_input>( ParseState::exec_tag,
136 ptr_first, parse_state.last );
137 } else {
138 while( DAW_LIKELY( ptr_first < ptr_last ) and
139 *ptr_first != '"' ) {
140 if( *ptr_first == '\\' ) {
141 ++ptr_first;
142 if( ptr_first >= ptr_last ) {
143 break;
144 }
145 }
146 ++ptr_first;
147 }
148 }
149 daw_json_assert( ptr_first < ptr_last,
150 ErrorReason::UnexpectedEndOfData, parse_state );
151 break;
152 case ',':
153 if( prime_bracket_count == 1 and second_bracket_count == 0 ) {
154 ++cnt;
155 }
156 break;
157 case PrimLeft:
158 ++prime_bracket_count;
159 break;
160 case PrimRight:
161 --prime_bracket_count;
162 if( prime_bracket_count == 0 ) {
163 daw_json_assert( second_bracket_count == 0,
164 ErrorReason::InvalidBracketing, parse_state );
165 ++ptr_first;
166 // We include the close primary bracket in the range so that
167 // subsequent parsers have a terminator inside their range
168 result.last = ptr_first;
169 result.counter = cnt;
170 parse_state.first = ptr_first;
171 return result;
172 }
173 break;
174 case SecLeft:
175 ++second_bracket_count;
176 break;
177 case SecRight:
178 --second_bracket_count;
179 break;
180 case '#':
181 ++ptr_first;
182 while( ptr_first < ptr_last and *ptr_first != '\n' ) {
183 ++ptr_first;
184 }
185 if( ptr_first < ptr_last ) {
186 continue;
187 }
188 break;
189 }
190 ++ptr_first;
191 }
192 daw_json_assert( ( prime_bracket_count == 0 ) &
193 ( second_bracket_count == 0 ),
194 ErrorReason::InvalidBracketing, parse_state );
195 // We include the close primary bracket in the range so that subsequent
196 // parsers have a terminator inside their range
197 result.last = ptr_first;
198 result.counter = cnt;
199 parse_state.first = ptr_first;
200 return result;
201 }
202
203 template<char PrimLeft, char PrimRight, char SecLeft, char SecRight,
204 typename ParseState>
205 DAW_ATTRIB_FLATINLINE static constexpr ParseState
207 // Not checking for Left as it is required to be skipped already
208 using CharT = typename ParseState::CharT;
209 auto result = parse_state;
210 std::size_t cnt = 0;
211 std::uint32_t prime_bracket_count = 1;
212 std::uint32_t second_bracket_count = 0;
213 CharT *ptr_first = parse_state.first;
214 if( *ptr_first == PrimLeft ) {
215 ++ptr_first;
216 }
217 while( true ) {
218 switch( *ptr_first ) {
219 case '\\':
220 ++ptr_first;
221 break;
222 case '"':
223 ++ptr_first;
224 if constexpr( traits::not_same_v<typename ParseState::exec_tag_t,
227 ParseState::is_unchecked_input>( ParseState::exec_tag,
228 ptr_first, parse_state.last );
229 } else {
230 while( *ptr_first != '"' ) {
231 if( *ptr_first == '\\' ) {
232 ++ptr_first;
233 }
234 ++ptr_first;
235 }
236 }
237 break;
238 case ',':
239 if( prime_bracket_count == 1 and second_bracket_count == 0 ) {
240 ++cnt;
241 }
242 break;
243 case PrimLeft:
244 ++prime_bracket_count;
245 break;
246 case PrimRight:
247 --prime_bracket_count;
248 if( prime_bracket_count == 0 ) {
249 ++ptr_first;
250 // We include the close primary bracket in the range so that
251 // subsequent parsers have a terminator inside their range
252 result.last = ptr_first;
253 result.counter = cnt;
254 parse_state.first = ptr_first;
255 return result;
256 }
257 break;
258 case SecLeft:
259 ++second_bracket_count;
260 break;
261 case SecRight:
262 --second_bracket_count;
263 break;
264 case '#':
265 ++ptr_first;
266 while( *ptr_first != '\n' ) {
267 ++ptr_first;
268 }
269 break;
270 }
271 ++ptr_first;
272 }
273 DAW_UNREACHABLE( );
274 }
275 };
276 } // namespace DAW_JSON_VER
277} // namespace daw::json
Definition: daw_json_parse_policy_hash_comments.h:28
static constexpr DAW_ATTRIB_FLATINLINE bool is_literal_end(char c)
Definition: daw_json_parse_policy_hash_comments.h:102
static constexpr DAW_ATTRIB_FLATINLINE void trim_left_checked(ParseState &parse_state)
Definition: daw_json_parse_policy_hash_comments.h:64
static constexpr DAW_ATTRIB_FLATINLINE void move_to_next_of(ParseState &parse_state)
Definition: daw_json_parse_policy_hash_comments.h:89
static constexpr DAW_ATTRIB_FLATINLINE void trim_left_unchecked(ParseState &parse_state)
Definition: daw_json_parse_policy_hash_comments.h:74
static constexpr DAW_ATTRIB_FLATINLINE ParseState skip_bracketed_item_unchecked(ParseState &parse_state)
Definition: daw_json_parse_policy_hash_comments.h:206
static constexpr DAW_ATTRIB_FLATINLINE ParseState skip_bracketed_item_checked(ParseState &parse_state)
Definition: daw_json_parse_policy_hash_comments.h:109
static constexpr DAW_ATTRIB_FLATINLINE void move_next_member_unchecked(ParseState &parse_state)
Definition: daw_json_parse_policy_hash_comments.h:83
#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
DAW_ATTRIB_INLINE CharT * mem_skip_until_end_of_string(ExecTag const &tag, CharT *first, CharT *const last)
Definition: daw_not_const_ex_functions.h:390
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