rapidyaml 0.15.2
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
filter_processor.hpp
Go to the documentation of this file.
1#ifndef C4_YML_FILTER_PROCESSOR_HPP_
2#define C4_YML_FILTER_PROCESSOR_HPP_
3
4#ifndef C4_YML_ERROR_HPP_
5#include "c4/yml/error.hpp"
6#endif
7
8#ifdef RYML_DBG
9#include "c4/charconv.hpp"
10#include "c4/yml/detail/dbgprint.hpp"
11#endif
12
13namespace c4 {
14namespace yml {
15
16/** @addtogroup doc_scalar_filter */
17/** @{ */
18
19
20//-----------------------------------------------------------------------------
21//-----------------------------------------------------------------------------
22//-----------------------------------------------------------------------------
23
24/** Result for filtering a scalar which not fit in the intended
25 * memory. */
27{
28 C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
29 C4_ALWAYS_INLINE size_t required_len() const noexcept { return str.len; }
30 C4_ALWAYS_INLINE csubstr get() const { RYML_ASSERT_BASIC_(valid()); return str; }
32};
33/** Result for filtering a scalar which not fit in the intended
34 * memory. */
36{
37 C4_ALWAYS_INLINE bool valid() const noexcept { return str.str != nullptr; }
38 C4_ALWAYS_INLINE size_t required_len() const noexcept { return reqlen; }
39 C4_ALWAYS_INLINE csubstr get() const { RYML_ASSERT_BASIC_(valid()); return str; }
41 size_t reqlen;
42};
43
44
45//-----------------------------------------------------------------------------
46
47/** Filters an input string into a different output string */
49{
52 size_t rpos; ///< read position
53 size_t wpos; ///< write position
54
55 C4_ALWAYS_INLINE FilterProcessorSrcDst(csubstr src_, substr dst_) noexcept
56 : src(src_)
57 , dst(dst_)
58 , rpos(0)
59 , wpos(0)
60 {
61 RYML_ASSERT_BASIC_(!dst.overlaps(src));
62 }
63
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_; }
66 C4_ALWAYS_INLINE void set_at_end() noexcept { skip(src.len - rpos); }
67
68 C4_ALWAYS_INLINE bool has_more_chars() const noexcept { return rpos < src.len; }
69 C4_ALWAYS_INLINE bool has_more_chars(size_t maxpos) const noexcept { RYML_ASSERT_BASIC_(maxpos <= src.len); return rpos < maxpos; }
70
71 C4_ALWAYS_INLINE csubstr rem() const noexcept { return src.sub(rpos); }
72 C4_ALWAYS_INLINE csubstr sofar() const noexcept { return csubstr(dst.str, wpos <= dst.len ? wpos : dst.len); }
73 C4_ALWAYS_INLINE FilterResult result() const noexcept
74 {
75 FilterResult ret;
76 ret.str.str = wpos <= dst.len ? dst.str : nullptr;
77 ret.str.len = wpos;
78 return ret;
79 }
80
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'; }
83 C4_ALWAYS_INLINE bool skipped_chars() const noexcept { return wpos != rpos; }
84
85 C4_ALWAYS_INLINE void skip() noexcept { ++rpos; }
86 C4_ALWAYS_INLINE void skip(size_t num) noexcept { rpos += num; }
87
88 C4_ALWAYS_INLINE void set_at(size_t pos, char c) noexcept // NOLINT(readability-make-member-function-const)
89 {
90 RYML_ASSERT_BASIC_(pos < wpos);
91 dst.str[pos] = c;
92 }
93 C4_ALWAYS_INLINE void set(char c) noexcept
94 {
95 if(wpos < dst.len)
96 dst.str[wpos] = c;
97 ++wpos;
98 }
99 C4_ALWAYS_INLINE void set(char c, size_t num) noexcept
100 {
101 RYML_ASSERT_BASIC_(num > 0);
102 if(wpos + num <= dst.len)
103 memset(dst.str + wpos, c, num);
104 wpos += num;
105 }
106
107 C4_ALWAYS_INLINE void copy() noexcept
108 {
109 RYML_ASSERT_BASIC_(rpos < src.len);
110 if(wpos < dst.len)
111 dst.str[wpos] = src.str[rpos];
112 ++wpos;
113 ++rpos;
114 }
115 C4_ALWAYS_INLINE void copy(size_t num) noexcept
116 {
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);
121 wpos += num;
122 rpos += num;
123 }
124
125 C4_ALWAYS_INLINE void translate_esc(char c) noexcept
126 {
127 if(wpos < dst.len)
128 dst.str[wpos] = c;
129 ++wpos;
130 rpos += 2;
131 }
132 C4_ALWAYS_INLINE void translate_esc_bulk(const char *C4_RESTRICT s, size_t nw, size_t nr) noexcept
133 {
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);
139 wpos += nw;
140 rpos += 1 + nr;
141 }
142 C4_ALWAYS_INLINE void translate_esc_extending(const char *C4_RESTRICT s, size_t nw, size_t nr) noexcept
143 {
144 translate_esc_bulk(s, nw, nr);
145 }
146};
147
148
149//-----------------------------------------------------------------------------
150// filter in place
151
152// debugging scaffold
153/** @cond dev */
154#if defined(RYML_DBG) && 0
155#define _c4dbgip(...) _c4dbgpf(__VA_ARGS__)
156#else
157#define _c4dbgip(...)
158#endif
159/** @endcond */
160
161/** Filters in place. While the result may be larger than the source,
162 * any extending happens only at the end of the string. Consequently,
163 * it's impossible for characters to be left unfiltered.
164 *
165 * @see FilterProcessorInplaceMidExtending */
167{
168 substr src; ///< the subject string
169 size_t wcap; ///< write capacity - the capacity of the subject string's buffer
170 size_t rpos; ///< read position
171 size_t wpos; ///< write position
172
173 C4_ALWAYS_INLINE FilterProcessorInplaceEndExtending(substr src_, size_t wcap_) noexcept
174 : src(src_)
175 , wcap(wcap_)
176 , rpos(0)
177 , wpos(0)
178 {
179 RYML_ASSERT_BASIC_(wcap >= src.len);
180 }
181
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_; }
184 C4_ALWAYS_INLINE void set_at_end() noexcept { skip(src.len - rpos); }
185
186 C4_ALWAYS_INLINE bool has_more_chars() const noexcept { return rpos < src.len; }
187 C4_ALWAYS_INLINE bool has_more_chars(size_t maxpos) const noexcept { RYML_ASSERT_BASIC_(maxpos <= src.len); return rpos < maxpos; }
188
189 C4_ALWAYS_INLINE FilterResult result() const noexcept
190 {
191 _c4dbgip("inplace: wpos={} wcap={} small={}", wpos, wcap, wpos > rpos);
192 FilterResult ret;
193 ret.str.str = (wpos <= wcap) ? src.str : nullptr;
194 ret.str.len = wpos;
195 return ret;
196 }
197 C4_ALWAYS_INLINE csubstr sofar() const noexcept { return csubstr(src.str, wpos <= wcap ? wpos : wcap); }
198 C4_ALWAYS_INLINE csubstr rem() const noexcept { return src.sub(rpos); }
199
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'; }
202
203 C4_ALWAYS_INLINE void skip() noexcept { ++rpos; }
204 C4_ALWAYS_INLINE void skip(size_t num) noexcept { rpos += num; }
205
206 void set_at(size_t pos, char c) noexcept
207 {
208 RYML_ASSERT_BASIC_(pos < wpos);
209 const size_t save = wpos;
210 wpos = pos;
211 set(c);
212 wpos = save;
213 }
214 void set(char c) noexcept
215 {
216 if(wpos < wcap) // respect write-capacity
217 src.str[wpos] = c;
218 ++wpos;
219 }
220 void set(char c, size_t num) noexcept
221 {
222 RYML_ASSERT_BASIC_(num);
223 if(wpos + num <= wcap) // respect write-capacity
224 memset(src.str + wpos, c, num);
225 wpos += num;
226 }
227
228 void copy() noexcept
229 {
230 RYML_ASSERT_BASIC_(wpos <= rpos);
231 RYML_ASSERT_BASIC_(rpos < src.len);
232 if(wpos < wcap) // respect write-capacity
233 src.str[wpos] = src.str[rpos];
234 ++rpos;
235 ++wpos;
236 }
237 void copy(size_t num) noexcept
238 {
239 RYML_ASSERT_BASIC_(num);
240 RYML_ASSERT_BASIC_(rpos+num <= src.len);
241 RYML_ASSERT_BASIC_(wpos <= rpos);
242 if(wpos + num <= wcap) // respect write-capacity
243 {
244 if(wpos + num <= rpos) // there is no overlap
245 memcpy(src.str + wpos, src.str + rpos, num);
246 else // there is overlap
247 memmove(src.str + wpos, src.str + rpos, num);
248 }
249 rpos += num;
250 wpos += num;
251 }
252
253 void translate_esc(char c) noexcept
254 {
255 RYML_ASSERT_BASIC_(rpos + 2 <= src.len);
256 RYML_ASSERT_BASIC_(wpos <= rpos);
257 if(wpos < wcap) // respect write-capacity
258 src.str[wpos] = c;
259 rpos += 2; // add 1u to account for the escape character
260 ++wpos;
261 }
262
263 void translate_esc_bulk(const char *C4_RESTRICT s, size_t nw, size_t nr) noexcept
264 {
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; // add 1u to account for the escape character
272 RYML_ASSERT_BASIC_(wpos_next <= rpos_next);
273 if(wpos_next <= wcap)
274 memcpy(src.str + wpos, s, nw);
275 rpos = rpos_next;
276 wpos = wpos_next;
277 }
278
279 C4_ALWAYS_INLINE void translate_esc_extending(const char *C4_RESTRICT s, size_t nw, size_t nr) noexcept
280 {
281 translate_esc_bulk(s, nw, nr);
282 }
283};
284
285
286//-----------------------------------------------------------------------------
287//-----------------------------------------------------------------------------
288//-----------------------------------------------------------------------------
289
290/** Filters in place. The result may be larger than the source, and
291 * extending may happen anywhere. As a result some characters may be
292 * left unfiltered when there is no slack in the buffer and the
293 * write-position would overlap the read-position. Consequently, it's
294 * possible for characters to be left unfiltered. In YAML, this
295 * happens only with double-quoted strings, and only with a small
296 * number of escape sequences such as `\L` which is substituted by three
297 * bytes. These escape sequences cause a call to translate_esc_extending()
298 * which is the only entry point to this unfiltered situation.
299 *
300 * @see FilterProcessorInplaceEndExtending */
302{
303 substr src; ///< the subject string
304 size_t wcap; ///< write capacity - the capacity of the subject string's buffer
305 size_t rpos; ///< read position
306 size_t wpos; ///< write position
307 size_t maxcap; ///< the max capacity needed for filtering the string. This may be larger than the final string size.
308 bool unfiltered_chars; ///< number of characters that were not added to wpos from lack of capacity
309
310 C4_ALWAYS_INLINE FilterProcessorInplaceMidExtending(substr src_, size_t wcap_) noexcept
311 : src(src_)
312 , wcap(wcap_)
313 , rpos(0)
314 , wpos(0)
315 , maxcap(src.len)
316 , unfiltered_chars(false)
317 {
318 RYML_ASSERT_BASIC_(wcap >= src.len);
319 }
320
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_; }
323 C4_ALWAYS_INLINE void set_at_end() noexcept { skip(src.len - rpos); }
324
325 C4_ALWAYS_INLINE bool has_more_chars() const noexcept { return rpos < src.len; }
326 C4_ALWAYS_INLINE bool has_more_chars(size_t maxpos) const noexcept { RYML_ASSERT_BASIC_(maxpos <= src.len); return rpos < maxpos; }
327
328 C4_ALWAYS_INLINE FilterResultExtending result() const noexcept
329 {
330 _c4dbgip("inplace: wpos={} wcap={} unfiltered={} maxcap={}", this->wpos, this->wcap, this->unfiltered_chars, this->maxcap);
332 ret.str.str = (wpos <= wcap && !unfiltered_chars) ? src.str : nullptr;
333 ret.str.len = wpos;
334 ret.reqlen = maxcap;
335 return ret;
336 }
337 C4_ALWAYS_INLINE csubstr sofar() const noexcept { return csubstr(src.str, wpos <= wcap ? wpos : wcap); }
338 C4_ALWAYS_INLINE csubstr rem() const noexcept { return src.sub(rpos); }
339
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'; }
342
343 C4_ALWAYS_INLINE void skip() noexcept { ++rpos; }
344 C4_ALWAYS_INLINE void skip(size_t num) noexcept { rpos += num; }
345
346 void set_at(size_t pos, char c) noexcept
347 {
348 RYML_ASSERT_BASIC_(pos < wpos);
349 const size_t save = wpos;
350 wpos = pos;
351 set(c);
352 wpos = save;
353 }
354 void set(char c) noexcept
355 {
356 if(wpos < wcap) // respect write-capacity
357 {
358 if((wpos <= rpos) && !unfiltered_chars)
359 src.str[wpos] = c;
360 }
361 else
362 {
363 _c4dbgip("inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
364 unfiltered_chars = true;
365 }
366 ++wpos;
367 maxcap = wpos > maxcap ? wpos : maxcap;
368 }
369 void set(char c, size_t num) noexcept
370 {
371 RYML_ASSERT_BASIC_(num);
372 if(wpos + num <= wcap) // respect write-capacity
373 {
374 if((wpos <= rpos) && !unfiltered_chars)
375 memset(src.str + wpos, c, num);
376 }
377 else
378 {
379 _c4dbgip("inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+num > maxcap ? wpos+num : maxcap));
380 unfiltered_chars = true;
381 }
382 wpos += num;
383 maxcap = wpos > maxcap ? wpos : maxcap;
384 }
385
386 void copy() noexcept
387 {
388 RYML_ASSERT_BASIC_(rpos < src.len);
389 if(wpos < wcap) // respect write-capacity
390 {
391 if((wpos < rpos) && !unfiltered_chars) // write only if wpos is behind rpos
392 src.str[wpos] = src.str[rpos];
393 }
394 else
395 {
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;
398 }
399 ++rpos;
400 ++wpos;
401 maxcap = wpos > maxcap ? wpos : maxcap;
402 }
403 void copy(size_t num) noexcept
404 {
405 RYML_ASSERT_BASIC_(num);
406 RYML_ASSERT_BASIC_(rpos+num <= src.len);
407 if(wpos + num <= wcap) // respect write-capacity
408 {
409 if((wpos < rpos) && !unfiltered_chars) // write only if wpos is behind rpos
410 {
411 if(wpos + num <= rpos) // there is no overlap
412 memcpy(src.str + wpos, src.str + rpos, num);
413 else // there is overlap
414 memmove(src.str + wpos, src.str + rpos, num);
415 }
416 }
417 else
418 {
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;
421 }
422 rpos += num;
423 wpos += num;
424 maxcap = wpos > maxcap ? wpos : maxcap;
425 }
426
427 void translate_esc(char c) noexcept
428 {
429 RYML_ASSERT_BASIC_(rpos + 2 <= src.len);
430 if(wpos < wcap) // respect write-capacity
431 {
432 if((wpos <= rpos) && !unfiltered_chars)
433 src.str[wpos] = c;
434 }
435 else
436 {
437 _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
438 unfiltered_chars = true;
439 }
440 rpos += 2;
441 ++wpos;
442 maxcap = wpos > maxcap ? wpos : maxcap;
443 }
444
445 C4_NO_INLINE void translate_esc_bulk(const char *C4_RESTRICT s, size_t nw, size_t nr) noexcept
446 {
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; // add 1u to account for the escape character
452 if(wpos_next <= wcap) // respect write-capacity
453 {
454 if((wpos <= rpos) && !unfiltered_chars) // write only if wpos is behind rpos
455 memcpy(src.str + wpos, s, nw);
456 }
457 else
458 {
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;
461 }
462 rpos = rpos_next;
463 wpos = wpos_next;
464 maxcap = wpos > maxcap ? wpos : maxcap;
465 }
466
467 C4_NO_INLINE void translate_esc_extending(const char *C4_RESTRICT s, size_t nw, size_t nr) noexcept
468 {
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; // add 1u to account for the escape character
474 if(wpos_next <= rpos_next) // read and write do not overlap. just do a vanilla copy.
475 {
476 if((wpos_next <= wcap) && !unfiltered_chars)
477 memcpy(src.str + wpos, s, nw);
478 rpos = rpos_next;
479 wpos = wpos_next;
480 maxcap = wpos > maxcap ? wpos : maxcap;
481 }
482 else // there is overlap. move the (to-be-read) string to the right.
483 {
484 const size_t excess = wpos_next - rpos_next;
485 RYML_ASSERT_BASIC_(wpos_next > rpos_next);
486 if(src.len + excess <= wcap) // ensure we do not go past the end
487 {
488 RYML_ASSERT_BASIC_(rpos+nr+excess <= src.len);
489 if(wpos_next <= wcap)
490 {
492 {
493 memmove(src.str + wpos_next, src.str + rpos_next, src.len - rpos_next);
494 memcpy(src.str + wpos, s, nw);
495 }
496 rpos = wpos_next; // wpos, not rpos
497 }
498 else
499 {
500 rpos = rpos_next;
501 //const size_t unw = nw > (nr + 1u) ? nw - (nr + 1u) : 0;
502 _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true);
503 unfiltered_chars = true;
504 }
505 wpos = wpos_next;
506 // extend the string up to capacity
507 src.len += excess;
508 maxcap = wpos > maxcap ? wpos : maxcap;
509 }
510 else
511 {
512 //const size_t unw = nw > (nr + 1u) ? nw - (nr + 1u) : 0;
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;
519 wpos = wpos_next;
520 rpos = rpos_next;
521 }
522 }
523 }
524};
525
526#undef _c4dbgip
527
528
529/** @} */
530
531} // namespace yml
532} // namespace c4
533
534#endif /* C4_YML_FILTER_PROCESSOR_HPP_ */
Lightweight generic type-safe wrappers for converting individual values to/from strings.
Error utilities used by ryml.
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2355
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356
size_t len
the length of the substring
Definition substr.hpp:218
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216
FilterProcessorInplaceEndExtending(substr src_, size_t wcap_) noexcept
size_t wcap
write capacity - the capacity of the subject string's buffer
void setpos(size_t rpos_, size_t wpos_) noexcept
void translate_esc_extending(const char *s, size_t nw, size_t nr) noexcept
void set(char c, size_t num) noexcept
void translate_esc_bulk(const char *s, size_t nw, size_t nr) noexcept
bool has_more_chars(size_t maxpos) const noexcept
void set_at(size_t pos, char c) noexcept
FilterResultExtending result() const 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
FilterProcessorInplaceMidExtending(substr src_, size_t wcap_) noexcept
size_t maxcap
the max capacity needed for filtering the string. This may be larger than the final string size.
bool has_more_chars(size_t maxpos) const noexcept
void setpos(size_t rpos_, size_t wpos_) noexcept
void set_at(size_t pos, char c) noexcept
size_t wcap
write capacity - the capacity of the subject string's buffer
bool unfiltered_chars
number of characters that were not added to wpos from lack of capacity
void set(char c, size_t num) noexcept
void translate_esc_bulk(const char *s, size_t nw, size_t nr) noexcept
void set_at(size_t pos, char c) noexcept
void setpos(size_t rpos_, size_t wpos_) noexcept
void copy(size_t num) noexcept
csubstr rem() const noexcept
FilterResult result() const noexcept
void skip(size_t num) noexcept
FilterProcessorSrcDst(csubstr src_, substr dst_) noexcept
void setwpos(size_t wpos_) noexcept
bool has_more_chars() const noexcept
void translate_esc(char c) noexcept
bool skipped_chars() const noexcept
csubstr sofar() const noexcept
void translate_esc_extending(const char *s, size_t nw, size_t nr) noexcept
void set(char c, size_t num) noexcept
bool has_more_chars(size_t maxpos) const noexcept
Result for filtering a scalar which not fit in the intended memory.
size_t required_len() const noexcept
Result for filtering a scalar which not fit in the intended memory.
size_t required_len() const noexcept
bool valid() const noexcept