rapidyaml 0.15.2
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
c4::yml::FilterProcessorInplaceMidExtending Struct Reference

Filters in place. More...

#include <filter_processor.hpp>

Public Member Functions

 FilterProcessorInplaceMidExtending (substr src_, size_t wcap_) noexcept
void setwpos (size_t wpos_) noexcept
void setpos (size_t rpos_, size_t wpos_) noexcept
void set_at_end () noexcept
bool has_more_chars () const noexcept
bool has_more_chars (size_t maxpos) const noexcept
FilterResultExtending result () const noexcept
csubstr sofar () const noexcept
csubstr rem () const noexcept
char curr () const noexcept
char next () const noexcept
void skip () noexcept
void skip (size_t num) noexcept
void set_at (size_t pos, char c) noexcept
void set (char c) noexcept
void set (char c, size_t num) noexcept
void copy () noexcept
void copy (size_t num) noexcept
void translate_esc (char c) noexcept
void translate_esc_bulk (const char *s, size_t nw, size_t nr) noexcept
void translate_esc_extending (const char *s, size_t nw, size_t nr) noexcept

Public Attributes

substr src
 the subject string
size_t wcap
 write capacity - the capacity of the subject string's buffer
size_t rpos
 read position
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.
bool unfiltered_chars
 number of characters that were not added to wpos from lack of capacity

Detailed Description

Filters in place.

The result may be larger than the source, and extending may happen anywhere. As a result some characters may be left unfiltered when there is no slack in the buffer and the write-position would overlap the read-position. Consequently, it's possible for characters to be left unfiltered. In YAML, this happens only with double-quoted strings, and only with a small number of escape sequences such as \L which is substituted by three bytes. These escape sequences cause a call to translate_esc_extending() which is the only entry point to this unfiltered situation.

See also
FilterProcessorInplaceEndExtending

Definition at line 301 of file filter_processor.hpp.

Constructor & Destructor Documentation

◆ FilterProcessorInplaceMidExtending()

c4::yml::FilterProcessorInplaceMidExtending::FilterProcessorInplaceMidExtending ( substr src_,
size_t wcap_ )
inlinenoexcept

Definition at line 310 of file filter_processor.hpp.

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 }
size_t maxcap
the max capacity needed for filtering the string. This may be larger than the final string size.
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

Member Function Documentation

◆ setwpos()

void c4::yml::FilterProcessorInplaceMidExtending::setwpos ( size_t wpos_)
inlinenoexcept

Definition at line 321 of file filter_processor.hpp.

321{ wpos = wpos_; }

◆ setpos()

void c4::yml::FilterProcessorInplaceMidExtending::setpos ( size_t rpos_,
size_t wpos_ )
inlinenoexcept

Definition at line 322 of file filter_processor.hpp.

322{ rpos = rpos_; wpos = wpos_; }

◆ set_at_end()

void c4::yml::FilterProcessorInplaceMidExtending::set_at_end ( )
inlinenoexcept

Definition at line 323 of file filter_processor.hpp.

◆ has_more_chars() [1/2]

bool c4::yml::FilterProcessorInplaceMidExtending::has_more_chars ( ) const
inlinenoexcept

Definition at line 325 of file filter_processor.hpp.

325{ return rpos < src.len; }

◆ has_more_chars() [2/2]

bool c4::yml::FilterProcessorInplaceMidExtending::has_more_chars ( size_t maxpos) const
inlinenoexcept

Definition at line 326 of file filter_processor.hpp.

326{ RYML_ASSERT_BASIC_(maxpos <= src.len); return rpos < maxpos; }

◆ result()

FilterResultExtending c4::yml::FilterProcessorInplaceMidExtending::result ( ) const
inlinenoexcept

Definition at line 328 of file filter_processor.hpp.

329 {
330 _c4dbgip("inplace: wpos={} wcap={} unfiltered={} maxcap={}", this->wpos, this->wcap, this->unfiltered_chars, this->maxcap);
331 FilterResultExtending ret;
332 ret.str.str = (wpos <= wcap && !unfiltered_chars) ? src.str : nullptr;
333 ret.str.len = wpos;
334 ret.reqlen = maxcap;
335 return ret;
336 }

◆ sofar()

csubstr c4::yml::FilterProcessorInplaceMidExtending::sofar ( ) const
inlinenoexcept

Definition at line 337 of file filter_processor.hpp.

337{ return csubstr(src.str, wpos <= wcap ? wpos : wcap); }
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356

◆ rem()

csubstr c4::yml::FilterProcessorInplaceMidExtending::rem ( ) const
inlinenoexcept

