rapidyaml 0.14.0
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
FilterProcessorInplaceMidExtending

Definition at line 307 of file filter_processor.hpp.

Constructor & Destructor Documentation

◆ FilterProcessorInplaceMidExtending()

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

Definition at line 316 of file filter_processor.hpp.

317 : src(src_)
318 , wcap(wcap_)
319 , rpos(0)
320 , wpos(0)
321 , maxcap(src.len)
322 , unfiltered_chars(false)
323 {
324 _RYML_ASSERT_BASIC(wcap >= src.len);
325 }
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 327 of file filter_processor.hpp.

327{ wpos = wpos_; }

◆ setpos()

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

Definition at line 328 of file filter_processor.hpp.

328{ rpos = rpos_; wpos = wpos_; }

◆ set_at_end()

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

Definition at line 329 of file filter_processor.hpp.

◆ has_more_chars() [1/2]

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

Definition at line 331 of file filter_processor.hpp.

331{ return rpos < src.len; }

◆ has_more_chars() [2/2]

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

Definition at line 332 of file filter_processor.hpp.

332{ _RYML_ASSERT_BASIC(maxpos <= src.len); return rpos < maxpos; }

◆ result()

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

Definition at line 334 of file filter_processor.hpp.

335 {
336 _c4dbgip("inplace: wpos={} wcap={} unfiltered={} maxcap={}", this->wpos, this->wcap, this->unfiltered_chars, this->maxcap);
337 FilterResultExtending ret;
338 ret.str.str = (wpos <= wcap && !unfiltered_chars) ? src.str : nullptr;
339 ret.str.len = wpos;
340 ret.reqlen = maxcap;
341 return ret;
342 }

◆ sofar()

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

Definition at line 343 of file filter_processor.hpp.

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

◆ rem()

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

Definition at line 344 of file filter_processor.hpp.

344{ return src.sub(rpos); }

◆ curr()

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

Definition at line 346 of file filter_processor.hpp.

346{ _RYML_ASSERT_BASIC(rpos < src.len); return src[rpos]; }

◆ next()

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

Definition at line 347 of file filter_processor.hpp.

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

◆ skip() [1/2]

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

Definition at line 349 of file filter_processor.hpp.

349{ ++rpos; }

◆ skip() [2/2]

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

Definition at line 350 of file filter_processor.hpp.

350{ rpos += num; }

◆ set_at()

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

Definition at line 352 of file filter_processor.hpp.

353 {
354 _RYML_ASSERT_BASIC(pos < wpos);
355 const size_t save = wpos;
356 wpos = pos;
357 set(c);
358 wpos = save;
359 }

◆ set() [1/2]

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

Definition at line 360 of file filter_processor.hpp.

361 {
362 if(wpos < wcap) // respect write-capacity
363 {
364 if((wpos <= rpos) && !unfiltered_chars)
365 src.str[wpos] = c;
366 }
367 else
368 {
369 _c4dbgip("inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
370 unfiltered_chars = true;
371 }
372 ++wpos;
373 maxcap = wpos > maxcap ? wpos : maxcap;
374 }

◆ set() [2/2]

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

Definition at line 375 of file filter_processor.hpp.

376 {
377 _RYML_ASSERT_BASIC(num);
378 if(wpos + num <= wcap) // respect write-capacity
379 {
380 if((wpos <= rpos) && !unfiltered_chars)
381 memset(src.str + wpos, c, num);
382 }
383 else
384 {
385 _c4dbgip("inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+num > maxcap ? wpos+num : maxcap));
386 unfiltered_chars = true;
387 }
388 wpos += num;
389 maxcap = wpos > maxcap ? wpos : maxcap;
390 }

◆ copy() [1/2]

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

Definition at line 392 of file filter_processor.hpp.

393 {
394 _RYML_ASSERT_BASIC(rpos < src.len);
395 if(wpos < wcap) // respect write-capacity
396 {
397 if((wpos < rpos) && !unfiltered_chars) // write only if wpos is behind rpos
398 src.str[wpos] = src.str[rpos];
399 }
400 else
401 {
402 _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));
403 unfiltered_chars = true;
404 }
405 ++rpos;
406 ++wpos;
407 maxcap = wpos > maxcap ? wpos : maxcap;
408 }

◆ copy() [2/2]

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

Definition at line 409 of file filter_processor.hpp.

