rapidyaml  0.9.0
parse and emit YAML, and do it fast
c4::yml::TagDirective Struct Reference

#include <tag.hpp>

Public Member Functions

bool create_from_str (csubstr directive_)
 leaves next_node_id unfilled More...
 
bool create_from_str (csubstr directive_, Tree *tree)
 
size_t transform (csubstr tag, substr output, Callbacks const &callbacks) const
 

Public Attributes

csubstr handle
 Eg. More...
 
csubstr prefix
 Eg. More...
 
id_type next_node_id
 The next node to which this tag directive applies. More...
 

Detailed Description

Definition at line 57 of file tag.hpp.

Member Function Documentation

◆ create_from_str() [1/2]

bool c4::yml::TagDirective::create_from_str ( csubstr  directive_)

leaves next_node_id unfilled

Definition at line 204 of file tag.cpp.

205 {
206  csubstr directive = directive_;
207  directive = directive.sub(4);
208  if(!directive.begins_with(' '))
209  return false;
210  directive = directive.triml(' ');
211  size_t pos = directive.find(' ');
212  if(pos == npos)
213  return false;
214  handle = directive.first(pos);
215  directive = directive.sub(handle.len).triml(' ');
216  pos = directive.find(' ');
217  if(pos != npos)
218  directive = directive.first(pos);
219  prefix = directive;
220  next_node_id = NONE;
221  _c4dbgpf("%TAG: handle={} prefix={}", handle, prefix);
222  return true;
223 }
@ npos
a null string position
Definition: common.hpp:267
@ NONE
an index to none
Definition: common.hpp:260
csubstr handle
Eg.
Definition: tag.hpp:60
id_type next_node_id
The next node to which this tag directive applies.
Definition: tag.hpp:64
csubstr prefix
Eg.
Definition: tag.hpp:62

References handle, next_node_id, c4::yml::NONE, c4::yml::npos, and prefix.

Referenced by c4::yml::Tree::add_tag_directive(), and create_from_str().

◆ create_from_str() [2/2]

bool c4::yml::TagDirective::create_from_str ( csubstr  directive_,
Tree tree 
)

Definition at line 225 of file tag.cpp.

226 {
227  _RYML_CB_CHECK(tree->callbacks(), directive_.begins_with("%TAG "));
228  if(!create_from_str(directive_))
229  {
230  _RYML_CB_ERR(tree->callbacks(), "invalid tag directive");
231  }
232  next_node_id = tree->size();
233  if(!tree->empty())
234  {
235  const id_type prev = tree->size() - 1;
236  if(tree->is_root(prev) && tree->type(prev) != NOTYPE && !tree->is_stream(prev))
237  ++next_node_id;
238  }
239  _c4dbgpf("%TAG: handle={} prefix={} next_node={}", handle, prefix, next_node_id);
240  return true;
241 }
@ NOTYPE
no node type or style is set
Definition: node_type.hpp:32
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
Definition: common.hpp:253
bool create_from_str(csubstr directive_)
leaves next_node_id unfilled
Definition: tag.cpp:204

References c4::yml::Tree::callbacks(), create_from_str(), c4::yml::Tree::empty(), handle, c4::yml::Tree::is_root(), c4::yml::Tree::is_stream(), next_node_id, c4::yml::NOTYPE, prefix, c4::yml::Tree::size(), and c4::yml::Tree::type().

◆ transform()

size_t c4::yml::TagDirective::transform ( csubstr  tag,
substr  output,
Callbacks const &  callbacks 
) const

Definition at line 243 of file tag.cpp.

