ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
epub_xml_toc.c
Go to the documentation of this file.
1
19#include <stddef.h>
20#include <stdint.h>
21
25#include "ra8_attributes.h"
26#include "xml.h"
27
29internal_ancestor_name(const xml_reader_t* reader, uint16_t depth, uint16_t levels)
30{
31 uint16_t frame = 0U;
32 return priv_epub_xml_ancestor_frame(depth, levels, &frame)
33 ? priv_epub_xml_frame_name(reader, frame)
34 : (xml_span_t){};
35}
36
37RA8_INTERNAL static uint8_t internal_ancestor_depth(const uint8_t* source,
38 size_t source_len,
39 const xml_reader_t* reader,
40 uint16_t depth,
41 const char* local)
42{
43 uint8_t count = 0U;
44 for (uint16_t i = 0U; i < depth; ++i) {
45 if (xml_span_local_equal(source, source_len, priv_epub_xml_frame_name(reader, i), local)) {
46 ++count;
47 }
48 }
49 return count;
50}
51
52RA8_INTERNAL static uint16_t internal_toc_reserve(const uint8_t* source,
53 size_t source_len,
54 const xml_event_t* event,
55 xml_reader_t* reader,
56 epub_book_t* book,
57 const char* local)
58{
59 uint16_t marker = 0U;
60 if (book->toc_count < (uint16_t)k_epub_max_toc) {
61 const uint16_t slot = book->toc_count;
62 book->toc_count++;
63 book->toc[slot] = (epub_toc_entry_t){};
64 book->toc[slot].depth =
65 internal_ancestor_depth(source, source_len, reader, event->depth, local);
66 marker = (uint16_t)(slot + 1U);
67 }
68 if (event->self_closing == 0U) {
69 reader->workspace->frames[event->depth].consumer = marker;
70 }
71 return marker;
72}
73
74RA8_INTERNAL static uint16_t internal_toc_marker(const xml_reader_t* reader, uint16_t depth)
75{
76 uint16_t level = depth;
77 while (level > 0U) {
78 --level;
79 const uint16_t marker = reader->workspace->frames[level].consumer;
80 if (marker != 0U) {
81 return marker;
82 }
83 }
84 return 0U;
85}
86
87RA8_INTERNAL static ra8_err_t internal_toc_capacity(const uint8_t* source,
88 size_t length,
89 epub_xml_workspace_t* workspace,
90 const xml_event_t* selected,
91 const char* entry_local,
92 bool require_list)
93{
94 xml_reader_t reader = {};
95 ra8_err_t err = priv_epub_xml_reader(&reader, source, length, workspace);
96 bool active = false;
97 bool enabled = !require_list;
98 uint16_t count = 0U;
99 while (err == k_ra8_ok) {
100 xml_event_t event = {};
101 err = xml_reader_next(&reader, &event);
102 // mcdc-deactivated: internal_toc_capacity pull-loop status gate; the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here and only the end-of-document condition varies.
103 if ((err != k_ra8_ok) || (event.kind == (uint8_t)k_xml_event_none)) {
104 break;
105 }
106 if (!active && (event.kind == (uint8_t)k_xml_event_start) &&
107 (event.markup.offset == selected->markup.offset)) {
108 active = true;
109 } else if (active && (event.kind == (uint8_t)k_xml_event_start) && require_list &&
110 priv_epub_xml_direct_child(event.depth, selected->depth) &&
111 xml_span_local_equal(source, length, event.name, "ol")) {
112 enabled = true;
113 } else if (active && enabled && (event.kind == (uint8_t)k_xml_event_start) &&
114 xml_span_local_equal(source, length, event.name, entry_local)) {
115 if (count >= (uint16_t)k_epub_max_toc) {
116 return k_ra8_err_no_mem;
117 }
118 ++count;
119 } else if (active && (event.kind == (uint8_t)k_xml_event_end) &&
120 (event.depth == selected->depth)) {
121 return k_ra8_ok;
122 } else {
123 /* Any other event is outside the counted entries and changes nothing. */
124 }
125 }
126 return err;
127}
128
130{
131 if (!ctx->active && (event->kind == (uint8_t)k_xml_event_start) &&
132 (event->markup.offset == ctx->selected.markup.offset)) {
133 ctx->active = true;
134 } else if (ctx->active && (event->kind == (uint8_t)k_xml_event_start) &&
135 xml_span_local_equal(ctx->source, ctx->source_len, event->name, "navPoint")) {
136 (void)
137 internal_toc_reserve(ctx->source, ctx->source_len, event, ctx->reader, ctx->book, "navPoint");
138 } else if (ctx->active && (event->kind == (uint8_t)k_xml_event_start) &&
139 xml_span_local_equal(ctx->source, ctx->source_len, event->name, "content")) {
140 const uint16_t marker = internal_toc_marker(ctx->reader, event->depth);
141 const priv_attr_t src = priv_epub_xml_attr(ctx->source, ctx->source_len, event, "src");
142 if ((marker != 0U) && src.present) {
144 ctx->source_len,
145 src.span,
146 ctx->book->toc[marker - 1U].href,
148 }
149 } else if ((event->kind == (uint8_t)k_xml_event_text) && (event->depth >= 3U) &&
151 ctx->source_len,
152 internal_ancestor_name(ctx->reader, event->depth, 1U),
153 "text") &&
155 ctx->source_len,
156 internal_ancestor_name(ctx->reader, event->depth, 2U),
157 "navLabel")) {
158 uint16_t nav_label = 0U;
159 const bool found = priv_epub_xml_ancestor_frame(event->depth, 2U, &nav_label);
160 const uint16_t marker = found ? internal_toc_marker(ctx->reader, nav_label) : 0U;
161 if ((marker != 0U) && (ctx->book->toc[marker - 1U].title[0] == '\0')) {
163 ctx->source_len,
164 event->markup,
165 ctx->book->toc[marker - 1U].title,
167 }
168 } else if ((event->kind == (uint8_t)k_xml_event_end) && ctx->active &&
169 (event->depth == ctx->selected.depth)) {
170 ctx->active = false;
171 } else {
172 /* Any other event carries nothing the navMap walker consumes. */
173 }
174}
175
176ra8_err_t priv_epub_xml_parse_ncx(const uint8_t* xml_bytes, size_t xml_len, epub_book_t* book)
177{
178 if ((xml_bytes == nullptr) || (book == nullptr)) {
179 return k_ra8_err_null_ptr;
180 }
181 if (xml_len == 0U) {
183 }
184 ra8_err_t err = xml_validate(xml_bytes, xml_len, &book->xml_workspace.reader);
185 xml_event_t selected = {};
186 if (err == k_ra8_ok) {
187 err = priv_epub_xml_find(xml_bytes,
188 xml_len,
189 &book->xml_workspace,
190 "navMap",
191 false,
192 0U,
193 0U,
194 &selected);
195 }
196 if (err == k_ra8_ok) {
197 err =
198 internal_toc_capacity(xml_bytes, xml_len, &book->xml_workspace, &selected, "navPoint", false);
199 }
200 if (err != k_ra8_ok) {
201 return err;
202 }
203 book->toc_count = 0U;
204 xml_reader_t reader = {};
205 err = priv_epub_xml_reader(&reader, xml_bytes, xml_len, &book->xml_workspace);
206 priv_ncx_ctx_t ctx = {.source = xml_bytes,
207 .source_len = xml_len,
208 .book = book,
209 .reader = &reader,
210 .selected = selected};
211 while (err == k_ra8_ok) {
212 xml_event_t event = {};
213 err = xml_reader_next(&reader, &event);
214 // mcdc-deactivated: priv_epub_xml_parse_ncx pull-loop status gate; the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here and only the end-of-document condition varies.
215 if ((err != k_ra8_ok) || (event.kind == (uint8_t)k_xml_event_none)) {
216 break;
217 }
218 internal_ncx_event(&ctx, &event);
219 }
220 return err;
221}
222
223RA8_INTERNAL static ra8_err_t internal_select_nav(const uint8_t* source,
224 size_t length,
225 epub_xml_workspace_t* workspace,
226 xml_event_t* out)
227{
228 xml_reader_t reader = {};
229 ra8_err_t err = priv_epub_xml_reader(&reader, source, length, workspace);
230 xml_event_t fallback = {};
231 while (err == k_ra8_ok) {
232 xml_event_t event = {};
233 err = xml_reader_next(&reader, &event);
234 // mcdc-deactivated: internal_select_nav pull-loop status gate; the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here and only the end-of-document condition varies.
235 if ((err != k_ra8_ok) || (event.kind == (uint8_t)k_xml_event_none)) {
236 break;
237 }
238 if ((event.kind == (uint8_t)k_xml_event_start) && (event.depth > 0U) &&
239 xml_span_local_equal(source, length, event.name, "nav")) {
240 if (fallback.kind == (uint8_t)k_xml_event_none) {
241 fallback = event;
242 }
244 length,
245 priv_epub_xml_attr(source, length, &event, "epub:type"),
246 "toc")) {
247 *out = event;
248 return k_ra8_ok;
249 }
250 }
251 }
252 // mcdc-deactivated: internal_select_nav fallback gate; the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here, so the loop can only exit at end-of-document with `err` equal to k_ra8_ok and the status condition is constant-true.
253 if ((err == k_ra8_ok) && (fallback.kind != (uint8_t)k_xml_event_none)) {
254 *out = fallback;
255 return k_ra8_ok;
256 }
257 return (err == k_ra8_ok) ? k_ra8_err_validation_failed : err;
258}
259
260RA8_INTERNAL static ra8_err_t internal_nav_has_list(const uint8_t* source,
261 size_t length,
262 epub_xml_workspace_t* workspace,
263 const xml_event_t* selected)
264{
265 xml_reader_t reader = {};
266 ra8_err_t err = priv_epub_xml_reader(&reader, source, length, workspace);
267 bool active = false;
268 while (err == k_ra8_ok) {
269 xml_event_t event = {};
270 err = xml_reader_next(&reader, &event);
271 // mcdc-deactivated: internal_nav_has_list pull-loop status gate; the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here and only the end-of-document condition varies.
272 if ((err != k_ra8_ok) || (event.kind == (uint8_t)k_xml_event_none)) {
273 break;
274 }
275 if (!active && (event.kind == (uint8_t)k_xml_event_start) &&
276 (event.markup.offset == selected->markup.offset)) {
277 active = true;
278 } else if (active && (event.kind == (uint8_t)k_xml_event_start) &&
279 priv_epub_xml_direct_child(event.depth, selected->depth) &&
280 xml_span_local_equal(source, length, event.name, "ol")) {
281 return k_ra8_ok;
282 } else if (active && (event.kind == (uint8_t)k_xml_event_end) &&
283 (event.depth == selected->depth)) {
285 } else {
286 /* Any other event neither opens the list nor ends the selected nav. */
287 }
288 }
289 return (err == k_ra8_ok) ? k_ra8_err_validation_failed : err;
290}
291
314{
316 xml_span_local_equal(ctx->source, ctx->source_len, event->name, "ol")) {
317 ctx->saw_ol = true;
318 return;
319 }
320 if (ctx->saw_ol && xml_span_local_equal(ctx->source, ctx->source_len, event->name, "li")) {
321 (void)internal_toc_reserve(ctx->source, ctx->source_len, event, ctx->reader, ctx->book, "li");
322 return;
323 }
324 if (!(ctx->saw_ol && (xml_span_local_equal(ctx->source, ctx->source_len, event->name, "a") ||
325 xml_span_local_equal(ctx->source, ctx->source_len, event->name, "span")))) {
326 return;
327 }
328 const uint16_t marker = internal_toc_marker(ctx->reader, event->depth);
329 if ((marker == 0U) || (event->self_closing != 0U)) {
330 return;
331 }
332 ctx->reader->workspace->frames[event->depth].consumer = marker;
333 if (!xml_span_local_equal(ctx->source, ctx->source_len, event->name, "a")) {
334 return;
335 }
336 const priv_attr_t href = priv_epub_xml_attr(ctx->source, ctx->source_len, event, "href");
337 if (href.present) {
339 ctx->source_len,
340 href.span,
341 ctx->book->toc[marker - 1U].href,
343 }
344 ctx->book->toc[marker - 1U].title[0] = '\0';
345}
346
348{
349 if (!ctx->active && (event->kind == (uint8_t)k_xml_event_start) &&
350 (event->markup.offset == ctx->selected.markup.offset)) {
351 ctx->active = true;
352 return;
353 }
354 if (!ctx->active) {
355 return;
356 }
357 if (event->kind == (uint8_t)k_xml_event_start) {
358 internal_nav_event_start(ctx, event);
359 // mcdc-deactivated: internal_nav_event text-depth gate; this arm is reached only while ctx->active, which spans the subtree of a <nav> that internal_select_nav selected at depth >= 1, so every event inside it sits at depth > 0 and the depth condition is constant-true.
360 } else if ((event->kind == (uint8_t)k_xml_event_text) && (event->depth > 0U)) {
361 const xml_span_t parent = internal_ancestor_name(ctx->reader, event->depth, 1U);
362 const uint16_t marker = priv_epub_xml_ancestor_marker(ctx->reader, event->depth, 1U);
363 if ((xml_span_local_equal(ctx->source, ctx->source_len, parent, "a") ||
364 xml_span_local_equal(ctx->source, ctx->source_len, parent, "span")) &&
365 (marker != 0U) && (ctx->book->toc[marker - 1U].title[0] == '\0')) {
367 ctx->source_len,
368 event->markup,
369 ctx->book->toc[marker - 1U].title,
371 }
372 } else if ((event->kind == (uint8_t)k_xml_event_end) && (event->depth == ctx->selected.depth)) {
373 ctx->active = false;
374 } else {
375 /* Any other event carries nothing the nav walker consumes. */
376 }
377}
378
379ra8_err_t priv_epub_xml_parse_nav(const uint8_t* xml_bytes, size_t xml_len, epub_book_t* book)
380{
381 if ((xml_bytes == nullptr) || (book == nullptr)) {
382 return k_ra8_err_null_ptr;
383 }
384 if (xml_len == 0U) {
386 }
387 ra8_err_t err = xml_validate(xml_bytes, xml_len, &book->xml_workspace.reader);
388 xml_event_t selected = {};
389 if (err == k_ra8_ok) {
390 err = internal_select_nav(xml_bytes, xml_len, &book->xml_workspace, &selected);
391 }
392 if (err == k_ra8_ok) {
393 err = internal_nav_has_list(xml_bytes, xml_len, &book->xml_workspace, &selected);
394 }
395 if (err == k_ra8_ok) {
396 err = internal_toc_capacity(xml_bytes, xml_len, &book->xml_workspace, &selected, "li", true);
397 }
398 if (err != k_ra8_ok) {
399 return err;
400 }
401 book->toc_count = 0U;
402 xml_reader_t reader = {};
403 err = priv_epub_xml_reader(&reader, xml_bytes, xml_len, &book->xml_workspace);
404 priv_nav_ctx_t ctx = {.source = xml_bytes,
405 .source_len = xml_len,
406 .book = book,
407 .reader = &reader,
408 .selected = selected};
409 while (err == k_ra8_ok) {
410 xml_event_t event = {};
411 err = xml_reader_next(&reader, &event);
412 // mcdc-deactivated: priv_epub_xml_parse_nav pull-loop status gate; the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here and only the end-of-document condition varies.
413 if ((err != k_ra8_ok) || (event.kind == (uint8_t)k_xml_event_none)) {
414 break;
415 }
416 internal_nav_event(&ctx, &event);
417 }
418 // mcdc-deactivated: priv_epub_xml_parse_nav completion gate; this point is reached only after internal_nav_has_list accepted the same bytes with the identical direct-child <ol> predicate that sets ctx.saw_ol in internal_nav_event, so saw_ol is always true, and the public entry point validated this exact byte range with xml_validate() before this re-parse and the bounded pull reader is a pure function of (source, source_len, workspace) -- the shim only ever writes the frame `consumer` field, which xml never reads back -- so xml_reader_next() cannot fail here.
419 if ((err != k_ra8_ok) || !ctx.saw_ol) {
420 return (err == k_ra8_ok) ? k_ra8_err_validation_failed : err;
421 }
422 return k_ra8_ok;
423}
@ k_epub_max_toc
Max table-of-contents entries we keep.
Definition epub.h:88
@ k_epub_max_path_len
Max href length (incl.
Definition epub.h:89
@ k_epub_meta_len
Max bytes per metadata field.
Definition epub.h:90
Private contracts for streamed EPUB XML consumers.
void priv_epub_xml_copy(const uint8_t *source, size_t source_len, xml_span_t span, char *destination, size_t capacity)
Copy decoded text into a bounded EPUB field.
xml_span_t priv_epub_xml_frame_name(const xml_reader_t *reader, uint16_t frame)
Return one live reader-frame name span.
bool priv_epub_xml_ancestor_frame(uint16_t depth, uint16_t levels, uint16_t *out_frame)
Resolve a bounded ancestor frame index.
uint16_t priv_epub_xml_ancestor_marker(const xml_reader_t *reader, uint16_t depth, uint16_t levels)
Return a checked ancestor consumer marker.
ra8_err_t priv_epub_xml_find(const uint8_t *source, size_t length, epub_xml_workspace_t *workspace, const char *local, bool use_parent, uint32_t parent_offset, uint16_t parent_depth, xml_event_t *out)
Find the first local-name element under an optional direct parent.
ra8_err_t priv_epub_xml_reader(xml_reader_t *reader, const uint8_t *source, size_t length, epub_xml_workspace_t *workspace)
Initialise another validated EPUB pull pass.
bool priv_epub_xml_attr_contains(const uint8_t *source, size_t source_len, priv_attr_t attribute, const char *needle)
Test whether a decoded attribute contains an ASCII literal.
bool priv_epub_xml_direct_child(uint16_t child, uint16_t parent)
Test whether a depth is exactly one level below another.
priv_attr_t priv_epub_xml_attr(const uint8_t *source, size_t source_len, const xml_event_t *event, const char *name)
Find an exact-name attribute on one start event.
Library-private contract for the bounded EPUB XML parser.
static void internal_ncx_event(priv_ncx_ctx_t *ctx, const xml_event_t *event)
static ra8_err_t internal_nav_has_list(const uint8_t *source, size_t length, epub_xml_workspace_t *workspace, const xml_event_t *selected)
static ra8_err_t internal_toc_capacity(const uint8_t *source, size_t length, epub_xml_workspace_t *workspace, const xml_event_t *selected, const char *entry_local, bool require_list)
static uint16_t internal_toc_reserve(const uint8_t *source, size_t source_len, const xml_event_t *event, xml_reader_t *reader, epub_book_t *book, const char *local)
static uint16_t internal_toc_marker(const xml_reader_t *reader, uint16_t depth)
static xml_span_t internal_ancestor_name(const xml_reader_t *reader, uint16_t depth, uint16_t levels)
static void internal_nav_event(priv_nav_ctx_t *ctx, const xml_event_t *event)
ra8_err_t priv_epub_xml_parse_nav(const uint8_t *xml_bytes, size_t xml_len, epub_book_t *book)
Parse an EPUB 3 nav document into book->toc.
static ra8_err_t internal_select_nav(const uint8_t *source, size_t length, epub_xml_workspace_t *workspace, xml_event_t *out)
static uint8_t internal_ancestor_depth(const uint8_t *source, size_t source_len, const xml_reader_t *reader, uint16_t depth, const char *local)
static void internal_nav_event_start(priv_nav_ctx_t *ctx, const xml_event_t *event)
Dispatch one start-tag event inside an active nav-list subtree.
ra8_err_t priv_epub_xml_parse_ncx(const uint8_t *xml_bytes, size_t xml_len, epub_book_t *book)
Parse an EPUB 2 NCX document into book->toc.
Private contracts for the EPUB NCX and nav table-of-contents consumers.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
Definition ra8_err.h:459
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Opened EPUB book.
Definition epub.h:286
epub_xml_workspace_t xml_workspace
Per-book XML parser state; never shared with another book.
Definition epub.h:311
uint16_t toc_count
Number of entries stored in toc.
Definition epub.h:350
epub_toc_entry_t toc[k_epub_max_toc]
Flattened TOC, document order.
Definition epub.h:351
One titled entry in the table of contents.
Definition epub.h:142
char href[k_epub_max_path_len]
Target href (rel.
Definition epub.h:144
char title[k_epub_meta_len]
Navigation label text ("" if none).
Definition epub.h:143
uint8_t depth
Nesting level; 0 == top level.
Definition epub.h:145
Per-book bounded storage for strict OPF/container/TOC parsing.
Definition epub.h:105
xml_workspace_t reader
4096-byte open-element stack.
Definition epub.h:106
Optional attribute span.
xml_span_t span
Value span.
bool present
Attribute existed.
Mutable state for one validated EPUB navigation pass.
bool saw_ol
Selected navigation contains its list.
xml_event_t selected
Selected navigation element.
xml_reader_t * reader
Reader whose live frames carry markers.
size_t source_len
Navigation-document byte count.
bool active
Selected subtree has begun.
epub_book_t * book
TOC output being populated.
const uint8_t * source
Immutable navigation document.
Mutable state for one validated NCX navigation-map pass.
xml_reader_t * reader
Reader whose live frames carry markers.
epub_book_t * book
TOC output being populated.
bool active
Selected subtree has begun.
xml_event_t selected
Selected navigation-map element.
size_t source_len
NCX-document byte count.
const uint8_t * source
Immutable NCX document.
One XML pull event.
Definition xml.h:71
xml_span_t markup
Complete markup span, or text payload.
Definition xml.h:72
uint8_t self_closing
One for an empty-element start.
Definition xml.h:77
xml_span_t name
Element name for start/end.
Definition xml.h:73
uint16_t depth
Root is depth zero.
Definition xml.h:74
uint8_t kind
xml_event_kind_t.
Definition xml.h:76
uint16_t consumer
Consumer-owned while this frame is live.
Definition xml.h:53
Pull-reader state; initialise before each pass.
Definition xml.h:93
xml_workspace_t * workspace
Caller-owned stack.
Definition xml.h:97
Immutable byte span expressed relative to the source.
Definition xml.h:44
uint32_t offset
First byte offset.
Definition xml.h:45
xml_frame_t frames[k_xml_workspace_frames]
Open-element stack.
Definition xml.h:58
Bounded, caller-owned, no-heap XML pull reader.
bool xml_span_local_equal(const uint8_t *source, size_t source_len, xml_span_t span, const char *literal)
Compare the namespace-local tail of a bounded span with an ASCII literal.
Definition xml_decode.c:565
@ k_xml_event_start
Element start.
Definition xml.h:64
@ k_xml_event_none
No event / end of source.
Definition xml.h:63
@ k_xml_event_text
Character-data run.
Definition xml.h:66
@ k_xml_event_end
Element end.
Definition xml.h:65
ra8_err_t xml_validate(const uint8_t *source, size_t source_len, xml_workspace_t *workspace)
Validate a complete document before any consumer mutation.
Definition xml.c:631
ra8_err_t xml_reader_next(xml_reader_t *reader, xml_event_t *out_event)
Return the next semantic event and validate syntax incrementally.
Definition xml.c:590