ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_rabook_xml_shim.c File Reference

Strict streamed XHTML-to-RABOOK consumer. More...

#include "ra8_rabook_xml_shim.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
Include dependency graph for ra8_rabook_xml_shim.c:

Go to the source code of this file.

Data Structures

struct  priv_selection_t
 Selected subtree root coordinates. More...

Functions

static uint32_t internal_intern_span (ra8_rabook_ctx_t *ctx, const uint8_t *source, size_t source_len, xml_span_t span)
 Intern one decoded immutable span through the existing string pool.
static ra8_err_t internal_attributes (const uint8_t *source, size_t source_len, const xml_event_t *event, ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace)
 Collect and intern one event's attributes.
static ra8_err_t internal_link (ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace, uint16_t parent_level, uint32_t next_sibling)
 Link a new node beneath its selected-subtree parent.
static ra8_err_t internal_element (const uint8_t *source, size_t source_len, const xml_event_t *event, uint16_t selected_depth, ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace, uint32_t *out_node)
 Emit one element event and link it into preorder.
static ra8_err_t internal_text (const uint8_t *source, size_t source_len, const xml_event_t *event, uint16_t selected_depth, ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace)
 Emit one decoded text run beneath the current element.
static ra8_err_t internal_select_event (const uint8_t *source, size_t length, const xml_event_t *event, uint16_t *root_depth, bool *saw_root, uint16_t *direct_children, priv_selection_t *out, bool *out_done)
 Apply one reader event to the direct-body selection search.
static ra8_err_t internal_select (const uint8_t *source, size_t length, xml_workspace_t *xml, priv_selection_t *out)
 Find a direct body or fall back to the document root.
static ra8_err_t internal_emit_start (const uint8_t *source, size_t length, const priv_selection_t *selection, const xml_event_t *event, ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace, bool *active, uint32_t *out_root)
 Handle one start event for the in-progress subtree emission.
static ra8_err_t internal_emit_event (const uint8_t *source, size_t length, const priv_selection_t *selection, const xml_event_t *event, ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace, bool *active, uint32_t *out_root)
 Apply one reader event to the in-progress subtree emission.
static ra8_err_t internal_emit (const uint8_t *source, size_t length, const priv_selection_t *selection, ra8_rabook_ctx_t *ctx, ra8_rabook_xml_workspace_t *workspace, uint32_t *out_root)
 Stream the selected subtree into the builder.
static ra8_err_t internal_parse_chapter_validate_args (const uint8_t *xhtml_bytes, size_t xhtml_len, const ra8_rabook_ctx_t *ctx, const char *chapter_href, const char *chapter_title, const ra8_rabook_xml_workspace_t *workspace)
 Validate the public chapter-parse entry point's arguments.
ra8_err_t ra8_rabook_xml_parse_chapter (const uint8_t *xhtml_bytes, size_t xhtml_len, ra8_rabook_ctx_t *ctx, const char *chapter_href, const char *chapter_title, ra8_rabook_xml_workspace_t *workspace)
 Parse one XHTML chapter and append it to ctx.

Detailed Description

Strict streamed XHTML-to-RABOOK consumer.

Validates immutable XHTML before streaming a selected body/root subtree into the bounded RABOOK builder, restoring the complete logical builder checkpoint on every failure.

[Ring 4 / EPUB Compiler] {World: NS}

Definition in file ra8_rabook_xml_shim.c.

Function Documentation

◆ internal_attributes()

ra8_err_t internal_attributes ( const uint8_t * source,
size_t source_len,
const xml_event_t * event,
ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace )
static

Collect and intern one event's attributes.

Preserves source order in caller workspace for element emission.

Parameters
[in]sourceImmutable XML source.
[in]source_lenExact readable source extent.
[in]eventValid start event aliasing source.
[in,out]ctxActive bounded RABOOK builder.
[in,out]workspaceExclusive attribute scratch.
Returns
Repository error code.
Return values
k_ra8_okEvery attribute was interned.
k_ra8_err_no_memAttribute or string capacity was exhausted.
k_ra8_err_validation_failedAttribute traversal was inconsistent.
Precondition
The complete document was validated before this pass.
workspace is not shared by another operation.
Postcondition
Success fills exactly event->attribute_count scratch entries.
Failure leaves source unchanged and marks builder failure when capacity failed.
Note
Workspace bytes are scratch on every result.
Since
0.1.0

