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);
bool read_hex(csubstr s, I *v) noexcept
read an hexadecimal integer from a string.