JReadString
Description
Read a quoted string, handling escape sequences.
\uXXXX escapes are recognised but not decoded – the parser logs a warning and skips the six bytes so the surrounding string still parses. See the top-of-file v1 scope note.
Parameters
| Name | Direction | Description |
|---|---|---|
si |
in | Current reading position in input string |
str |
out | Output string to store parsed result |
Success
Returns StrIter advanced past closing quote
Failure
Returns original StrIter on error (invalid escape, missing quote, etc.)
Usage example (Cross-references)
Usage examples (Cross-references)
- In
JSON.h:250:
do { \
Str UNPL(my_str) = StrInit(); \
si = JReadString((si), &UNPL(my_str)); \
(str) = UNPL(my_str); \
} while (0)- In
JSON.h:273:
if (!StrCmp(&key, (k))) { \
Str UNPL(my_str) = StrInit(); \
si = JReadString((si), &UNPL(my_str)); \
(str) = UNPL(my_str); \
} \
- In
JSON.h:573:
\
/* key start */ \
UNPL(read_si) = JReadString(si, &key); \
if (StrIterIndex(&UNPL(read_si)) == StrIterIndex(&si)) { \
LOG_ERROR("Failed to read string key in object. Invalid JSON"); \
- In
JSON.c:57:
// key start
read_si = JReadString(si, &key);
if (StrIterIndex(&read_si) == StrIterIndex(&si)) {
LOG_ERROR("Failed to read string key in object. Invalid JSON");- In
JSON.c:181:
}
StrIter JReadString(StrIter si, Str *str) {
if (!StrIterRemainingLength(&si)) {
return si;- In
JSON.c:638:
DefaultAllocator scratch = DefaultAllocatorInit();
Str s = StrInit(&scratch);
si = JReadString(si, &s);
StrDeinit(&s);
DefaultAllocatorDeinit(&scratch); } \
Str key = StrInit(&alloc); \
UNPL(read_si) = JReadString(si, &key); \
if (StrIterIndex(&UNPL(read_si)) == StrIterIndex(&si)) { \
LOG_ERROR("Failed to read string key in object. Invalid JSON"); \
do { \
Str UNPL(my_str) = StrInit(&alloc); \
si = JReadString((si), &UNPL(my_str)); \
(str) = UNPL(my_str); \
} while (0) if (!StrCmp(&key, (k))) { \
Str UNPL(my_str) = StrInit(&alloc); \
si = JReadString((si), &UNPL(my_str)); \
(str) = UNPL(my_str); \
} \
StrIter si = StrIterFromStr(j);
Str out = StrInit(&alloc);
StrIter r = JReadString(si, &out);
// Truncated escape -> failure -> iterator unchanged.
if (StrIterIndex(&r) != StrIterIndex(&si)) { // Truncated escape -> failure -> iterator unchanged.
if (StrIterIndex(&r) != StrIterIndex(&si)) {
WriteFmtLn("[DEBUG] JReadString advanced on truncated escape case {}", i);
success = false;
} StrIter si = StrIterFromStr(j);
Str out = StrInit(&alloc);
StrIter r = JReadString(si, &out);
if (StrIterIndex(&r) != StrIterIndex(&si)) {
WriteFmtLn("[DEBUG] JReadString accepted a complete \\u escape (should reject): idx={}", StrIterIndex(&r)); StrIter r = JReadString(si, &out);
if (StrIterIndex(&r) != StrIterIndex(&si)) {
WriteFmtLn("[DEBUG] JReadString accepted a complete \\u escape (should reject): idx={}", StrIterIndex(&r));
success = false;
} }
if (StrLen(&out) != 0) {
WriteFmtLn("[DEBUG] JReadString left partial output on rejected \\u escape: len={}", StrLen(&out));
success = false;
} StrIter si = StrIterFromStr(j);
Str out = StrInit(&alloc);
StrIter r = JReadString(si, &out);
if (StrIterIndex(&r) == StrIterIndex(&si) || StrIterIndex(&r) != StrIterLength(&r)) {
WriteFmtLn("[DEBUG] JReadString failed on a plain string: idx={}", StrIterIndex(&r)); StrIter r = JReadString(si, &out);
if (StrIterIndex(&r) == StrIterIndex(&si) || StrIterIndex(&r) != StrIterLength(&r)) {
WriteFmtLn("[DEBUG] JReadString failed on a plain string: idx={}", StrIterIndex(&r));
success = false;
} }
if (StrLen(&out) != 5 || MemCompare(StrBegin(&out), "plain", 5) != 0) {
WriteFmtLn("[DEBUG] JReadString decoded plain string wrong: len={}", StrLen(&out));
success = false;
}
Last updated on