Definition at line 115 of file ra8_rabook_xml_shim.c.

References xml_event_t::attribute_count, ra8_rabook_xml_workspace_t::attributes, ra8_rabook_ctx_t::failed, internal_intern_span(), k_ra8_err_no_mem, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_rabook_xml_max_attributes, xml_attribute_t::name, book_attr_t::name_off, RA8_INTERNAL, xml_attribute_t::value, book_attr_t::value_off, xml_attr_begin(), and xml_attr_next().

Referenced by internal_element().

◆ internal_element()

ra8_err_t internal_element ( const uint8_t * source,
size_t source_len,
const xml_event_t * event,
uint16_t selected_depth,
ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace,
uint32_t * out_node )
static

Emit one element event and link it into preorder.

Interns the name/attributes, creates the node, then links its parent.

Parameters
[in]sourceImmutable XML source.
[in]source_lenExact readable source extent.
[in]eventValid element-start event.
[in]selected_depthAbsolute depth of the emitted subtree root.
[in,out]ctxActive bounded builder.
[in,out]workspaceExclusive emission scratch.
[out]out_nodeNewly created node on success.
Returns
Repository error code.
Return values
k_ra8_okElement emitted.
k_ra8_err_no_memAny bounded builder capacity was exhausted.
k_ra8_err_validation_failedAttribute traversal failed.
Precondition
event lies within the selected validated subtree.
Workspace level capacity covers event->depth - selected_depth.
Postcondition
Success stores the live node in out_node and workspace.
Failure never changes source bytes; caller restores the builder checkpoint.
Note
Intermediate builder bytes are transactional at the public caller.
Since
0.1.0

Definition at line 203 of file ra8_rabook_xml_shim.c.

References xml_event_t::attribute_count, ra8_rabook_xml_workspace_t::attributes, xml_event_t::depth, ra8_rabook_xml_workspace_t::element_nodes, internal_attributes(), internal_intern_span(), internal_link(), k_book_nil, k_ra8_err_no_mem, k_ra8_ok, ra8_rabook_xml_workspace_t::last_children, xml_event_t::name, RA8_INTERNAL, and ra8_rabook_add_element().

Referenced by internal_emit_start().

◆ internal_emit()

ra8_err_t internal_emit ( const uint8_t * source,
size_t length,
const priv_selection_t * selection,
ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace,
uint32_t * out_root )
static

Stream the selected subtree into the builder.

Emits start and text events until the selected element closes; delegates the per-event decision to internal_emit_event.

Parameters
[in]sourceImmutable validated XML source.
[in]lengthExact readable source extent.
[in]selectionSelected subtree coordinates.
[in,out]ctxActive bounded builder.
[in,out]workspaceExclusive reader/emission scratch.
[out]out_rootEmitted subtree root node.
Returns
Repository error code.
Return values
k_ra8_okSelected subtree consumed.
k_ra8_err_no_memBounded builder capacity failed.
k_ra8_err_validation_failedRepeated reader traversal failed.
Precondition
selection came from internal_select on this source.
The complete source was validated and workspace is exclusive.
Postcondition
Success returns the emitted root and canonical preorder links.
Failure leaves source unchanged; caller restores the builder checkpoint.
Note
Workspace contents are scratch on every result.
Since
0.1.0

Definition at line 512 of file ra8_rabook_xml_shim.c.

References internal_emit_event(), k_ra8_ok, k_xml_event_none, RA8_INTERNAL, ra8_rabook_xml_workspace_t::xml, xml_reader_init(), and xml_reader_next().

Referenced by ra8_rabook_xml_parse_chapter().

◆ internal_emit_event()

ra8_err_t internal_emit_event ( const uint8_t * source,
size_t length,
const priv_selection_t * selection,
const xml_event_t * event,
ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace,
bool * active,
uint32_t * out_root )
static

Apply one reader event to the in-progress subtree emission.

While inactive, skips events until the selected subtree's start event arrives. While active, delegates a start event to internal_emit_start, emits text events, and closes the active span on the matching end event.

