44 for (uint16_t i = 0U; i < depth; ++i) {
66 marker = (uint16_t)(slot + 1U);
76 uint16_t level = depth;
91 const char* entry_local,
97 bool enabled = !require_list;
109 }
else if (active && (event.kind == (uint8_t)
k_xml_event_start) && require_list &&
120 (event.depth == selected->
depth)) {
142 if ((marker != 0U) && src.
present) {
158 uint16_t nav_label = 0U;
161 if ((marker != 0U) && (ctx->
book->
toc[marker - 1U].
title[0] ==
'\0')) {
178 if ((xml_bytes ==
nullptr) || (book ==
nullptr)) {
207 .source_len = xml_len,
210 .selected = selected};
283 (event.depth == selected->
depth)) {
365 (marker != 0U) && (ctx->
book->
toc[marker - 1U].
title[0] ==
'\0')) {
381 if ((xml_bytes ==
nullptr) || (book ==
nullptr)) {
405 .source_len = xml_len,
408 .selected = selected};
@ k_epub_max_toc
Max table-of-contents entries we keep.
@ k_epub_max_path_len
Max href length (incl.
@ k_epub_meta_len
Max bytes per metadata field.
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).
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
epub_xml_workspace_t xml_workspace
Per-book XML parser state; never shared with another book.
uint16_t toc_count
Number of entries stored in toc.
epub_toc_entry_t toc[k_epub_max_toc]
Flattened TOC, document order.
One titled entry in the table of contents.
char href[k_epub_max_path_len]
Target href (rel.
char title[k_epub_meta_len]
Navigation label text ("" if none).
uint8_t depth
Nesting level; 0 == top level.
Per-book bounded storage for strict OPF/container/TOC parsing.
xml_workspace_t reader
4096-byte open-element stack.
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.
xml_span_t markup
Complete markup span, or text payload.
uint8_t self_closing
One for an empty-element start.
xml_span_t name
Element name for start/end.
uint16_t depth
Root is depth zero.
uint8_t kind
xml_event_kind_t.
uint16_t consumer
Consumer-owned while this frame is live.
Pull-reader state; initialise before each pass.
xml_workspace_t * workspace
Caller-owned stack.
Immutable byte span expressed relative to the source.
uint32_t offset
First byte offset.
xml_frame_t frames[k_xml_workspace_frames]
Open-element stack.
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.
@ k_xml_event_start
Element start.
@ k_xml_event_none
No event / end of source.
@ k_xml_event_text
Character-data run.
@ k_xml_event_end
Element end.
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.
ra8_err_t xml_reader_next(xml_reader_t *reader, xml_event_t *out_event)
Return the next semantic event and validate syntax incrementally.