3 #include "c4/yml/detail/dbgprint.hpp"
11 if((tag.len > 2) && (tag.str[0] ==
'!'))
13 size_t pos = tag.find(
'!', 1);
14 return pos !=
npos && pos > 1 && tag.str[1] !=
'<';
24 if(tag.begins_with(
"!<"))
26 if(tag.begins_with(
"<!"))
36 if(tag.begins_with(
"!<"))
38 if(tag.begins_with(
"<!"))
46 if(result.begins_with(
"!!"))
49 const csubstr pfx =
"<tag:yaml.org,2002:";
50 const size_t len = pfx.len + tag.len + 1;
53 memcpy(output.str , pfx.str, pfx.len);
54 memcpy(output.str + pfx.len, tag.str, tag.len);
55 output[pfx.len + tag.len] =
'>';
56 result = output.first(len);
69 if(tag.begins_with(
"!<"))
71 if(tag.begins_with(
"!!"))
73 else if(tag.begins_with(
'!'))
79 csubstr pfx =
"<tag:yaml.org,2002:";
80 csubstr pfx2 = pfx.sub(1);
81 if(tag.begins_with(pfx2))
83 tag = tag.sub(pfx2.len);
85 else if(tag.begins_with(pfx))
87 tag = tag.sub(pfx.len);
96 else if(tag ==
"omap")
98 else if(tag ==
"pairs")
100 else if(tag ==
"set")
102 else if(tag ==
"seq")
104 else if(tag ==
"binary")
106 else if(tag ==
"bool")
108 else if(tag ==
"float")
110 else if(tag ==
"int")
112 else if(tag ==
"merge")
114 else if(tag ==
"null")
116 else if(tag ==
"str")
118 else if(tag ==
"timestamp")
120 else if(tag ==
"value")
122 else if(tag ==
"yaml")
133 return {
"<tag:yaml.org,2002:map>"};
135 return {
"<tag:yaml.org,2002:omap>"};
137 return {
"<tag:yaml.org,2002:pairs>"};
139 return {
"<tag:yaml.org,2002:set>"};
141 return {
"<tag:yaml.org,2002:seq>"};
143 return {
"<tag:yaml.org,2002:binary>"};
145 return {
"<tag:yaml.org,2002:bool>"};
147 return {
"<tag:yaml.org,2002:float>"};
149 return {
"<tag:yaml.org,2002:int>"};
151 return {
"<tag:yaml.org,2002:merge>"};
153 return {
"<tag:yaml.org,2002:null>"};
155 return {
"<tag:yaml.org,2002:str>"};
157 return {
"<tag:yaml.org,2002:timestamp>"};
159 return {
"<tag:yaml.org,2002:value>"};
161 return {
"<tag:yaml.org,2002:yaml>"};
197 return {
"!!timestamp"};
211 _RYML_CHECK_BASIC(directive.begins_with(
"%TAG "));
212 directive = directive.sub(4);
213 if(!directive.begins_with(
' '))
215 directive = directive.triml(
' ');
216 size_t pos = directive.find(
' ');
219 handle = directive.first(pos);
220 directive = directive.sub(
handle.len).triml(
' ');
221 pos = directive.find(
' ');
223 directive = directive.first(pos);
233 _RYML_ASSERT_BASIC_(callbacks, tag.len >=
handle.len);
234 csubstr rest = tag.sub(
handle.len);
235 _c4dbgpf(
"%TAG: rest={}", rest);
236 if(rest.begins_with(
'<'))
238 _c4dbgpf(
"%TAG: begins with <. rest={}", rest);
239 if(C4_UNLIKELY(!rest.ends_with(
'>')))
240 _RYML_ERR_BASIC_(callbacks,
"malformed tag");
241 rest = rest.offs(1, 1);
242 if(rest.begins_with(
prefix))
244 _c4dbgpf(
"%TAG: already transformed! actual={}", rest.sub(
prefix.len));
248 size_t len =
prefix.len + rest.len;
251 size_t numpc = rest.count(
'%');
254 if(len <= output.len)
260 memcpy(1u + output.str +
prefix.len, rest.str, rest.len);
261 output.str[1u +
prefix.len + rest.len] =
'>';
266 memcpy(output.str +
prefix.len, rest.str, rest.len);
273 size_t pos = rest.find(
'%');
274 _RYML_ASSERT_BASIC_(callbacks, pos !=
npos);
276 size_t next = rest.first_not_of(
"0123456789abcdefABCDEF", pos+1);
279 _RYML_CHECK_BASIC_(callbacks, pos+1 < next);
280 _RYML_CHECK_BASIC_(callbacks, pos+1 + 2 <= next);
281 size_t delta = next - (pos+1);
283 pos = rest.find(
'%', pos+1);
284 }
while(pos !=
npos);
285 if(len <= output.len)
287 size_t prev = 0, wpos = 0;
288 auto appendstr = [&](csubstr s) { memcpy(output.str + wpos, s.str, s.len); wpos += s.len; };
289 auto appendchar = [&](
char c) { output.str[wpos++] = c; };
293 pos = rest.find(
'%');
294 _RYML_ASSERT_BASIC_(callbacks, pos !=
npos);
296 size_t next = rest.first_not_of(
"0123456789abcdefABCDEF", pos+1);
299 _RYML_CHECK_BASIC_(callbacks, pos+1 < next);
300 _RYML_CHECK_BASIC_(callbacks, pos+1 + 2 <= next);
302 if(C4_UNLIKELY(!
read_hex(rest.range(pos+1, next), &val) || val > 127))
303 _RYML_ERR_BASIC_(callbacks,
"invalid URI character");
304 appendstr(rest.range(prev, pos));
305 appendchar(
static_cast<char>(val));
307 pos = rest.find(
'%', pos+1);
308 }
while(pos !=
npos);
309 _RYML_ASSERT_BASIC_(callbacks, pos ==
npos);
310 _RYML_ASSERT_BASIC_(callbacks, prev > 0);
311 _RYML_ASSERT_BASIC_(callbacks, rest.len >= prev);
312 appendstr(rest.sub(prev));
315 _RYML_ASSERT_BASIC_(callbacks, wpos == len);
Error utilities used by ryml.
bool read_hex(csubstr s, I *v) noexcept
read an hexadecimal integer from a string.
csubstr from_tag_long(YamlTag_e tag)
bool is_custom_tag(csubstr tag)
csubstr normalize_tag_long(csubstr tag)
YamlTag_e
a bit mask for marking tags for types
csubstr normalize_tag(csubstr tag)
csubstr from_tag(YamlTag_e tag)
YamlTag_e to_tag(csubstr tag)
@ TAG_SET
!!set Unordered set of non-equal values.
@ TAG_MERGE
!!merge Specify one or more mapping to be merged with the current one.
@ TAG_INT
!!float Mathematical integers.
@ TAG_SEQ
!!seq Sequence of arbitrary values.
@ TAG_NULL
!!null Devoid of value.
@ TAG_YAML
!!yaml Specify the default value of a mapping https://yaml.org/type/yaml.html
@ TAG_TIMESTAMP
!!timestamp A point in time https://yaml.org/type/timestamp.html
@ TAG_STR
!!str A sequence of zero or more Unicode characters.
@ TAG_BOOL
!!bool Mathematical Booleans.
@ TAG_MAP
!!map Unordered set of key: value pairs without duplicates.
@ TAG_BINARY
!!binary A sequence of zero or more octets (8 bit values).
@ TAG_PAIRS
!!pairs Ordered sequence of key: value pairs allowing duplicates.
@ TAG_VALUE
!!value Specify the default value of a mapping https://yaml.org/type/value.html
@ TAG_OMAP
!!omap Ordered sequence of key: value pairs without duplicates.
@ TAG_FLOAT
!!float Floating-point approximation to real numbers.
@ npos
a null string position
(Undefined by default) Use shorter error message from checks/asserts: do not show the check condition...
A c-style callbacks class to customize behavior on errors or allocation.
bool create_from_str(csubstr directive_)
leaves next_node_id unfilled
id_type next_node_id
The next node to which this tag directive applies.
size_t transform(csubstr tag, substr output, Callbacks const &callbacks, bool with_brackets=true) const