Parameters
[in]sourceImmutable validated XML source.
[in]lengthExact readable source extent.
[in]selectionSelected subtree coordinates.
[in]eventOne decoded reader event.
[in,out]ctxActive bounded builder.
[in,out]workspaceExclusive reader/emission scratch.
[in,out]activeWhether the selected subtree is currently open.
[out]out_rootEmitted subtree root node; set when the root starts.
Returns
Repository error code.
Return values
k_ra8_okThe event was applied.
k_ra8_err_no_memBounded builder capacity failed.
Precondition
selection came from internal_select on this source.
event came from the same reader driving this emission.
Postcondition
Success may advance out_root, mutate the builder, or update active per the event's kind.
active becomes false on the end event whose depth matches the selection.
Note
Not thread-safe; caller owns the reader state.
Since
0.1.0

Definition at line 459 of file ra8_rabook_xml_shim.c.

References priv_selection_t::depth, xml_event_t::depth, internal_emit_start(), internal_text(), k_ra8_ok, k_xml_event_end, k_xml_event_start, k_xml_event_text, xml_event_t::kind, xml_event_t::markup, priv_selection_t::offset, xml_span_t::offset, and RA8_INTERNAL.

Referenced by internal_emit().

◆ internal_emit_start()

ra8_err_t internal_emit_start ( const uint8_t * source,
size_t length,
const priv_selection_t * selection,
const xml_event_t * event,
ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace,
bool * active,
uint32_t * out_root )
static

Handle one start event for the in-progress subtree emission.

Emits the element, records the root node when the started element is the subtree root, and closes a self-closing root immediately.

Parameters
[in]sourceImmutable validated XML source.
[in]lengthExact readable source extent.
[in]selectionSelected subtree coordinates.
[in]eventOne decoded start-kind reader event.
[in,out]ctxActive bounded builder.
[in,out]workspaceExclusive reader/emission scratch.
[in,out]activeWhether the selected subtree is currently open.
[out]out_rootEmitted subtree root node; set when the root starts.
Returns
Repository error code.
Return values
k_ra8_okThe element was emitted.
k_ra8_err_no_memBounded builder capacity failed.
Precondition
event->kind is k_xml_event_start.
selection came from internal_select on this same source.
Postcondition
Success may advance out_root and close a self-closing root.
out_root is written whenever the event starts the selected root, even when the element emission itself then fails.
Note
Not thread-safe; caller owns the reader state.
Since
0.1.0

Definition at line 406 of file ra8_rabook_xml_shim.c.

References priv_selection_t::depth, internal_element(), k_book_nil, k_ra8_ok, xml_event_t::markup, priv_selection_t::offset, xml_span_t::offset, RA8_INTERNAL, and xml_event_t::self_closing.

Referenced by internal_emit_event().

◆ internal_intern_span()

uint32_t internal_intern_span ( ra8_rabook_ctx_t * ctx,
const uint8_t * source,
size_t source_len,
xml_span_t span )
static

Intern one decoded immutable span through the existing string pool.

Measures and decodes the complete span before committing pool size.

Parameters
[in,out]ctxActive bounded RABOOK builder.
[in]sourceImmutable XML source containing span.
[in]source_lenExact readable source extent.
[in]spanSource-relative encoded text span.
Returns
String-pool offset, or k_book_nil on failure.
Return values
k_book_nilDecode or string-pool capacity failed.
Precondition
ctx and source are non-NULL.
span lies within source_len validated bytes.
Postcondition
Success returns a live interned string offset.
Failure sets ctx->failed; source bytes remain unchanged.
Note
Duplicate decoded strings reuse their existing offset.
Since
0.1.0

Definition at line 48 of file ra8_rabook_xml_shim.c.

References ra8_rabook_ctx_t::buf, ra8_rabook_ctx_t::failed, k_book_nil, k_ra8_ok, RA8_INTERNAL, ra8_rabook_buffers_t::string_cap, ra8_rabook_buffers_t::string_pool, ra8_rabook_ctx_t::string_size, strlen(), xml_decode(), and xml_decoded_size().

Referenced by internal_attributes(), internal_element(), and internal_text().

◆ internal_link()

ra8_err_t internal_link ( ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace,
uint16_t parent_level,
uint32_t next_sibling )
static

Link a new node beneath its selected-subtree parent.

Appends after the remembered last child or establishes the first child.

Parameters
[in,out]ctxActive bounded RABOOK builder.
[in,out]workspaceSelected-subtree linkage state.
[in]parent_levelWorkspace level holding the parent.
[in]next_siblingLive node to append.
Returns
Repository error code.
Return values
k_ra8_okNode linked and last-child state advanced.
k_ra8_err_no_memUnderlying bounded link operation failed.
Precondition
parent_level indexes live workspace entries.
next_sibling and its parent are live builder nodes.
Postcondition
Success records next_sibling as the parent's last child.
Failure leaves the workspace last-child entry unchanged.
Note
Builder mutation follows the underlying link operation's contract.
Since
0.1.0

