rapidyaml  0.7.0
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 279 of file filter_processor.hpp.

Constructor & Destructor Documentation

◆ FilterProcessorInplaceMidExtending()

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

Definition at line 288 of file filter_processor.hpp.

289  : src(src_)
290  , wcap(wcap_)
291  , rpos(0)
292  , wpos(0)
293  , maxcap(src.len)
294  , unfiltered_chars(false)
295  {
296  RYML_ASSERT(wcap >= src.len);
297  }
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 299 of file filter_processor.hpp.

299 { wpos = wpos_; }

References wpos.

◆ setpos()

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

Definition at line 300 of file filter_processor.hpp.

300 { rpos = rpos_; wpos = wpos_; }

References rpos, and wpos.

◆ set_at_end()

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

Definition at line 301 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 303 of file filter_processor.hpp.

303 { 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 304 of file filter_processor.hpp.

304 { RYML_ASSERT(maxpos <= src.len); return rpos < maxpos; }

References rpos, and src.

◆ result()

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

Definition at line 306 of file filter_processor.hpp.

307  {
308  _c4dbgip("inplace: wpos={} wcap={} unfiltered={} maxcap={}", this->wpos, this->wcap, this->unfiltered_chars, this->maxcap);
309  FilterResultExtending ret;
310  ret.str.str = (wpos <= wcap && !unfiltered_chars) ? src.str : nullptr;
311  ret.str.len = wpos;
312  ret.reqlen = maxcap;
313  return ret;
314  }

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

◆ sofar()

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

Definition at line 315 of file filter_processor.hpp.

315 { return csubstr(src.str, wpos <= wcap ? wpos : wcap); }

References src, wcap, and wpos.

◆ rem()

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

Definition at line 316 of file filter_processor.hpp.

316 { return src.sub(rpos); }

References rpos, and src.

◆ curr()

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

Definition at line 318 of file filter_processor.hpp.

318 { RYML_ASSERT(rpos < src.len); return src[rpos]; }

References rpos, and src.

◆ next()

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

Definition at line 319 of file filter_processor.hpp.

319 { 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 321 of file filter_processor.hpp.

321 { ++rpos; }

References rpos.

Referenced by set_at_end().

◆ skip() [2/2]

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

Definition at line 322 of file filter_processor.hpp.

322 { rpos += num; }

References rpos.

◆ set_at()

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

Definition at line 324 of file filter_processor.hpp.

325  {
326  RYML_ASSERT(pos < wpos);
327  const size_t save = wpos;
328  wpos = pos;
329  set(c);
330  wpos = save;
331  }

References set(), and wpos.

◆ set() [1/2]

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

Definition at line 332 of file filter_processor.hpp.

333  {
334  if(wpos < wcap) // respect write-capacity
335  {
336  if((wpos <= rpos) && !unfiltered_chars)
337  src.str[wpos] = c;
338  }
339  else
340  {
341  _c4dbgip("inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
342  unfiltered_chars = true;
343  }
344  ++wpos;
345  maxcap = wpos > maxcap ? wpos : maxcap;
346  }

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

Referenced by set_at().

◆ set() [2/2]

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

Definition at line 347 of file filter_processor.hpp.

348  {
349  RYML_ASSERT(num);
350  if(wpos + num <= wcap) // respect write-capacity
351  {
352  if((wpos <= rpos) && !unfiltered_chars)
353  memset(src.str + wpos, c, num);
354  }
355  else
356  {
357  _c4dbgip("inplace: add unwritten {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+num > maxcap ? wpos+num : maxcap));
358  unfiltered_chars = true;
359  }
360  wpos += num;
361  maxcap = wpos > maxcap ? wpos : maxcap;
362  }

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

◆ copy() [1/2]

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

Definition at line 364 of file filter_processor.hpp.

365  {
366  RYML_ASSERT(rpos < src.len);
367  if(wpos < wcap) // respect write-capacity
368  {
369  if((wpos < rpos) && !unfiltered_chars) // write only if wpos is behind rpos
370  src.str[wpos] = src.str[rpos];
371  }
372  else
373  {
374  _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));
375  unfiltered_chars = true;
376  }
377  ++rpos;
378  ++wpos;
379  maxcap = wpos > maxcap ? wpos : maxcap;
380  }

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

◆ copy() [2/2]

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

Definition at line 381 of file filter_processor.hpp.

382  {
383  RYML_ASSERT(num);
384  RYML_ASSERT(rpos+num <= src.len);
385  if(wpos + num <= wcap) // respect write-capacity
386  {
387  if((wpos < rpos) && !unfiltered_chars) // write only if wpos is behind rpos
388  {
389  if(wpos + num <= rpos) // there is no overlap
390  memcpy(src.str + wpos, src.str + rpos, num);
391  else // there is overlap
392  memmove(src.str + wpos, src.str + rpos, num);
393  }
394  }
395  else
396  {
397  _c4dbgip("inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars, true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap);
398  unfiltered_chars = true;
399  }
400  rpos += num;
401  wpos += num;
402  maxcap = wpos > maxcap ? wpos : maxcap;
403  }

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

◆ translate_esc()

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

Definition at line 405 of file filter_processor.hpp.

406  {
407  RYML_ASSERT(rpos + 2 <= src.len);
408  if(wpos < wcap) // respect write-capacity
409  {
410  if((wpos <= rpos) && !unfiltered_chars)
411  src.str[wpos] = c;
412  }
413  else
414  {
415  _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, (wpos+1u > maxcap ? wpos+1u : maxcap));
416  unfiltered_chars = true;
417  }
418  rpos += 2;
419  ++wpos;
420  maxcap = wpos > maxcap ? wpos : maxcap;
421  }

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

424  {
425  RYML_ASSERT(nw > 0);
426  RYML_ASSERT(nr > 0);
427  RYML_ASSERT(nr+1u >= nw);
428  const size_t wpos_next = wpos + nw;
429  const size_t rpos_next = rpos + nr + 1u; // add 1u to account for the escape character
430  if(wpos_next <= wcap) // respect write-capacity
431  {
432  if((wpos <= rpos) && !unfiltered_chars) // write only if wpos is behind rpos
433  memcpy(src.str + wpos, s, nw);
434  }
435  else
436  {
437  _c4dbgip("inplace: add unwritten {}->{} (wpos={}!=rpos={})={} (wpos={}<wcap={}) maxcap={}->{}!", unfiltered_chars, true, wpos, rpos, wpos!=rpos, wpos, wcap, wpos<wcap);
438  unfiltered_chars = true;
439  }
440  rpos = rpos_next;
441  wpos = wpos_next;
442  maxcap = wpos > maxcap ? wpos : maxcap;
443  }

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

446  {
447  RYML_ASSERT(nw > 0);
448  RYML_ASSERT(nr > 0);
449  RYML_ASSERT(rpos+nr <= src.len);
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 <= rpos_next) // read and write do not overlap. just do a vanilla copy.
453  {
454  if((wpos_next <= wcap) && !unfiltered_chars)
455  memcpy(src.str + wpos, s, nw);
456  rpos = rpos_next;
457  wpos = wpos_next;
458  maxcap = wpos > maxcap ? wpos : maxcap;
459  }
460  else // there is overlap. move the (to-be-read) string to the right.
461  {
462  const size_t excess = wpos_next - rpos_next;
463  RYML_ASSERT(wpos_next > rpos_next);
464  if(src.len + excess <= wcap) // ensure we do not go past the end
465  {
466  RYML_ASSERT(rpos+nr+excess <= src.len);
467  if(wpos_next <= wcap)
468  {
469  if(!unfiltered_chars)
470  {
471  memmove(src.str + wpos_next, src.str + rpos_next, src.len - rpos_next);
472  memcpy(src.str + wpos, s, nw);
473  }
474  rpos = wpos_next; // wpos, not rpos
475  }
476  else
477  {
478  rpos = rpos_next;
479  //const size_t unw = nw > (nr + 1u) ? nw - (nr + 1u) : 0;
480  _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true);
481  unfiltered_chars = true;
482  }
483  wpos = wpos_next;
484  // extend the string up to capacity
485  src.len += excess;
486  maxcap = wpos > maxcap ? wpos : maxcap;
487  }
488  else
489  {
490  //const size_t unw = nw > (nr + 1u) ? nw - (nr + 1u) : 0;
491  RYML_ASSERT(rpos_next <= src.len);
492  const size_t required_size = wpos_next + (src.len - rpos_next);
493  _c4dbgip("inplace: add unfiltered {}->{} maxcap={}->{}!", unfiltered_chars, true, maxcap, required_size > maxcap ? required_size : maxcap);
494  RYML_ASSERT(required_size > wcap);
495  unfiltered_chars = true;
496  maxcap = required_size > maxcap ? required_size : maxcap;
497  wpos = wpos_next;
498  rpos = rpos_next;
499  }
500  }
501  }

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

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

Referenced by FilterProcessorInplaceMidExtending(), copy(), result(), 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 285 of file filter_processor.hpp.

Referenced by copy(), result(), 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 286 of file filter_processor.hpp.

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


The documentation for this struct was generated from the following file: