rapidyaml  0.12.1
parse and emit YAML, and do it fast
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 More...
 
size_t wcap
 write capacity - the capacity of the subject string's buffer More...
 
size_t rpos
 read position More...
 
size_t wpos
 write position More...
 
size_t maxcap
 the max capacity needed for filtering the string. This may be larger than the final string size. More...
 
bool unfiltered_chars
 number of characters that were not added to wpos from lack of capacity More...
 

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

References src, and wcap.

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_; }

References 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_; }

References rpos, and wpos.

◆ set_at_end()

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

Definition at line 329 of file filter_processor.hpp.

References rpos, skip(), and src.

◆ 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; }

References rpos, and src.

◆ 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; }

References rpos, and src.

◆ 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  }

References maxcap, c4::yml::FilterResultExtending::reqlen, src, c4::yml::FilterResultExtending::str, unfiltered_chars, wcap, and wpos.

◆ 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); }

References src, wcap, and wpos.

◆ rem()

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

Definition at line 344 of file filter_processor.hpp.

344 { return src.sub(rpos); }

References rpos, and src.

◆ 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]; }

References rpos, and src.

◆ 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'; }

References rpos, and src.

◆ skip() [1/2]

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

Definition at line 349 of file filter_processor.hpp.

349 { ++rpos; }

References 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; }

References rpos.

◆ 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  }

References set(), and wpos.

◆ 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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

◆ 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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

◆ 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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

◆ 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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

◆ 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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

◆ 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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

◆ 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  {
497  if(!unfiltered_chars)
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  }

References maxcap, rpos, src, unfiltered_chars, wcap, and wpos.

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: