1 #ifndef C4_YML_FILTER_PROCESSOR_HPP_
2 #define C4_YML_FILTER_PROCESSOR_HPP_
4 #ifndef C4_YML_ERROR_HPP_
10 #include "c4/yml/detail/dbgprint.hpp"
28 C4_ALWAYS_INLINE
bool valid() const noexcept {
return str.
str !=
nullptr; }
37 C4_ALWAYS_INLINE
bool valid() const noexcept {
return str.
str !=
nullptr; }
61 RYML_ASSERT_BASIC_(!dst.
overlaps(src));
64 C4_ALWAYS_INLINE
void setwpos(
size_t wpos_) noexcept { wpos = wpos_; }
65 C4_ALWAYS_INLINE
void setpos(
size_t rpos_,
size_t wpos_) noexcept { rpos = rpos_; wpos = wpos_; }
69 C4_ALWAYS_INLINE
bool has_more_chars(
size_t maxpos)
const noexcept { RYML_ASSERT_BASIC_(maxpos <= src.
len);
return rpos < maxpos; }
81 C4_ALWAYS_INLINE
char curr() const noexcept { RYML_ASSERT_BASIC_(rpos < src.
len);
return src[
rpos]; }
82 C4_ALWAYS_INLINE
char next() const noexcept {
return rpos+1 < src.
len ? src[rpos+1] :
'\0'; }
85 C4_ALWAYS_INLINE
void skip() noexcept { ++
rpos; }
86 C4_ALWAYS_INLINE
void skip(
size_t num) noexcept { rpos += num; }
88 C4_ALWAYS_INLINE
void set_at(
size_t pos,
char c) noexcept
90 RYML_ASSERT_BASIC_(pos < wpos);
93 C4_ALWAYS_INLINE
void set(
char c) noexcept
99 C4_ALWAYS_INLINE
void set(
char c,
size_t num) noexcept
101 RYML_ASSERT_BASIC_(num > 0);
102 if(wpos + num <= dst.
len)
103 memset(dst.
str + wpos, c, num);
107 C4_ALWAYS_INLINE
void copy() noexcept
109 RYML_ASSERT_BASIC_(rpos < src.
len);
115 C4_ALWAYS_INLINE
void copy(
size_t num) noexcept
117 RYML_ASSERT_BASIC_(num);
118 RYML_ASSERT_BASIC_(rpos+num <= src.
len);
119 if(wpos + num <= dst.
len)
120 memcpy(dst.
str + wpos, src.
str + rpos, num);
134 RYML_ASSERT_BASIC_(nw > 0);
135 RYML_ASSERT_BASIC_(nr > 0);
136 RYML_ASSERT_BASIC_(rpos+nr <= src.
len);
137 if(wpos+nw <= dst.
len)
138 memcpy(dst.
str + wpos, s, nw);
154 #if defined(RYML_DBG) && 0
155 #define _c4dbgip(...) _c4dbgpf(__VA_ARGS__)
157 #define _c4dbgip(...)
179 RYML_ASSERT_BASIC_(wcap >= src.
len);
182 C4_ALWAYS_INLINE
void setwpos(
size_t wpos_) noexcept { wpos = wpos_; }
183 C4_ALWAYS_INLINE
void setpos(
size_t rpos_,
size_t wpos_) noexcept { rpos = rpos_; wpos = wpos_; }
187 C4_ALWAYS_INLINE
bool has_more_chars(
size_t maxpos)
const noexcept { RYML_ASSERT_BASIC_(maxpos <= src.
len);
return rpos < maxpos; }
191 _c4dbgip(
"inplace: wpos={} wcap={} small={}", wpos, wcap, wpos > rpos);
200 C4_ALWAYS_INLINE
char curr() const noexcept { RYML_ASSERT_BASIC_(rpos < src.
len);
return src[
rpos]; }
201 C4_ALWAYS_INLINE
char next() const noexcept {
return rpos+1 < src.
len ? src[rpos+1] :
'\0'; }
204 C4_ALWAYS_INLINE
void skip(
size_t num) noexcept { rpos += num; }
208 RYML_ASSERT_BASIC_(pos < wpos);
209 const size_t save =
wpos;
220 void set(
char c,
size_t num) noexcept
222 RYML_ASSERT_BASIC_(num);
223 if(wpos + num <= wcap)
224 memset(src.
str + wpos, c, num);
230 RYML_ASSERT_BASIC_(wpos <= rpos);
231 RYML_ASSERT_BASIC_(rpos < src.
len);
239 RYML_ASSERT_BASIC_(num);
240 RYML_ASSERT_BASIC_(rpos+num <= src.
len);
241 RYML_ASSERT_BASIC_(wpos <= rpos);
242 if(wpos + num <= wcap)
244 if(wpos + num <= rpos)
245 memcpy(src.
str + wpos, src.
str + rpos, num);
247 memmove(src.
str + wpos, src.
str + rpos, num);
255 RYML_ASSERT_BASIC_(rpos + 2 <= src.
len);
256 RYML_ASSERT_BASIC_(wpos <= rpos);
265 RYML_ASSERT_BASIC_(nw > 0);
266 RYML_ASSERT_BASIC_(nr > 0);
267 RYML_ASSERT_BASIC_(nw <= nr + 1u);
268 RYML_ASSERT_BASIC_(rpos+nr <= src.
len);
269 RYML_ASSERT_BASIC_(wpos <= rpos);
270 const size_t wpos_next = wpos + nw;
271 const size_t rpos_next = rpos + nr + 1u;
272 RYML_ASSERT_BASIC_(wpos_next <= rpos_next);
273 if(wpos_next <= wcap)
274 memcpy(src.
str + wpos, s, nw);
318 RYML_ASSERT_BASIC_(wcap >= src.
len);
321 C4_ALWAYS_INLINE
void setwpos(
size_t wpos_) noexcept { wpos = wpos_; }
322 C4_ALWAYS_INLINE
void setpos(
size_t rpos_,
size_t wpos_) noexcept { rpos = rpos_; wpos = wpos_; }
326 C4_ALWAYS_INLINE
bool has_more_chars(
size_t maxpos)
const noexcept { RYML_ASSERT_BASIC_(maxpos <= src.
len);
return rpos < maxpos; }
330 _c4dbgip(
"inplace: wpos={} wcap={} unfiltered={} maxcap={}", this->wpos, this->wcap, this->unfiltered_chars, this->maxcap);
340 C4_ALWAYS_INLINE
char curr() const noexcept { RYML_ASSERT_BASIC_(rpos < src.
len);
return src[
rpos]; }
341 C4_ALWAYS_INLINE
char next() const noexcept {
return rpos+1 < src.
len ? src[rpos+1] :
'\0'; }
344 C4_ALWAYS_INLINE
void skip(
size_t num) noexcept { rpos += num; }
348 RYML_ASSERT_BASIC_(pos < wpos);
349 const size_t save =
wpos;
358 if((wpos <= rpos) && !unfiltered_chars)
363 _c4dbgip(
"inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars,
true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
364 unfiltered_chars =
true;
367 maxcap = wpos > maxcap ? wpos :
maxcap;
369 void set(
char c,
size_t num) noexcept
371 RYML_ASSERT_BASIC_(num);
372 if(wpos + num <= wcap)
374 if((wpos <= rpos) && !unfiltered_chars)
375 memset(src.
str + wpos, c, num);
379 _c4dbgip(
"inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars,
true, maxcap, (wpos+num > maxcap ? wpos+num : maxcap));
380 unfiltered_chars =
true;
383 maxcap = wpos > maxcap ? wpos :
maxcap;
388 RYML_ASSERT_BASIC_(rpos < src.
len);
391 if((wpos < rpos) && !unfiltered_chars)
396 _c4dbgip(
"inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars,
true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
397 unfiltered_chars =
true;
401 maxcap = wpos > maxcap ? wpos :
maxcap;
405 RYML_ASSERT_BASIC_(num);
406 RYML_ASSERT_BASIC_(rpos+num <= src.
len);
407 if(wpos + num <= wcap)
409 if((wpos < rpos) && !unfiltered_chars)
411 if(wpos + num <= rpos)
412 memcpy(src.
str + wpos, src.
str + rpos, num);
414 memmove(src.
str + wpos, src.
str + rpos, num);
419 _c4dbgip(
"inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars,
true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap);
420 unfiltered_chars =
true;
424 maxcap = wpos > maxcap ? wpos :
maxcap;
429 RYML_ASSERT_BASIC_(rpos + 2 <= src.
len);
432 if((wpos <= rpos) && !unfiltered_chars)
437 _c4dbgip(
"inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars,
true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
438 unfiltered_chars =
true;
442 maxcap = wpos > maxcap ? wpos :
maxcap;
447 RYML_ASSERT_BASIC_(nw > 0);
448 RYML_ASSERT_BASIC_(nr > 0);
449 RYML_ASSERT_BASIC_(nr+1u >= nw);
450 const size_t wpos_next = wpos + nw;
451 const size_t rpos_next = rpos + nr + 1u;
452 if(wpos_next <= wcap)
454 if((wpos <= rpos) && !unfiltered_chars)
455 memcpy(src.
str + wpos, s, nw);
459 _c4dbgip(
"inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars,
true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap);
460 unfiltered_chars =
true;
464 maxcap = wpos > maxcap ? wpos :
maxcap;
469 RYML_ASSERT_BASIC_(nw > 0);
470 RYML_ASSERT_BASIC_(nr > 0);
471 RYML_ASSERT_BASIC_(rpos+nr <= src.
len);
472 const size_t wpos_next = wpos + nw;
473 const size_t rpos_next = rpos + nr + 1u;
474 if(wpos_next <= rpos_next)
476 if((wpos_next <= wcap) && !unfiltered_chars)
477 memcpy(src.
str + wpos, s, nw);
480 maxcap = wpos > maxcap ? wpos :
maxcap;
484 const size_t excess = wpos_next - rpos_next;
485 RYML_ASSERT_BASIC_(wpos_next > rpos_next);
486 if(src.
len + excess <= wcap)
488 RYML_ASSERT_BASIC_(rpos+nr+excess <= src.
len);
489 if(wpos_next <= wcap)
491 if(!unfiltered_chars)
493 memmove(src.
str + wpos_next, src.
str + rpos_next, src.
len - rpos_next);
494 memcpy(src.
str + wpos, s, nw);
502 _c4dbgip(
"inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars,
true);
503 unfiltered_chars =
true;
508 maxcap = wpos > maxcap ? wpos :
maxcap;
513 RYML_ASSERT_BASIC_(rpos_next <= src.
len);
514 const size_t required_size = wpos_next + (src.
len - rpos_next);
515 _c4dbgip(
"inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars,
true, maxcap, required_size > maxcap ? required_size : maxcap);
516 RYML_ASSERT_BASIC_(required_size > wcap);
517 unfiltered_chars =
true;
518 maxcap = required_size > maxcap ? required_size :
maxcap;
void set_at(size_t pos, char c) noexcept
void translate_esc_extending(const char *s, size_t nw, size_t nr) noexcept
FilterResultExtending result() const noexcept
bool overlaps(ro_substr const that) const noexcept
true if there is overlap of at least one element between that and *this
csubstr rem() const noexcept
size_t wcap
write capacity - the capacity of the subject string's buffer
void copy(size_t num) noexcept
void translate_esc_extending(const char *s, size_t nw, size_t nr) noexcept
void translate_esc_bulk(const char *s, size_t nw, size_t nr) noexcept
void translate_esc_bulk(const char *s, size_t nw, size_t nr) noexcept
FilterResult result() const noexcept
void skip(size_t num) noexcept
void set(char c, size_t num) noexcept
FilterResult result() const noexcept
void set(char c) noexcept
void set_at(size_t pos, char c) noexcept
C * str
a restricted pointer to the first character of the substring
size_t required_len() const noexcept
void setpos(size_t rpos_, size_t wpos_) noexcept
bool skipped_chars() const noexcept
void set(char c, size_t num) noexcept
void set(char c, size_t num) noexcept
void setpos(size_t rpos_, size_t wpos_) noexcept
void set(char c) noexcept
void set_at_end() noexcept
bool has_more_chars(size_t maxpos) const noexcept
size_t required_len() const noexcept
void set(char c) noexcept
FilterProcessorInplaceEndExtending(substr src_, size_t wcap_) noexcept
bool has_more_chars() const noexcept
FilterProcessorInplaceMidExtending(substr src_, size_t wcap_) noexcept
size_t wpos
write position
size_t maxcap
the max capacity needed for filtering the string. This may be larger than the final string size...
void setwpos(size_t wpos_) noexcept
char curr() const noexcept
void copy(size_t num) noexcept
FilterProcessorSrcDst(csubstr src_, substr dst_) noexcept
substr src
the subject string
char curr() const noexcept
void translate_esc(char c) noexcept
void copy(size_t num) noexcept
basic_substring sub(size_t first) const noexcept
return [first,len[
Lightweight generic type-safe wrappers for converting individual values to/from strings.
csubstr sofar() const noexcept
void set_at(size_t pos, char c) noexcept
basic_substring< const char > csubstr
an immutable string view
void setpos(size_t rpos_, size_t wpos_) noexcept
size_t wpos
write position
char next() const noexcept
void setwpos(size_t wpos_) noexcept
void set_at_end() noexcept
char curr() const noexcept
size_t len
the length of the substring
Error utilities used by ryml.
bool unfiltered_chars
number of characters that were not added to wpos from lack of capacity
csubstr sofar() const noexcept
size_t wcap
write capacity - the capacity of the subject string's buffer
Filters an input string into a different output string.
void translate_esc_bulk(const char *s, size_t nw, size_t nr) noexcept
void set_at_end() noexcept
bool valid() const noexcept
void translate_esc(char c) noexcept
bool has_more_chars(size_t maxpos) const noexcept
void skip(size_t num) noexcept
csubstr rem() const noexcept
Result for filtering a scalar which not fit in the intended memory.
bool has_more_chars() const noexcept
bool has_more_chars(size_t maxpos) const noexcept
Result for filtering a scalar which not fit in the intended memory.
char next() const noexcept
void setwpos(size_t wpos_) noexcept
void skip(size_t num) noexcept
void translate_esc(char c) noexcept
substr src
the subject string
bool has_more_chars() const noexcept
csubstr rem() const noexcept
size_t wpos
write position
csubstr sofar() const noexcept
bool valid() const noexcept
char next() const noexcept
void translate_esc_extending(const char *s, size_t nw, size_t nr) noexcept