244 {
245  _c4dbgpf("%TAG: handle={} prefix={} next_node={}. tag={}", handle, prefix, next_node_id, tag);
246  _RYML_CB_ASSERT(callbacks, tag.len >= handle.len);
247  csubstr rest = tag.sub(handle.len);
248  _c4dbgpf("%TAG: rest={}", rest);
249  if(rest.begins_with('<'))
250  {
251  _c4dbgpf("%TAG: begins with <. rest={}", rest);
252  if(C4_UNLIKELY(!rest.ends_with('>')))
253  _RYML_CB_ERR(callbacks, "malformed tag");
254  rest = rest.offs(1, 1);
255  if(rest.begins_with(prefix))
256  {
257  _c4dbgpf("%TAG: already transformed! actual={}", rest.sub(prefix.len));
258  return 0; // return 0 to signal that the tag is local and cannot be resolved
259  }
260  }
261  size_t len = 1u + prefix.len + rest.len + 1u;
262  size_t numpc = rest.count('%');
263  if(numpc == 0)
264  {
265  if(len <= output.len)
266  {
267  output.str[0] = '<';
268  memcpy(1u + output.str, prefix.str, prefix.len);
269  memcpy(1u + output.str + prefix.len, rest.str, rest.len);
270  output.str[1u + prefix.len + rest.len] = '>';
271  }
272  }
273  else
274  {
275  // need to decode URI % sequences
276  size_t pos = rest.find('%');
277  _RYML_CB_ASSERT(callbacks, pos != npos);
278  do {
279  size_t next = rest.first_not_of("0123456789abcdefABCDEF", pos+1);
280  if(next == npos)
281  next = rest.len;
282  _RYML_CB_CHECK(callbacks, pos+1 < next);
283  _RYML_CB_CHECK(callbacks, pos+1 + 2 <= next);
284  size_t delta = next - (pos+1);
285  len -= delta;
286  pos = rest.find('%', pos+1);
287  } while(pos != npos);
288  if(len <= output.len)
289  {
290  size_t prev = 0, wpos = 0;
291  auto appendstr = [&](csubstr s) { memcpy(output.str + wpos, s.str, s.len); wpos += s.len; };
292  auto appendchar = [&](char c) { output.str[wpos++] = c; };
293  appendchar('<');
294  appendstr(prefix);
295  pos = rest.find('%');
296  _RYML_CB_ASSERT(callbacks, pos != npos);
297  do {
298  size_t next = rest.first_not_of("0123456789abcdefABCDEF", pos+1);
299  if(next == npos)
300  next = rest.len;
301  _RYML_CB_CHECK(callbacks, pos+1 < next);
302  _RYML_CB_CHECK(callbacks, pos+1 + 2 <= next);
303  uint8_t val;
304  if(C4_UNLIKELY(!read_hex(rest.range(pos+1, next), &val) || val > 127))
305  _RYML_CB_ERR(callbacks, "invalid URI character");
306  appendstr(rest.range(prev, pos));
307  appendchar(static_cast<char>(val));
308  prev = next;
309  pos = rest.find('%', pos+1);
310  } while(pos != npos);
311  _RYML_CB_ASSERT(callbacks, pos == npos);
312  _RYML_CB_ASSERT(callbacks, prev > 0);
313  _RYML_CB_ASSERT(callbacks, rest.len >= prev);
314  appendstr(rest.sub(prev));
315  appendchar('>');
316  _RYML_CB_ASSERT(callbacks, wpos == len);
317  }
318  }
319  return len;
320 }
bool read_hex(csubstr s, I *v) noexcept
read an hexadecimal integer from a string.
Definition: charconv.hpp:890

References handle, next_node_id, c4::yml::npos, prefix, and c4::read_hex().

Referenced by c4::yml::Tree::resolve_tag().

Member Data Documentation

◆ handle

csubstr c4::yml::TagDirective::handle

Eg.

!e!

in

TAG !e! tag:example.com,2000:app/

Definition at line 60 of file tag.hpp.

Referenced by c4::yml::Tree::add_tag_directive(), create_from_str(), and transform().

◆ prefix

csubstr c4::yml::TagDirective::prefix

Eg.

tag:example.com,2000:app/

in

TAG !e! tag:example.com,2000:app/

Definition at line 62 of file tag.hpp.

Referenced by c4::yml::Tree::add_tag_directive(), create_from_str(), and transform().

◆ next_node_id

id_type c4::yml::TagDirective::next_node_id

The next node to which this tag directive applies.

Definition at line 64 of file tag.hpp.

Referenced by create_from_str(), and transform().


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