Definition at line 166 of file ra8_rabook_xml_shim.c.

References ra8_rabook_xml_workspace_t::element_nodes, k_book_nil, k_ra8_ok, ra8_rabook_xml_workspace_t::last_children, RA8_INTERNAL, ra8_rabook_link_child(), and ra8_rabook_link_sibling().

Referenced by internal_element(), and internal_text().

◆ internal_parse_chapter_validate_args()

ra8_err_t internal_parse_chapter_validate_args ( const uint8_t * xhtml_bytes,
size_t xhtml_len,
const ra8_rabook_ctx_t * ctx,
const char * chapter_href,
const char * chapter_title,
const ra8_rabook_xml_workspace_t * workspace )
static

Validate the public chapter-parse entry point's arguments.

Rejects any null pointer argument and a zero-length source before any parsing work begins.

Parameters
[in]xhtml_bytesCandidate XHTML source bytes.
[in]xhtml_lenCandidate source length in bytes.
[in]ctxCandidate active builder.
[in]chapter_hrefCandidate spine href string.
[in]chapter_titleCandidate TOC title string.
[in]workspaceCandidate reader/emission scratch.
Returns
Argument validation status.
Return values
k_ra8_okEvery argument is present and xhtml_len is nonzero.
k_ra8_err_null_ptrA required pointer argument is NULL.
k_ra8_err_invalid_sizexhtml_len is zero.
Precondition
None; every argument is treated as untrusted.
ctx and workspace need not be initialized; only addresses are read.
Postcondition
No argument or builder state is modified.
Success proves every later dereference in the parse path has a non-NULL base.
Note
Not thread-safe with respect to concurrent callers sharing ctx.
Since
0.1.0

Definition at line 580 of file ra8_rabook_xml_shim.c.

References k_ra8_err_invalid_size, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by ra8_rabook_xml_parse_chapter().

◆ internal_select()

ra8_err_t internal_select ( const uint8_t * source,
size_t length,
xml_workspace_t * xml,
priv_selection_t * out )
static

Find a direct body or fall back to the document root.

Rejects a root with more than the bounded direct-child search limit; delegates the per-event decision to internal_select_event.

Parameters
[in]sourceImmutable validated XML source.
[in]lengthExact readable source extent.
[in,out]xmlExclusive reader workspace.
[out]outSelected start offset and absolute depth.
Returns
Repository error code.
Return values
k_ra8_okSelection completed.
k_ra8_err_validation_failedReader or bounded search failed.
Precondition
source already passed xml_validate.
xml and out are writable and non-overlapping.
Postcondition
Success selects the first direct body or the document root.
Failure leaves source bytes unchanged; out is unspecified.
Note
Workspace bytes are scratch on return.
Since
0.1.0

Definition at line 355 of file ra8_rabook_xml_shim.c.

References internal_select_event(), k_ra8_ok, k_xml_event_none, xml_reader_init(), and xml_reader_next().

Referenced by ra8_rabook_xml_parse_chapter().

◆ internal_select_event()

ra8_err_t internal_select_event ( const uint8_t * source,
size_t length,
const xml_event_t * event,
uint16_t * root_depth,
bool * saw_root,
uint16_t * direct_children,
priv_selection_t * out,
bool * out_done )
static

Apply one reader event to the direct-body selection search.

Latches the document root on first sight, then watches direct children of the root for a body element, enforcing the bounded sibling-search limit.

Parameters
[in]sourceImmutable validated XML source.
[in]lengthExact readable source extent.
[in]eventOne decoded reader event.
[in,out]root_depthRoot element depth; latched on first start event.
[in,out]saw_rootWhether the root has been latched yet.
[in,out]direct_childrenDirect-child count seen since the root.
[out]outSelected start offset and absolute depth.
[out]out_doneSet true once a body element has been selected.
Returns
Selection status.
Return values
k_ra8_okThe event was applied; out_done reports finality.
k_ra8_err_validation_failedThe bounded sibling-search limit was exceeded.
Precondition
event came from the same reader driving this search.
out_done was initialized false by the caller before the first call.
Postcondition
On a body match, out selects the body and *out_done is true.
Otherwise out holds the root fallback selection.
Note
Not thread-safe; caller owns the reader state.
Since
0.1.0

