rapidyaml  0.10.0
parse and emit YAML, and do it fast
scalar.cpp
Go to the documentation of this file.
1 #ifdef RYML_SINGLE_HEADER_INTS
2  #ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
3  #include <ryml_ints.hpp>
4  #endif
5 #elif defined(RYML_SINGLE_HEADER)
6  #ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
7  #include <ryml_all.hpp>
8  #endif
9 #endif
10 
11 #ifndef _C4_YML_EXTRA_SCALAR_HPP_
12 #include <c4/yml/extra/scalar.hpp>
13 #endif
14 
15 
16 namespace c4 {
17 namespace yml {
18 namespace extra {
19 
20 size_t escape_scalar(substr buffer, csubstr val)
21 {
22  size_t pos = 0;
23  #define _append(repl) \
24  do { \
25  if(repl.len && (pos + repl.len <= buffer.len)) \
26  memcpy(buffer.str + pos, repl.str, repl.len); \
27  pos += repl.len; \
28  } while(0)
29  #define _c4flush_use_instead(i, repl, skip) \
30  do { \
31  _append(val.range(prev, i)); \
32  _append(csubstr(repl)); \
33  prev = i + skip; \
34  } \
35  while(0)
36  uint8_t const* C4_RESTRICT s = reinterpret_cast<uint8_t const*>(val.str);
37  size_t prev = 0;
38  for(size_t i = 0; i < val.len; ++i)
39  {
40  switch(s[i])
41  {
42  case UINT8_C(0x0a): // \n
43  _c4flush_use_instead(i, "\\n", 1); break;
44  case UINT8_C(0x5c): // '\\'
45  _c4flush_use_instead(i, "\\\\", 1); break;
46  case UINT8_C(0x09): // \t
47  _c4flush_use_instead(i, "\\t", 1); break;
48  case UINT8_C(0x0d): // \r
49  _c4flush_use_instead(i, "\\r", 1); break;
50  case UINT8_C(0x00): // \0
51  _c4flush_use_instead(i, "\\0", 1); break;
52  case UINT8_C(0x0c): // \f (form feed)
53  _c4flush_use_instead(i, "\\f", 1); break;
54  case UINT8_C(0x08): // \b (backspace)
55  _c4flush_use_instead(i, "\\b", 1); break;
56  case UINT8_C(0x07): // \a (bell)
57  _c4flush_use_instead(i, "\\a", 1); break;
58  case UINT8_C(0x0b): // \v (vertical tab)
59  _c4flush_use_instead(i, "\\v", 1); break;
60  case UINT8_C(0x1b): // \e (escape)
61  _c4flush_use_instead(i, "\\e", 1); break;
62  case UINT8_C(0xc2):
63  if(i+1 < val.len)
64  {
65  const uint8_t np1 = s[i+1];
66  if(np1 == UINT8_C(0xa0))
67  _c4flush_use_instead(i, "\\_", 2);
68  else if(np1 == UINT8_C(0x85))
69  _c4flush_use_instead(i, "\\N", 2);
70  }
71  break;
72  case UINT8_C(0xe2):
73  if(i+2 < val.len)
74  {
75  if(s[i+1] == UINT8_C(0x80))
76  {
77  if(s[i+2] == UINT8_C(0xa8))
78  _c4flush_use_instead(i, "\\L", 3);
79  else if(s[i+2] == UINT8_C(0xa9))
80  _c4flush_use_instead(i, "\\P", 3);
81  }
82  }
83  break;
84  }
85  }
86  // flush the rest
87  _append(val.sub(prev));
88  #undef _c4flush_use_instead
89  #undef _append
90  return pos;
91 }
92 
93 } // namespace extra
94 } // namespace yml
95 } // namespace c4
size_t escape_scalar(substr buffer, csubstr val)
Definition: scalar.cpp:20
Definition: common.cpp:12
#define _append(repl)
#define _c4flush_use_instead(i, repl, skip)