410 {
411 _RYML_ASSERT_BASIC(num);
412 _RYML_ASSERT_BASIC(rpos+num <= src.len);
413 if(wpos + num <= wcap) // respect write-capacity
414 {
415 if((wpos < rpos) && !unfiltered_chars) // write only if wpos is behind rpos
416 {
417 if(wpos + num <= rpos) // there is no overlap
418 memcpy(src.str + wpos, src.str + rpos, num);
419 else // there is overlap
420 memmove(src.str + wpos, src.str + rpos, num);
421 }
422 }
423 else
424 {
425 _c4dbgip("inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars, true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap);
426 unfiltered_chars = true;
427 }
428 rpos += num;
429 wpos += num;
430 maxcap = wpos > maxcap ? wpos : maxcap;
431 }

◆ translate_esc()

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

Definition at line 433 of file filter_processor.hpp.

434 {
435 _RYML_ASSERT_BASIC(rpos + 2 <= src.len);
436 if(wpos < wcap) // respect write-capacity
437 {
438 if((wpos <= rpos) && !unfiltered_chars)
439 src.str[wpos] = c;
440 }
441 else
442 {
443 _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
444 unfiltered_chars = true;
445 }
446 rpos += 2;
447 ++wpos;
448 maxcap = wpos > maxcap ? wpos : maxcap;
449 }

◆ translate_esc_bulk()

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

Definition at line 451 of file filter_processor.hpp.

452 {
453 _RYML_ASSERT_BASIC(nw > 0);
454 _RYML_ASSERT_BASIC(nr > 0);
455 _RYML_ASSERT_BASIC(nr+1u >= nw);
456 const size_t wpos_next = wpos + nw;
457 const size_t rpos_next = rpos + nr + 1u; // add 1u to account for the escape character
458 if(wpos_next <= wcap) // respect write-capacity
459 {
460 if((wpos <= rpos) && !unfiltered_chars) // write only if wpos is behind rpos
461 memcpy(src.str + wpos, s, nw);
462 }
463 else
464 {
465 _c4dbgip("inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars, true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap);
466 unfiltered_chars = true;
467 }
468 rpos = rpos_next;
469 wpos = wpos_next;
470 maxcap = wpos > maxcap ? wpos : maxcap;
471 }

◆ translate_esc_extending()

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

Definition at line 473 of file filter_processor.hpp.

474 {
475 _RYML_ASSERT_BASIC(nw > 0);
476 _RYML_ASSERT_BASIC(nr > 0);
477 _RYML_ASSERT_BASIC(rpos+nr <= src.len);
478 const size_t wpos_next = wpos + nw;
479 const size_t rpos_next = rpos + nr + 1u; // add 1u to account for the escape character
480 if(wpos_next <= rpos_next) // read and write do not overlap. just do a vanilla copy.
481 {
482 if((wpos_next <= wcap) && !unfiltered_chars)
483 memcpy(src.str + wpos, s, nw);
484 rpos = rpos_next;
485 wpos = wpos_next;
486 maxcap = wpos > maxcap ? wpos : maxcap;
487 }
488 else // there is overlap. move the (to-be-read) string to the right.
489 {
490 const size_t excess = wpos_next - rpos_next;
491 _RYML_ASSERT_BASIC(wpos_next > rpos_next);
492 if(src.len + excess <= wcap) // ensure we do not go past the end
493 {
494 _RYML_ASSERT_BASIC(rpos+nr+excess <= src.len);
495 if(wpos_next <= wcap)
496 {
498 {
499 memmove(src.str + wpos_next, src.str + rpos_next, src.len - rpos_next);
500 memcpy(src.str + wpos, s, nw);
501 }
502 rpos = wpos_next; // wpos, not rpos
503 }
504 else
505 {
506 rpos = rpos_next;
507 //const size_t unw = nw > (nr + 1u) ? nw - (nr + 1u) : 0;
508 _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true);
509 unfiltered_chars = true;
510 }
511 wpos = wpos_next;
512 // extend the string up to capacity
513 src.len += excess;
514 maxcap = wpos > maxcap ? wpos : maxcap;
515 }
516 else
517 {
518 //const size_t unw = nw > (nr + 1u) ? nw - (nr + 1u) : 0;
519 _RYML_ASSERT_BASIC(rpos_next <= src.len);
520 const size_t required_size = wpos_next + (src.len - rpos_next);
521 _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, required_size > maxcap ? required_size : maxcap);
522 _RYML_ASSERT_BASIC(required_size > wcap);
523 unfiltered_chars = true;
524 maxcap = required_size > maxcap ? required_size : maxcap;
525 wpos = wpos_next;
526 rpos = rpos_next;
527 }
528 }
529 }

Member Data Documentation

◆ src

substr c4::yml::FilterProcessorInplaceMidExtending::src

the subject string

Definition at line 309 of file filter_processor.hpp.

◆ wcap

size_t c4::yml::FilterProcessorInplaceMidExtending::wcap

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

Definition at line 310 of file filter_processor.hpp.

◆ rpos

size_t c4::yml::FilterProcessorInplaceMidExtending::rpos

read position

Definition at line 311 of file filter_processor.hpp.

◆ wpos

size_t c4::yml::FilterProcessorInplaceMidExtending::wpos

write position

Definition at line 312 of file filter_processor.hpp.

◆ 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 313 of file filter_processor.hpp.

◆ unfiltered_chars

bool c4::yml::FilterProcessorInplaceMidExtending::unfiltered_chars

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

Definition at line 314 of file filter_processor.hpp.


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