Definition at line 300 of file ra8_rabook_xml_shim.c.

References xml_event_t::depth, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_rabook_xml_body_siblings, k_xml_event_start, xml_event_t::kind, xml_event_t::name, RA8_INTERNAL, and xml_span_equal().

Referenced by internal_select().

◆ internal_text()

ra8_err_t internal_text ( const uint8_t * source,
size_t source_len,
const xml_event_t * event,
uint16_t selected_depth,
ra8_rabook_ctx_t * ctx,
ra8_rabook_xml_workspace_t * workspace )
static

Emit one decoded text run beneath the current element.

Empty decoded runs are ignored; nonempty runs become linked text nodes.

Parameters
[in]sourceImmutable XML source.
[in]source_lenExact readable source extent.
[in]eventValid text event.
[in]selected_depthAbsolute depth of the emitted subtree root.
[in,out]ctxActive bounded builder.
[in,out]workspaceExclusive linkage scratch.
Returns
Repository error code.
Return values
k_ra8_okText was empty or emitted and linked.
k_ra8_err_no_memString, node, or link capacity was exhausted.
k_ra8_err_validation_failedText decoding failed.
Precondition
event has a live parent inside the selected subtree.
The complete source was validated before this pass.
Postcondition
Success preserves source order beneath the current parent.
Failure never changes source bytes; caller restores the builder checkpoint.
Note
Workspace mutation is scratch until public-call success.
Since
0.1.0

Definition at line 253 of file ra8_rabook_xml_shim.c.

References xml_event_t::depth, internal_intern_span(), internal_link(), k_book_nil, k_ra8_err_no_mem, k_ra8_err_validation_failed, k_ra8_ok, xml_event_t::markup, RA8_INTERNAL, ra8_rabook_add_text(), and xml_decoded_size().

Referenced by internal_emit_event().

◆ ra8_rabook_xml_parse_chapter()

ra8_err_t ra8_rabook_xml_parse_chapter ( const uint8_t * xhtml_bytes,
size_t xhtml_len,
ra8_rabook_ctx_t * ctx,
const char * chapter_href,
const char * chapter_title,
ra8_rabook_xml_workspace_t * workspace )
nodiscard

Parse one XHTML chapter and append it to ctx.

Validates all immutable source bytes before modifying ctx. A direct <body> child among at most 256 root element children is emitted. A document exceeding that bounded search is rejected; when the complete bounded set has no body, the document root is emitted. Text and attributes are entity-decoded; inter-element whitespace is preserved; comments, PIs, and CDATA are skipped.

Parameters
[in]xhtml_bytesImmutable complete XHTML byte sequence.
[in]xhtml_lenExact readable extent of xhtml_bytes in bytes.
[in,out]ctxInitialised builder receiving one chapter on success.
[in]chapter_hrefNUL-terminated immutable chapter identity.
[in]chapter_titleNUL-terminated immutable chapter title.
[in,out]workspaceExclusive caller-owned parser and builder scratch.
Return values
k_ra8_okChapter appended.
k_ra8_err_null_ptrA required pointer is NULL.
k_ra8_err_invalid_sizexhtml_len is zero or exceeds UINT32_MAX.
k_ra8_err_validation_failedXML is malformed, too deeply nested, or exceeds the bounded body search.
k_ra8_err_no_memBuilder or attribute capacity is exhausted.
Precondition
Every source/string argument remains readable and immutable for the call.
ctx is initialized; its storage and workspace are writable, non-overlapping, and not used by another live operation.
Postcondition
Any failure restores ctx to its entry state; bytes written beyond the restored active counts and all workspace bytes are unspecified scratch.
On success the chapter is canonical and all input bytes remain unchanged.
The function performs no dynamic allocation.
Note
Thread-safe for distinct contexts and workspaces.
Since
0.1.0

Definition at line 608 of file ra8_rabook_xml_shim.c.

References ra8_rabook_ctx_t::failed, internal_emit(), internal_parse_chapter_validate_args(), internal_select(), k_book_nil, k_ra8_err_no_mem, k_ra8_err_validation_failed, k_ra8_ok, ra8_rabook_add_chapter(), ra8_rabook_intern(), ra8_rabook_xml_workspace_t::xml, and xml_validate().

Referenced by internal_compile_chapters().