|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Paged book-source layer: copy-out reads over ra8_vmem (#163). More...
#include "book_paged.h"#include <string.h>#include "book.h"#include "book_internal.h"#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_vmem.h"Go to the source code of this file.
Enumerations | |
| enum | book_paged_bound_t : uint32_t { k_book_paged_span_pad = 2U , k_book_paged_min_frame = 2U } |
| Loop-bound headroom for the frame-by-frame copy-out (NASA Rule 2). More... | |
| enum | book_image_rect_const_t : uint32_t { k_book_gray4_nib_lo = 0x0FU , k_book_gray4_nib_sh = 4U , k_book_gray4_ppb = 2U , k_book_rect_chunk_px = 512U , k_book_rect_chunk_pad = 2U } |
| 4bpp nibble packing + the per-read pixel budget (no magic numbers). More... | |
| enum | book_paged_walk_bound_t : uint32_t { k_book_paged_strbuf = 256U , k_book_paged_tagbuf = 64U , k_book_paged_pad = 2U } |
| Staging sizes and loop bounds for the paged text walk (no magic numbers). More... | |
Functions | |
| ra8_err_t | book_src_resident (book_src_t *out, const void *base, uint32_t size) |
| Bind a resident (already-inflated, fully resident) book as a source. | |
| ra8_err_t | book_src_paged (book_src_t *out, ra8_vmem_t *vm, uint32_t object_id, uint32_t frame_bytes, uint32_t size) |
| Bind a paged book source over an ::ra8_vmem cache + ::ra8_vsource object. | |
| static ra8_err_t | internal_book_src_read_paged (const book_src_t *src, uint32_t off, void *dst, uint32_t len) |
| Copy a byte range out of a paged source, frame by frame. | |
| ra8_err_t | book_src_read (const book_src_t *src, uint32_t off, void *dst, uint32_t len) |
| Copy a byte range out of a book source (resident memcpy or paged fault). | |
| static ra8_err_t | internal_book_image_row (const book_src_t *src, const book_image_t *img, uint32_t x, uint32_t ry, uint32_t w, uint8_t *out) |
Unpack one horizontal gray4 run [x, x+w) of source row ry to gray8. | |
| static ra8_err_t | internal_book_image_row_gray8 (const book_src_t *src, const book_image_t *img, uint32_t x, uint32_t ry, uint32_t w, uint8_t *out) |
Copy one horizontal gray8 run [x, x+w) of source row ry into out. | |
| ra8_err_t | book_src_image (const book_src_t *src, uint32_t idx, book_image_t *out_img) |
| Read one image descriptor out of a book source (resident or paged). | |
| ra8_err_t | book_src_image_rect (const book_src_t *src, const book_image_t *img, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t *out, uint32_t out_stride) |
| Read a sub-rectangle of a raster image (4bpp or 8bpp) as gray8, row by row. | |
| static ra8_err_t | internal_paged_node (const book_src_t *src, uint32_t idx, book_node_t *out) |
| Read one DOM node record out of a paged/resident book source by index. | |
| static ra8_err_t | internal_paged_str_short (const book_src_t *src, uint32_t abs_off, char *buf, uint32_t cap) |
| Copy a short NUL-terminated string (a tag name) out into a buffer. | |
| static bool | internal_paged_emit_run (const book_src_t *src, uint32_t abs_off, char *out, size_t cap, size_t *pos, bool *at_break, ra8_err_t *io_err) |
| Emit one text run from a paged source, collapsing whitespace. | |
| static bool | internal_paged_visit_node (const book_src_t *src, uint32_t n, char *out, size_t cap, size_t *pos, bool *at_break, uint32_t *stack, uint32_t *sp, ra8_err_t *io_err) |
| Process one popped node in the paged text walk. | |
| static bool | internal_walk_text_paged (const book_src_t *src, uint32_t root, uint32_t node_count, char *out, size_t cap, size_t *pos, ra8_err_t *io_err) |
| Bounded pre-order text walk over a paged book source. | |
| ra8_err_t | book_chapter_text_src (const book_src_t *src, uint32_t chapter_idx, char *out, size_t cap, size_t *out_len) |
| Extract one chapter's plain text from a book source (resident or paged). | |
| ra8_err_t | book_src_prefetch_chapter (const book_src_t *src, uint32_t chapter_idx) |
| Warm the cache frame holding a chapter's first content bytes, without pinning it (single-threaded read-ahead for the display-flush idle window). | |
Variables | |
| static const char *const | s_tag_paged = "book_paged" |
| Log tag for paged-source diagnostics. | |
Paged book-source layer: copy-out reads over ra8_vmem (#163).
Implements the book_src_t seam from book_paged.h. A source is either resident (a validated blob base; reads are a memcpy) or paged (an ra8_vmem cache fronting an ra8_vsource object; reads fault frames in and copy the requested slice out). book_src_read is the single primitive the DOM walkers build on; the paged path pins at most one frame at a time, so the resident working set stays bounded by the cache budget irrespective of how much of the book a chapter walk touches.
Definition in file book_paged.c.
| enum book_image_rect_const_t : uint32_t |
4bpp nibble packing + the per-read pixel budget (no magic numbers).
A k_book_image_gray4 pool byte holds two pixels; the high nibble is the even flat index, the low nibble the odd. A 4-bit sample expands to gray8 by replicating the nibble into both halves ((nib << 4) | nib). book_src_image_rect unpacks each row in spans of at most k_book_rect_chunk_px pixels so the staging buffer – and every book_src_read – stays small and bounded.
Definition at line 180 of file book_paged.c.
| enum book_paged_bound_t : uint32_t |
Loop-bound headroom for the frame-by-frame copy-out (NASA Rule 2).
A copy of len bytes spans at most ceil(len/frame_bytes) + 1 frames (a leading partial frame plus full frames); the +2 guard covers the partial head and tail so the bounded loop can never spin.
| Enumerator | |
|---|---|
| k_book_paged_span_pad | Extra frame iterations over the exact span. |
| k_book_paged_min_frame | Smallest accepted frame size (Rule-2 bound). |
Definition at line 40 of file book_paged.c.
| enum book_paged_walk_bound_t : uint32_t |
Staging sizes and loop bounds for the paged text walk (no magic numbers).
| Enumerator | |
|---|---|
| k_book_paged_strbuf | Staging chunk for a paged text run. |
| k_book_paged_tagbuf | Staging for one (short) element tag name. |
| k_book_paged_pad | Loop-bound headroom over the exact span. |
Definition at line 380 of file book_paged.c.
|
nodiscard |
Extract one chapter's plain text from a book source (resident or paged).
The source-aware counterpart of book_chapter_text(): same output contract (whitespace-collapsed text runs, a newline at each block-level element, not NUL-terminated), but reads the DOM through src so a paged book is walked frame-by-frame. In resident mode it delegates to book_chapter_text() and is byte-for-byte identical; in paged mode it copies each visited node and string out on demand, pinning only what it is reading.
| [in] | src | Bound book source. |
| [in] | chapter_idx | Spine chapter index (< src->hdr.chapter_count). |
| [out] | out | Destination text buffer (non-NULL). |
| [in] | cap | Capacity of out in bytes. |
| [out] | out_len | Receives the text byte length written. |
| k_ra8_ok | Chapter text extracted. |
| k_ra8_err_null_ptr | src, out, or out_len was NULL. |
| k_ra8_err_invalid_arg | chapter_idx is out of range. |
| k_ra8_err_invalid_size | Output did not fit cap, or DOM nesting exceeded the bounded walk stack. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). chapter_idx is less than src->hdr.chapter_count. out content is unspecified.Definition at line 681 of file book_paged.c.
References book_src_t::base, book_chapter_text(), book_src_read(), book_header_t::chapter_count, book_header_t::chapter_off, book_src_t::hdr, internal_walk_text_paged(), k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, book_header_t::node_count, RA8_CHECK_NULL_PTR, book_chapter_t::root_node, and s_tag_paged.
Referenced by sh_book_chapter_text().
|
nodiscard |
Read one image descriptor out of a book source (resident or paged).
The source-aware counterpart of the resident-only book_images() accessor: resolves image idx to its blob offset (hdr.image_off + idx * sizeof(book_image_t)) and copies the 24-byte descriptor out through book_src_read, so a paged book faults the descriptor's frame in on demand. The descriptor names the image geometry and its data_off into the image pool; feed it to book_src_image_rect to read pixels. This is the library-owned replacement for open-coding the image-table stride in a consumer.
| [in] | src | Bound book source. |
| [in] | idx | Image-table index (< src->hdr.image_count). |
| [out] | out_img | Receives the image descriptor. |
| k_ra8_ok | Descriptor copied into out_img. |
| k_ra8_err_null_ptr | src or out_img was NULL. |
| k_ra8_err_invalid_arg | idx is at or past src->hdr.image_count. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). out_img addresses writable storage for one book_image_t. out_img holds the descriptor at idx. out_img content is unspecified.Definition at line 314 of file book_paged.c.
References book_src_read(), book_src_t::hdr, book_header_t::image_count, book_header_t::image_off, k_ra8_err_invalid_arg, RA8_CHECK_NULL_PTR, and s_tag_paged.
Referenced by sh_gray4_image().
|
nodiscard |
Read a sub-rectangle of a raster image (4bpp or 8bpp) as gray8, row by row.
Owns the image-pool addressing contract so consumers do not. Both raster depths of a k_book_image_gray4 entry are served, selected by the descriptor's book_image_pixfmt_t, and both yield one gray8 byte per output pixel so the renderer sees a single depth:
The per-call read stays bounded by the rectangle regardless of the image width (book_src_read itself faults a paged source frame-by-frame), so the whole pool is never inflated. Rows are written at out_stride intervals, so out may be a window into a wider buffer.
| [in] | src | Bound book source. |
| [in] | img | Image descriptor from book_src_image (format must be k_book_image_gray4; pixel_format selects the gray4 vs gray8 unpack). |
| [in] | x | Sub-rect left edge in source pixels (x + w <= img->width). |
| [in] | y | Sub-rect top edge in source pixels (y + h <= img->height). |
| [in] | w | Sub-rect width in pixels (> 0, <= out_stride). |
| [in] | h | Sub-rect height in pixels (> 0). |
| [out] | out | Destination gray8 buffer (>= out_stride * h bytes). |
| [in] | out_stride | Bytes between successive output rows (>= w). |
| k_ra8_ok | The wxh window was read into out as gray8. |
| k_ra8_err_null_ptr | src, img, or out was NULL. |
| k_ra8_err_invalid_arg | img is not a raster (SVG), its pixel_format is neither gray4 nor gray8, or w == 0, h == 0, or out_stride < w. |
| k_ra8_err_out_of_range | The sub-rect leaves the image, or the pool span it addresses leaves the blob. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). out addresses at least out_stride * h writable bytes. out content is unspecified.Definition at line 325 of file book_paged.c.
References book_image_pixfmt(), book_image_t::format, book_image_t::height, internal_book_image_row(), internal_book_image_row_gray8(), k_book_image_gray4, k_book_pixfmt_gray4, k_book_pixfmt_gray8, k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag_paged, and book_image_t::width.
Referenced by sh_gray4_fetch_row(), and sh_loupe_stage().
|
nodiscard |
Bind a paged book source over an ::ra8_vmem cache + ::ra8_vsource object.
The demand-fetch path for books that do not fit the resident budget. The caller has already registered the book's bytes as an ::ra8_vsource paged (or XIP) object and initialised vm with ra8_vsource_loader. This reads the 100-byte header through the cache into book_src_t::hdr so header fields never fault thereafter.
| [out] | out | Source to populate (caller-owned). |
| [in] | vm | Initialised page cache fronting the book object (non-NULL). |
| [in] | object_id | The book's ::ra8_vsource object id within vm's loader. |
| [in] | frame_bytes | vm's frame size in bytes (>= 2); used for slice math. |
| [in] | size | Blob length in bytes (> 0, == header total_size). |
| k_ra8_ok | Source bound in paged mode; header cached. |
| k_ra8_err_null_ptr | out or vm was NULL. |
| k_ra8_err_invalid_size | size was zero or frame_bytes was < 2. |
| k_ra8_err_* | A page fault while reading the header (verbatim). |
vm was initialised with the book registered at object_id. frame_bytes equals the frame size vm was configured with. out is left unbound.vm's pin/evict state is mutated by reads. Definition at line 61 of file book_paged.c.
References book_src_t::base, book_src_read(), book_src_t::frame_bytes, book_src_t::hdr, k_book_paged_min_frame, k_ra8_err_invalid_size, book_src_t::object_id, RA8_CHECK_NULL_PTR, s_tag_paged, book_src_t::size, and book_src_t::vm.
Referenced by sh_paged_bind().
|
nodiscard |
Warm the cache frame holding a chapter's first content bytes, without pinning it (single-threaded read-ahead for the display-flush idle window).
The reader-facing wrapper #207 wires into the flush-idle window: after rendering the current page and issuing the panel flush, warm the adjacent chapters (N+1 for forward reading, N-1 for a back-flip) so the next chapter-crossing page turn finds them resident. Resolves chapter_idx to the byte offset of its root DOM node – the first content range book_chapter_text_src reads for that chapter – and hands it to ra8_vmem_prefetch, which does a bounded get+put so the page ends resident but unpinned (SLRU/2Q probationary: a wrong read-ahead guess ages out before hot data, no prefetch backfire on a fast skim). Best-effort and transparent: warming only changes cache residency, never the bytes a later read returns, so rendered output is unchanged. Resident sources are already wholly in RAM and are rejected as a no-op.
| [in] | src | Bound (paged) book source. |
| [in] | chapter_idx | Spine chapter index to warm (< src->hdr.chapter_count). |
| k_ra8_ok | The chapter's root-node frame is resident, unpinned. |
| k_ra8_err_null_ptr | src was NULL. |
| k_ra8_err_invalid_state | src is resident (or unbound): nothing to page. |
| k_ra8_err_invalid_arg | chapter_idx is out of range. |
| k_ra8_err_* | A chapter-record read or the warm faulted (verbatim). |
src was populated by book_src_paged() (paged mode, src->vm != NULL). Definition at line 721 of file book_paged.c.
References book_src_read(), book_header_t::chapter_count, book_header_t::chapter_off, book_src_t::hdr, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, book_header_t::node_off, book_src_t::object_id, RA8_CHECK_NULL_PTR, ra8_vmem_prefetch(), book_chapter_t::root_node, s_tag_paged, and book_src_t::vm.
Referenced by sh_reader_prefetch_adjacent().
|
nodiscard |
Copy a byte range out of a book source (resident memcpy or paged fault).
The single read primitive both modes share. Resident mode is a memcpy(dst, base + off, len). Paged mode walks the range frame by frame: ra8_vmem_get pins the frame holding the current offset, the overlapping slice is copied to dst, and ra8_vmem_put releases it before advancing – so at most one frame is pinned at a time and the resident working set stays bounded regardless of len.
| [in] | src | Bound book source. |
| [in] | off | Byte offset within the blob (off + len <= src->size). |
| [out] | dst | Destination buffer receiving len bytes (non-NULL). |
| [in] | len | Number of bytes to copy. |
| k_ra8_ok | Bytes copied into dst. |
| k_ra8_err_null_ptr | src or dst was NULL. |
| k_ra8_err_invalid_state | src is bound to neither mode. |
| k_ra8_err_out_of_range | off + len exceeds src->size. |
| k_ra8_err_* | A page fault (paged mode only; returned verbatim). |
src was populated by book_src_resident() / book_src_paged(). dst addresses at least len writable bytes. off. dst content is unspecified and no pin is held.Definition at line 141 of file book_paged.c.
References book_src_t::base, internal_book_src_read_paged(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_ok, memcpy(), RA8_CHECK_NULL_PTR, s_tag_paged, book_src_t::size, and book_src_t::vm.
Referenced by book_chapter_text_src(), book_src_image(), book_src_paged(), book_src_prefetch_chapter(), internal_book_image_row(), internal_book_image_row_gray8(), internal_paged_emit_run(), internal_paged_node(), internal_paged_str_short(), sh_rabook_label(), and sh_src_string().
|
nodiscard |
Bind a resident (already-inflated, fully resident) book as a source.
The zero-copy fast path: book_src_t::base is set to base and reads become base + off, byte-for-byte identical to the book.h accessors. The header is copied into book_src_t::hdr.
| [out] | out | Source to populate (caller-owned). |
| [in] | base | Validated .rabook blob base (non-NULL), as from book_open(). |
| [in] | size | Blob length in bytes (> 0, == header total_size). |
| k_ra8_ok | Source bound in resident mode. |
| k_ra8_err_null_ptr | out or base was NULL. |
| k_ra8_err_invalid_size | size was zero. |
base was accepted by book_validate() / book_open(). out points at writable storage out-living the reads. out is left unbound.Definition at line 45 of file book_paged.c.
References book_src_t::base, book_src_t::frame_bytes, book_src_t::hdr, k_ra8_err_invalid_size, k_ra8_ok, memcpy(), book_src_t::object_id, RA8_CHECK_NULL_PTR, s_tag_paged, book_src_t::size, and book_src_t::vm.
|
static |
Unpack one horizontal gray4 run [x, x+w) of source row ry to gray8.
The per-row worker of book_src_image_rect. Walks the run in spans of at most k_book_rect_chunk_px pixels: each span's flat nibble index maps to an absolute pool offset (image_pool_off + data_off + (flat >> 1)), the packed span is copied out via book_src_read (bounds-checked, paged-fault-aware), and each 4-bit sample is replicated into a gray8 byte. Tracking the absolute flat index per pixel keeps the high/low nibble parity correct across span boundaries and for odd image widths.
| [in] | src | Bound book source. |
| [in] | img | Gray4 image descriptor (caller already checked the format). |
| [in] | x | Run left edge in source pixels (x + w <= img->width). |
| [in] | ry | Source row index (< img->height). |
| [in] | w | Run width in pixels (> 0). |
| [out] | out | Destination gray8 run (>= w bytes). |
| k_ra8_ok | The run was unpacked into out. |
| k_ra8_err_out_of_range | A span it addresses leaves the blob. |
| k_ra8_err_* | A book_src_read fault (returned verbatim). |
src is bound and img is a gray4 descriptor within src. out addresses at least w writable bytes. out content is unspecified.Definition at line 220 of file book_paged.c.
References book_src_read(), book_image_t::data_off, book_src_t::hdr, book_header_t::image_pool_off, k_book_gray4_nib_lo, k_book_gray4_nib_sh, k_book_gray4_ppb, k_book_rect_chunk_pad, k_book_rect_chunk_px, k_ra8_err_out_of_range, k_ra8_ok, RA8_INTERNAL, book_src_t::size, and book_image_t::width.
Referenced by book_src_image_rect().
|
static |
Copy one horizontal gray8 run [x, x+w) of source row ry into out.
The per-row worker of book_src_image_rect for a k_book_pixfmt_gray8 raster (the full-resolution, continuous-tone representation the compiled .rabook retains for zoomable content, #476). At 8bpp there is no nibble packing: pixel (px, py) is one byte at flat index py * width + px, so the run maps to a single contiguous pool span [image_pool_off + data_off + (ry * width + x), + w) that is copied straight into out via book_src_read – which is itself bounded (a paged source faults the covering frames in one at a time), so no unpack staging buffer and no per-span loop are needed here.
| [in] | src | Bound book source. |
| [in] | img | Gray8 image descriptor (caller already checked format + depth). |
| [in] | x | Run left edge in source pixels (x + w <= img->width). |
| [in] | ry | Source row index (< img->height). |
| [in] | w | Run width in pixels (> 0). |
| [out] | out | Destination gray8 run (>= w bytes). |
| k_ra8_ok | The run was copied into out. |
| k_ra8_err_out_of_range | The pool span it addresses leaves the blob. |
| k_ra8_err_* | A book_src_read fault (returned verbatim). |
src is bound and img is a gray8 descriptor within src. out addresses at least w writable bytes. out content is unspecified.Definition at line 296 of file book_paged.c.
References book_src_read(), book_image_t::data_off, book_src_t::hdr, book_header_t::image_pool_off, k_ra8_err_out_of_range, RA8_INTERNAL, book_src_t::size, and book_image_t::width.
Referenced by book_src_image_rect().
|
static |
Copy a byte range out of a paged source, frame by frame.
The demand-fetch worker behind book_src_read: walks len bytes at off through the cache, pinning the frame holding the current offset (ra8_vmem_get), copying the overlapping slice, and releasing it (ra8_vmem_put) before advancing – one frame pinned at a time. The loop is bounded by len / frame_bytes + 2 (frame_bytes >= 2 is enforced at bind time, so the bound never overflows).
| [in] | src | Paged source (src->vm non-NULL, src->base NULL). |
| [in] | off | Byte offset within the blob (range already validated). |
| [out] | dst | Destination buffer receiving len bytes. |
| [in] | len | Number of bytes to copy (non-zero). |
| k_ra8_ok | All len bytes copied into dst. |
| k_ra8_err_out_of_range | The loop drained before len bytes (unreachable for a valid range / frame_bytes >= 2). |
| k_ra8_err_* | A ra8_vmem_get / ra8_vmem_put fault (verbatim). |
src is paged and off + len <= src->size. dst addresses at least len writable bytes. off; no pin is held. dst content is unspecified and no pin is held.Definition at line 114 of file book_paged.c.
References book_src_t::frame_bytes, k_book_paged_span_pad, k_ra8_err_out_of_range, k_ra8_ok, memcpy(), book_src_t::object_id, ra8_vmem_get(), ra8_vmem_put(), and book_src_t::vm.
Referenced by book_src_read().
|
static |
Emit one text run from a paged source, collapsing whitespace.
Streams the NUL-terminated run at abs_off through a staging buffer in k_book_paged_strbuf-sized chunks, calling the shared priv_book_emit_text on each chunk. Chunking keeps the resident footprint bounded for arbitrarily long runs; the at_break flag threads across chunks so whitespace collapsing is identical to the resident single-pass walk.
| [in] | src | Bound book source. |
| [in] | abs_off | Absolute blob offset of the NUL-terminated run. |
| [out] | out | Destination text buffer. |
| [in] | cap | Capacity of out in bytes. |
| [in,out] | pos | Current write offset; advanced as text is emitted. |
| [in,out] | at_break | Whitespace-collapse carry flag threaded across chunks. |
| [out] | io_err | Set to the fault code on a read fault; untouched otherwise. |
| true | The whole run was emitted; *io_err is unchanged. |
| false | Output buffer overflowed (io_err untouched), or a page fault occurred (*io_err set to the fault code). |
src is bound; out has room for cap bytes. pos and at_break are non-null and valid. Definition at line 498 of file book_paged.c.
References book_src_read(), k_book_paged_pad, k_book_paged_strbuf, k_ra8_ok, priv_book_emit_text(), RA8_INTERNAL, and book_src_t::size.
Referenced by internal_paged_visit_node().
|
static |
Read one DOM node record out of a paged/resident book source by index.
Translates the node index to its blob byte offset (node_off + idx * sizeof(book_node_t)) and copies the 24-byte record out via book_src_read, which bounds-checks the range and faults the frame in for a paged source.
| [in] | src | Bound book source. |
| [in] | idx | Node-table index to read. |
| [out] | out | Receives the node record. |
| k_ra8_ok | Node copied into out. |
| k_ra8_err_out_of_range | idx lies outside the node table. |
| k_ra8_err_* | A book_src_read fault (returned verbatim). |
src is bound and out is writable. idx is intended to index a valid node (verified by the read bounds). out holds the node at idx. out content is unspecified.Definition at line 412 of file book_paged.c.
References book_src_read(), book_src_t::hdr, and book_header_t::node_off.
Referenced by internal_paged_visit_node().
|
static |
Copy a short NUL-terminated string (a tag name) out into a buffer.
Reads up to cap - 1 bytes at abs_off and NUL-terminates at the first embedded NUL or at the buffer end. Used for element tag names, which are short; a name longer than the buffer is truncated, which at worst makes priv_book_is_block treat it as inline (no break) – never a correctness issue for real markup.
| [in] | src | Bound book source. |
| [in] | abs_off | Absolute blob offset of the string start. |
| [out] | buf | Destination buffer (>= cap bytes). |
| [in] | cap | Capacity of buf in bytes (>= 1). |
| k_ra8_ok | String (possibly truncated) copied + terminated. |
| k_ra8_err_out_of_range | abs_off is at or past the blob end. |
| k_ra8_err_* | A book_src_read fault (returned verbatim). |
src is bound and buf has room for cap bytes. cap is at least one (for the NUL terminator). buf is a NUL-terminated string. buf content is unspecified.Definition at line 447 of file book_paged.c.
References book_src_read(), k_ra8_err_out_of_range, k_ra8_ok, and book_src_t::size.
Referenced by internal_paged_visit_node().
|
static |
Process one popped node in the paged text walk.
The per-node body of internal_walk_text_paged, split out to keep both functions within the size/complexity budget. Reads the node, pushes its sibling, then either emits a text run (internal_paged_emit_run) or, for an element, inserts a block break (priv_book_is_block over a staged tag name) and pushes its first child. Mutates the caller's stack/sp and whitespace-collapse at_break in place.
| [in] | src | Bound (paged) book source. |
| [in] | n | Node index to visit (already non-nil). |
| [out] | out | Destination plain-text buffer. |
| [in] | cap | Capacity of out in bytes. |
| [in,out] | pos | Current write offset; advanced as text is emitted. |
| [in,out] | at_break | Whitespace-collapse carry flag. |
| [in,out] | stack | Caller walk stack of length k_book_xhtml_stack. |
| [in,out] | sp | Stack pointer (live entry count); pushed up to twice. |
| [out] | io_err | Set to the fault code on a read fault; untouched otherwise. |
| true | Node handled; the walk may continue. |
| false | Output overflow, stack full, or a read fault (see io_err). |
src is paged; n indexes a node in the blob. stack / sp / at_break are the walk's live state. io_err is set iff a fault occurred.Definition at line 570 of file book_paged.c.
References book_node_t::first_child, book_src_t::hdr, internal_paged_emit_run(), internal_paged_node(), internal_paged_str_short(), k_book_node_text, k_book_paged_tagbuf, k_book_xhtml_stack, k_ra8_ok, book_node_t::kind, book_node_t::name_off, book_node_t::next_sibling, priv_book_emit_break(), priv_book_is_block(), RA8_INTERNAL, book_header_t::string_off, and book_node_t::text_off.
Referenced by internal_walk_text_paged().
|
static |
Bounded pre-order text walk over a paged book source.
The paged counterpart of internal_walk_text(): identical iterative, recursion-free pre-order traversal and identical output, dispatching each popped node to internal_paged_visit_node. At most one cache frame is pinned at a time, so the resident working set stays bounded.
| [in] | src | Bound (paged) book source. |
| [in] | root | Node index of the subtree root. |
| [in] | node_count | Total node count, for the iteration guard. |
| [out] | out | Destination plain-text buffer. |
| [in] | cap | Capacity of out in bytes. |
| [in,out] | pos | Current write offset; advanced as text is emitted. |
| [out] | io_err | Set to the fault code on a read fault; k_ra8_ok otherwise. |
| true | Subtree fully serialised (check io_err for a clean run). |
| false | Overflow, stack/guard exhaustion, or a read fault (see io_err). |
src is a paged source bound by book_src_paged(). root is a node index within the blob. out holds the chapter text. Definition at line 648 of file book_paged.c.
References internal_paged_visit_node(), k_book_nil, k_book_xhtml_iter_x, k_book_xhtml_stack, and RA8_INTERNAL.
Referenced by book_chapter_text_src().
|
static |
Log tag for paged-source diagnostics.
Definition at line 30 of file book_paged.c.
Referenced by book_chapter_text_src(), book_src_image(), book_src_image_rect(), book_src_paged(), book_src_prefetch_chapter(), book_src_read(), and book_src_resident().