Definition at line 338 of file filter_processor.hpp.

338{ return src.sub(rpos); }

◆ curr()

char c4::yml::FilterProcessorInplaceMidExtending::curr ( ) const
inlinenoexcept

Definition at line 340 of file filter_processor.hpp.

340{ RYML_ASSERT_BASIC_(rpos < src.len); return src[rpos]; }

◆ next()

char c4::yml::FilterProcessorInplaceMidExtending::next ( ) const
inlinenoexcept

Definition at line 341 of file filter_processor.hpp.

341{ return rpos+1 < src.len ? src[rpos+1] : '\0'; }

◆ skip() [1/2]

void c4::yml::FilterProcessorInplaceMidExtending::skip ( )
inlinenoexcept

Definition at line 343 of file filter_processor.hpp.

343{ ++rpos; }

Referenced by set_at_end().

◆ skip() [2/2]

void c4::yml::FilterProcessorInplaceMidExtending::skip ( size_t num)
inlinenoexcept

Definition at line 344 of file filter_processor.hpp.

344{ rpos += num; }

◆ set_at()

void c4::yml::FilterProcessorInplaceMidExtending::set_at ( size_t pos,
char c )
inlinenoexcept

Definition at line 346 of file filter_processor.hpp.

347 {
348 RYML_ASSERT_BASIC_(pos < wpos);
349 const size_t save = wpos;
350 wpos = pos;
351 set(c);
352 wpos = save;
353 }

◆ set() [1/2]

void c4::yml::FilterProcessorInplaceMidExtending::set ( char c)
inlinenoexcept

Definition at line 354 of file filter_processor.hpp.

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 }

Referenced by set_at().

◆ set() [2/2]

void c4::yml::FilterProcessorInplaceMidExtending::set ( char c,
size_t num )
inlinenoexcept

Definition at line 369 of file filter_processor.hpp.

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 }

◆ copy() [1/2]

void c4::yml::FilterProcessorInplaceMidExtending::copy ( )
inlinenoexcept

Definition at line 386 of file filter_processor.hpp.

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 }

◆ copy() [2/2]

void c4::yml::FilterProcessorInplaceMidExtending::copy ( size_t num)
inlinenoexcept

Definition at line 403 of file filter_processor.hpp.

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 }

◆ translate_esc()

void c4::yml::FilterProcessorInplaceMidExtending::translate_esc ( char c)
inlinenoexcept

Definition at line 427 of file filter_processor.hpp.

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 }

◆ translate_esc_bulk()

void c4::yml::FilterProcessorInplaceMidExtending::translate_esc_bulk ( const char * s,
size_t nw,
size_t nr )
inlinenoexcept

Definition at line 445 of file filter_processor.hpp.

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 }

◆ translate_esc_extending()

void c4::yml::FilterProcessorInplaceMidExtending::translate_esc_extending ( const char * s,
size_t nw,
size_t nr )
inlinenoexcept

Definition at line 467 of file filter_processor.hpp.

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 }

Member Data Documentation

◆ src

substr c4::yml::FilterProcessorInplaceMidExtending::src

◆ wcap

size_t c4::yml::FilterProcessorInplaceMidExtending::wcap

write capacity - the capacity of the subject string's buffer

Definition at line 304 of file filter_processor.hpp.

Referenced by FilterProcessorInplaceMidExtending(), copy(), copy(), result(), set(), set(), sofar(), translate_esc(), translate_esc_bulk(), and translate_esc_extending().

◆ rpos

size_t c4::yml::FilterProcessorInplaceMidExtending::rpos

◆ wpos

size_t c4::yml::FilterProcessorInplaceMidExtending::wpos

◆ maxcap

size_t c4::yml::FilterProcessorInplaceMidExtending::maxcap

the max capacity needed for filtering the string. This may be larger than the final string size.

Definition at line 307 of file filter_processor.hpp.

Referenced by copy(), copy(), result(), set(), set(), translate_esc(), translate_esc_bulk(), and translate_esc_extending().

◆ unfiltered_chars

bool c4::yml::FilterProcessorInplaceMidExtending::unfiltered_chars

number of characters that were not added to wpos from lack of capacity

Definition at line 308 of file filter_processor.hpp.

Referenced by copy(), copy(), result(), set(), set(), translate_esc(), translate_esc_bulk(), and translate_esc_extending().


The documentation for this struct was generated from the following file:
  • /home/docs/checkouts/readthedocs.org/user_builds/rapidyaml/checkouts/latest/src/c4/yml/filter_processor.hpp