ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
book_paged.c
Go to the documentation of this file.
1
19#include "book_paged.h"
20
21#include <string.h>
22
23#include "book.h"
24#include "book_internal.h"
25#include "ra8_attributes.h"
26#include "ra8_check.h"
27#include "ra8_vmem.h"
28
30static const char* const s_tag_paged = "book_paged";
31
44
45ra8_err_t book_src_resident(book_src_t* out, const void* base, uint32_t size)
46{
47 RA8_CHECK_NULL_PTR(out, s_tag_paged, "resident: null out");
48 RA8_CHECK_NULL_PTR(base, s_tag_paged, "resident: null base");
49 if (size == 0U) {
51 }
52 out->base = (const uint8_t*)base;
53 out->vm = nullptr;
54 out->object_id = 0U;
55 out->frame_bytes = 0U;
56 out->size = size;
57 (void)memcpy(&out->hdr, base, sizeof(book_header_t));
58 return k_ra8_ok;
59}
60
62 ra8_vmem_t* vm,
63 uint32_t object_id,
64 uint32_t frame_bytes,
65 uint32_t size)
66{
67 RA8_CHECK_NULL_PTR(out, s_tag_paged, "paged: null out");
68 RA8_CHECK_NULL_PTR(vm, s_tag_paged, "paged: null vm");
69 /* frame_bytes >= 2 keeps the copy-out loop bound (len/frame_bytes + 2)
70 * provably non-overflowing for any uint32_t len. */
71 if ((size == 0U) || (frame_bytes < (uint32_t)k_book_paged_min_frame)) {
73 }
74 out->base = nullptr;
75 out->vm = vm;
76 out->object_id = object_id;
77 out->frame_bytes = frame_bytes;
78 out->size = size;
79 /* Cache the header so its fields never fault during a walk. */
80 return book_src_read(out, 0U, &out->hdr, (uint32_t)sizeof(book_header_t));
81}
82
113static ra8_err_t
114internal_book_src_read_paged(const book_src_t* src, uint32_t off, void* dst, uint32_t len)
115{
116 uint8_t* d = (uint8_t*)dst;
117 uint32_t cur = off;
118 uint32_t remaining = len;
119 const uint32_t max_iter = (len / src->frame_bytes) + (uint32_t)k_book_paged_span_pad;
120 for (uint32_t it = 0U; (it < max_iter) && (remaining > 0U); ++it) {
121 void* page = nullptr;
122 const ra8_err_t ge = ra8_vmem_get(src->vm, src->object_id, (uint64_t)cur, &page);
123 if (ge != k_ra8_ok) {
124 return ge;
125 }
126 const uint32_t in_frame = cur % src->frame_bytes;
127 const uint32_t avail = src->frame_bytes - in_frame;
128 const uint32_t n = (remaining < avail) ? remaining : avail;
129 (void)memcpy(d, &((const uint8_t*)page)[in_frame], n);
130 const ra8_err_t pe = ra8_vmem_put(src->vm, page);
131 if (pe != k_ra8_ok) {
132 return pe;
133 }
134 d = &d[n];
135 cur += n;
136 remaining -= n;
137 }
138 return (remaining == 0U) ? k_ra8_ok : k_ra8_err_out_of_range;
139}
140
141ra8_err_t book_src_read(const book_src_t* src, uint32_t off, void* dst, uint32_t len)
142{
143 RA8_CHECK_NULL_PTR(src, s_tag_paged, "read: null src");
144 RA8_CHECK_NULL_PTR(dst, s_tag_paged, "read: null dst");
145 if (((uint64_t)off + (uint64_t)len) > (uint64_t)src->size) {
147 }
148 if (len == 0U) {
149 return k_ra8_ok;
150 }
151 if (src->base != nullptr) {
152 (void)memcpy(dst, &src->base[off], len);
153 return k_ra8_ok;
154 }
155 if (src->vm == nullptr) {
157 }
158 return internal_book_src_read_paged(src, off, dst, len);
159}
160
161/* ===========================================================================
162 * Image sub-rect reads (#342): the image-pool addressing contract -- descriptor
163 * stride, pool base, 4bpp nibble packing, and odd-width parity -- lives here in
164 * the library that owns the format, not open-coded in every image renderer. The
165 * loupe / tile / thumbnail consumers keep only their geometry and blit and call
166 * book_src_image_rect() for "read me this rectangle" as unpacked gray8.
167 * =========================================================================== */
168
187
221 const book_image_t* img,
222 uint32_t x,
223 uint32_t ry,
224 uint32_t w,
225 uint8_t* out)
226{
227 const uint32_t row_flat = (ry * (uint32_t)img->width) + x;
228 uint8_t packed[(k_book_rect_chunk_px / k_book_gray4_ppb) + 1U];
229 uint32_t done = 0U;
230 const uint32_t max_iter = (w / (uint32_t)k_book_rect_chunk_px) + (uint32_t)k_book_rect_chunk_pad;
231 for (uint32_t it = 0U; it < max_iter; ++it) {
232 if (done >= w) {
233 break; /* whole run unpacked; the count bound above is the loop invariant */
234 }
235 const uint32_t remain = w - done;
236 const uint32_t cpx =
237 (remain < (uint32_t)k_book_rect_chunk_px) ? remain : (uint32_t)k_book_rect_chunk_px;
238 const uint32_t flat0 = row_flat + done;
239 const uint32_t first = flat0 >> 1U;
240 const uint32_t last = (flat0 + cpx - 1U) >> 1U;
241 const uint32_t n = (last - first) + 1U;
242 const uint64_t off =
243 (uint64_t)src->hdr.image_pool_off + (uint64_t)img->data_off + (uint64_t)first;
244 if ((off + (uint64_t)n) > (uint64_t)src->size) {
245 return k_ra8_err_out_of_range; /* descriptor / geometry points past the blob */
246 }
247 const ra8_err_t re = book_src_read(src, (uint32_t)off, packed, n);
248 if (re != k_ra8_ok) {
249 return re;
250 }
251 for (uint32_t i = 0U; i < cpx; ++i) {
252 const uint32_t flat = flat0 + i;
253 const uint8_t byte = packed[(flat >> 1U) - first];
254 const uint8_t nib = ((flat & 1U) != 0U) ? (uint8_t)(byte & (uint8_t)k_book_gray4_nib_lo)
255 : (uint8_t)(byte >> (uint8_t)k_book_gray4_nib_sh);
256 out[done + i] = (uint8_t)((nib << (uint8_t)k_book_gray4_nib_sh) | nib);
257 }
258 done += cpx;
259 }
260 return (done == w) ? k_ra8_ok : k_ra8_err_out_of_range;
261}
262
297 const book_image_t* img,
298 uint32_t x,
299 uint32_t ry,
300 uint32_t w,
301 uint8_t* out)
302{
303 const uint32_t row_flat = (ry * (uint32_t)img->width) + x;
304 const uint64_t off =
305 (uint64_t)src->hdr.image_pool_off + (uint64_t)img->data_off + (uint64_t)row_flat;
306 /* Single exit (MISRA 15.5): a span leaving the blob is an out-of-range read. */
307 ra8_err_t re = k_ra8_err_out_of_range; /* descriptor / geometry points past the blob */
308 if ((off + (uint64_t)w) <= (uint64_t)src->size) {
309 re = book_src_read(src, (uint32_t)off, out, w);
310 }
311 return re;
312}
313
314ra8_err_t book_src_image(const book_src_t* src, uint32_t idx, book_image_t* out_img)
315{
316 RA8_CHECK_NULL_PTR(src, s_tag_paged, "image: null src");
317 RA8_CHECK_NULL_PTR(out_img, s_tag_paged, "image: null out_img");
318 if (idx >= src->hdr.image_count) {
320 }
321 const uint32_t off = src->hdr.image_off + (idx * (uint32_t)sizeof(book_image_t));
322 return book_src_read(src, off, out_img, (uint32_t)sizeof(book_image_t));
323}
324
326 const book_image_t* img,
327 uint32_t x,
328 uint32_t y,
329 uint32_t w,
330 uint32_t h,
331 uint8_t* out,
332 uint32_t out_stride)
333{
334 RA8_CHECK_NULL_PTR(src, s_tag_paged, "image_rect: null src");
335 RA8_CHECK_NULL_PTR(img, s_tag_paged, "image_rect: null img");
336 RA8_CHECK_NULL_PTR(out, s_tag_paged, "image_rect: null out");
337 /* Readable raster of a known depth (one decision, single exit -- MISRA 15.5):
338 * SVG has no pixel grid, and only the two grayscale depths are unpackable --
339 * gray4 nibble-unpacks 2px/byte, gray8 copies 1px/byte verbatim (the retained
340 * full-resolution continuous-tone source, #343/#476). book_validate()
341 * already refuses any other depth; this also guards a corrupt descriptor. */
343 if ((img->format != (uint8_t)k_book_image_gray4) ||
344 ((pf != k_book_pixfmt_gray4) && (pf != k_book_pixfmt_gray8))) {
346 }
347 if ((w == 0U) || (h == 0U) || (out_stride < w)) {
349 }
350 if ((((uint64_t)x + (uint64_t)w) > (uint64_t)img->width) ||
351 (((uint64_t)y + (uint64_t)h) > (uint64_t)img->height)) {
352 return k_ra8_err_out_of_range; /* sub-rect not fully inside the image */
353 }
354 const bool is_gray8 = (pf == k_book_pixfmt_gray8);
355 for (uint32_t row = 0U; row < h; ++row) {
356 uint8_t* const dst = &out[(size_t)row * (size_t)out_stride];
357 const ra8_err_t re = is_gray8 ? internal_book_image_row_gray8(src, img, x, y + row, w, dst)
358 : internal_book_image_row(src, img, x, y + row, w, dst);
359 if (re != k_ra8_ok) {
360 return re;
361 }
362 }
363 return k_ra8_ok;
364}
365
366/* ===========================================================================
367 * Paged plain-text extraction (#163): same output as book_chapter_text but
368 * the DOM is read frame-by-frame through an book_src_t / ra8_vmem cache, so a
369 * book that exceeds the resident budget is walked with a bounded working set.
370 * The resident path above is untouched; these helpers reuse the shared,
371 * source-agnostic emit_text / emit_break / is_block leaf helpers on staging
372 * buffers, so paged output is byte-for-byte identical to the resident walk.
373 * =========================================================================== */
374
385
412internal_paged_node(const book_src_t* src, uint32_t idx, book_node_t* out)
413{
414 const uint32_t off = src->hdr.node_off + (idx * (uint32_t)sizeof(book_node_t));
415 return book_src_read(src, off, out, (uint32_t)sizeof(book_node_t));
416}
417
446static ra8_err_t
447internal_paged_str_short(const book_src_t* src, uint32_t abs_off, char* buf, uint32_t cap)
448{
449 if (abs_off >= src->size) {
451 }
452 const uint32_t remain = src->size - abs_off;
453 const uint32_t want = cap - 1U;
454 const uint32_t chunk = (remain < want) ? remain : want;
455 const ra8_err_t re = book_src_read(src, abs_off, buf, chunk);
456 if (re != k_ra8_ok) {
457 return re;
458 }
459 uint32_t nlen = 0U;
460 while ((nlen < chunk) && (buf[nlen] != '\0')) {
461 ++nlen;
462 }
463 buf[nlen] = '\0';
464 return k_ra8_ok;
465}
466
499 uint32_t abs_off,
500 char* out,
501 size_t cap,
502 size_t* pos,
503 bool* at_break,
504 ra8_err_t* io_err)
505{
506 char buf[k_book_paged_strbuf];
507 uint32_t off = abs_off;
508 const uint32_t max_iter =
509 (src->size / (uint32_t)(k_book_paged_strbuf - 1U)) + (uint32_t)k_book_paged_pad;
510 for (uint32_t it = 0U; it < max_iter; ++it) {
511 if (off >= src->size) {
512 return true; /* Ran to blob end without a NUL (degenerate); treat as done. */
513 }
514 const uint32_t remain = src->size - off;
515 const uint32_t want = (uint32_t)(k_book_paged_strbuf - 1U);
516 const uint32_t chunk = (remain < want) ? remain : want;
517 const ra8_err_t re = book_src_read(src, off, buf, chunk);
518 if (re != k_ra8_ok) {
519 *io_err = re;
520 return false;
521 }
522 uint32_t nlen = 0U;
523 while ((nlen < chunk) && (buf[nlen] != '\0')) {
524 ++nlen;
525 }
526 buf[nlen] = '\0';
527 if (!priv_book_emit_text(out, cap, pos, buf, at_break)) {
528 return false; /* Output overflow. */
529 }
530 if (nlen < chunk) {
531 return true; /* Hit the real NUL terminator. */
532 }
533 off += nlen; /* nlen == chunk: advance and read the next chunk. */
534 }
535 return true;
536}
537
571 uint32_t n,
572 char* out,
573 size_t cap,
574 size_t* pos,
575 bool* at_break,
576 uint32_t* stack,
577 uint32_t* sp,
578 ra8_err_t* io_err)
579{
580 book_node_t node = {};
581 const ra8_err_t ne = internal_paged_node(src, n, &node);
582 if (ne != k_ra8_ok) {
583 *io_err = ne;
584 return false;
585 }
586 if (*sp >= k_book_xhtml_stack) {
587 return false;
588 }
589 stack[*sp] = node.next_sibling; /* sibling chain after this subtree */
590 *sp += 1U;
591 if (node.kind == (uint8_t)k_book_node_text) {
592 return internal_paged_emit_run(src,
593 src->hdr.string_off + node.text_off,
594 out,
595 cap,
596 pos,
597 at_break,
598 io_err);
599 }
600 char tag[k_book_paged_tagbuf] = {};
601 const ra8_err_t te = internal_paged_str_short(src,
602 src->hdr.string_off + node.name_off,
603 tag,
604 (uint32_t)k_book_paged_tagbuf);
605 if (te != k_ra8_ok) {
606 *io_err = te;
607 return false;
608 }
609 bool ok = true;
610 if (priv_book_is_block(tag)) {
611 ok = priv_book_emit_break(out, cap, pos, at_break);
612 }
613 if (ok && (*sp < k_book_xhtml_stack)) {
614 stack[*sp] = node.first_child; /* descend, pre-order */
615 *sp += 1U;
616 }
617 return ok;
618}
619
649 uint32_t root,
650 uint32_t node_count,
651 char* out,
652 size_t cap,
653 size_t* pos,
654 ra8_err_t* io_err)
655{
656 /* Explicit DFS stack (2 KiB) kept in module-static storage so this frame
657 * stays within the stack-usage budget; iterative (no recursion) and
658 * single-threaded, so the shared buffer never overlaps. */
659 static uint32_t s_paged_stack[k_book_xhtml_stack];
660 uint32_t* stack = s_paged_stack;
661 uint32_t sp = 0U;
662 bool ok = true;
663 bool at_break = true;
664 stack[sp] = root;
665 sp += 1U;
666
667 const uint32_t max_iter = (node_count * k_book_xhtml_iter_x) + k_book_xhtml_stack;
668 uint32_t guard = 0U;
669 while ((sp > 0U) && ok && (guard < max_iter)) {
670 ++guard;
671 sp -= 1U;
672 const uint32_t n = stack[sp];
673 if (n == k_book_nil) {
674 continue;
675 }
676 ok = internal_paged_visit_node(src, n, out, cap, pos, &at_break, stack, &sp, io_err);
677 }
678 return ok && (guard < max_iter);
679}
680
682 uint32_t chapter_idx,
683 char* out,
684 size_t cap,
685 size_t* out_len)
686{
687 RA8_CHECK_NULL_PTR(src, s_tag_paged, "text_src: null src");
688 RA8_CHECK_NULL_PTR(out, s_tag_paged, "text_src: null out");
689 RA8_CHECK_NULL_PTR(out_len, s_tag_paged, "text_src: null out_len");
690
691 if (chapter_idx >= src->hdr.chapter_count) {
693 }
694 /* Resident source: delegate to the untouched, byte-identical fast path. */
695 if (src->base != nullptr) {
696 return book_chapter_text(src->base, chapter_idx, out, cap, out_len);
697 }
698
699 /* Paged source: read the chapter record, then walk the DOM frame-by-frame. */
700 book_chapter_t chap = {};
701 const uint32_t coff = src->hdr.chapter_off + (chapter_idx * (uint32_t)sizeof(book_chapter_t));
702 const ra8_err_t ce = book_src_read(src, coff, &chap, (uint32_t)sizeof(book_chapter_t));
703 if (ce != k_ra8_ok) {
704 return ce;
705 }
706 size_t pos = 0U;
707 ra8_err_t io_err = k_ra8_ok;
709 chap.root_node,
710 src->hdr.node_count,
711 out,
712 cap,
713 &pos,
714 &io_err)) {
715 return (io_err != k_ra8_ok) ? io_err : k_ra8_err_invalid_size;
716 }
717 *out_len = pos;
718 return k_ra8_ok;
719}
720
721ra8_err_t book_src_prefetch_chapter(const book_src_t* src, uint32_t chapter_idx)
722{
723 RA8_CHECK_NULL_PTR(src, s_tag_paged, "prefetch: null src");
724 /* Prefetch warms a paged cache; a resident (or unbound) source has no cache. */
725 if (src->vm == nullptr) {
727 }
728 if (chapter_idx >= src->hdr.chapter_count) {
730 }
731 /* Resolve the chapter's root DOM node: the first content range
732 * book_chapter_text_src() reads for this chapter. Reading the record here
733 * also warms the chapter-table frame the same walk touches first. */
734 book_chapter_t chap = {};
735 const uint32_t coff = src->hdr.chapter_off + (chapter_idx * (uint32_t)sizeof(book_chapter_t));
736 const ra8_err_t ce = book_src_read(src, coff, &chap, (uint32_t)sizeof(book_chapter_t));
737 if (ce != k_ra8_ok) {
738 return ce;
739 }
740 /* uint64 offset math cannot overflow; an out-of-range root_node simply faults
741 * in the loader and is returned verbatim (best-effort, nothing warmed). */
742 const uint64_t noff =
743 (uint64_t)src->hdr.node_off + ((uint64_t)chap.root_node * sizeof(book_node_t));
744 return ra8_vmem_prefetch(src->vm, src->object_id, noff);
745}
Flat, execute-in-place container for a build-time "compiled" e-book.
ra8_err_t book_chapter_text(const void *base, uint32_t chapter_idx, char *out, size_t cap, size_t *out_len)
Extract one chapter's readable plain text from the DOM.
Definition book_xhtml.c:683
@ k_book_node_text
A text run: carries a string, no children.
Definition book.h:163
@ k_book_nil
Absent index / "applies to all chapters".
Definition book.h:129
@ k_book_image_gray4
4bpp gray, 2px/byte; pixel (x,y) is at flat index y*width + x.
Definition book.h:175
static book_image_pixfmt_t book_image_pixfmt(const book_image_t *img)
Declared pixel depth of one image descriptor.
Definition book.h:599
book_image_pixfmt_t
Pixel depth of a k_book_image_gray4 raster in the image pool.
Definition book.h:212
@ k_book_pixfmt_gray4
4bpp packed grayscale, 2px/byte (default; every pre-field blob).
Definition book.h:213
@ k_book_pixfmt_gray8
8bpp grayscale, 1px/byte (lossless against any grey panel).
Definition book.h:215
book DOM-walk helpers shared across the library's translation units.
bool priv_book_is_block(const char *name)
Test whether an element name is a block-level HTML element.
Definition book_xhtml.c:470
bool priv_book_emit_break(char *out, size_t cap, size_t *pos, bool *at_break)
Append a paragraph break, collapsing consecutive block-level breaks.
Definition book_xhtml.c:583
bool priv_book_emit_text(char *out, size_t cap, size_t *pos, const char *str, bool *at_break)
Append a whitespace-collapsed text run to the output buffer.
Definition book_xhtml.c:526
@ k_book_xhtml_stack
Max pending open/close walk entries.
@ k_book_xhtml_iter_x
Iteration-guard multiplier over node_count.
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.
Definition book_paged.c:61
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.
Definition book_paged.c:412
static const char *const s_tag_paged
Log tag for paged-source diagnostics.
Definition book_paged.c:30
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.
Definition book_paged.c:220
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.
Definition book_paged.c:447
book_paged_bound_t
Loop-bound headroom for the frame-by-frame copy-out (NASA Rule 2).
Definition book_paged.c:40
@ k_book_paged_min_frame
Smallest accepted frame size (Rule-2 bound).
Definition book_paged.c:42
@ k_book_paged_span_pad
Extra frame iterations over the exact span.
Definition book_paged.c:41
book_image_rect_const_t
4bpp nibble packing + the per-read pixel budget (no magic numbers).
Definition book_paged.c:180
@ k_book_rect_chunk_pad
Loop-bound headroom over ceil(w / k_book_rect_chunk_px).
Definition book_paged.c:185
@ k_book_gray4_nib_sh
Nibble shift and 4->8 bit replicate amount.
Definition book_paged.c:182
@ k_book_gray4_ppb
Pixels packed per pool byte.
Definition book_paged.c:183
@ k_book_rect_chunk_px
Max pixels unpacked per bounded span read.
Definition book_paged.c:184
@ k_book_gray4_nib_lo
Low-nibble mask (odd flat index).
Definition book_paged.c:181
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.
Definition book_paged.c:325
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.
Definition book_paged.c:296
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 rea...
Definition book_paged.c:721
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.
Definition book_paged.c:114
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.
Definition book_paged.c:570
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.
Definition book_paged.c:648
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.
Definition book_paged.c:45
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.
Definition book_paged.c:498
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).
Definition book_paged.c:314
book_paged_walk_bound_t
Staging sizes and loop bounds for the paged text walk (no magic numbers).
Definition book_paged.c:380
@ k_book_paged_tagbuf
Staging for one (short) element tag name.
Definition book_paged.c:382
@ k_book_paged_strbuf
Staging chunk for a paged text run.
Definition book_paged.c:381
@ k_book_paged_pad
Loop-bound headroom over the exact span.
Definition book_paged.c:383
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).
Definition book_paged.c:141
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).
Definition book_paged.c:681
Paged (demand-fetched) accessor mode for book over ra8_vmem (#163).
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ 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
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Byte-range page cache with SLRU eviction (Layer 2, #147).
ra8_err_t ra8_vmem_put(ra8_vmem_t *vm, void *page)
Release one pin on a frame previously returned by ra8_vmem_get.
Definition ra8_vmem.c:179
ra8_err_t ra8_vmem_get(ra8_vmem_t *vm, uint32_t object_id, uint64_t offset, void **out_page)
Get (and pin) the frame holding object object_id at offset.
Definition ra8_vmem.c:162
ra8_err_t ra8_vmem_prefetch(ra8_vmem_t *vm, uint32_t object_id, uint64_t offset)
Warm the frame holding object object_id at offset into the cache without holding a pin (single-thread...
Definition ra8_vmem.c:186
One spine document (a renderable chapter) plus its TOC label.
Definition book.h:280
uint32_t root_node
Node-table index of this chapter's root element.
Definition book.h:283
Fixed 100-byte prologue describing every table and pool in the blob.
Definition book.h:246
uint32_t image_off
Offset to the image table.
Definition book.h:265
uint32_t node_count
Number of DOM nodes.
Definition book.h:258
uint32_t chapter_count
Number of spine chapters.
Definition book.h:256
uint32_t image_count
Number of image descriptors.
Definition book.h:264
uint32_t string_off
Offset to the string pool.
Definition book.h:266
uint32_t node_off
Offset to the node table.
Definition book.h:259
uint32_t chapter_off
Offset to the chapter table.
Definition book.h:257
uint32_t image_pool_off
Offset to the image pool.
Definition book.h:268
Descriptor for one transcoded image in the image pool.
Definition book.h:354
uint16_t height
Pixel height.
Definition book.h:357
uint8_t format
book_image_format_t.
Definition book.h:358
uint16_t width
Pixel width.
Definition book.h:356
uint32_t data_off
Image-pool offset of the compressed pixel data.
Definition book.h:361
One DOM node.
Definition book.h:299
uint8_t kind
book_node_kind_t.
Definition book.h:300
uint32_t text_off
Text: string-pool offset of the run (element: 0).
Definition book.h:304
uint32_t next_sibling
Index of next sibling node, or nil.
Definition book.h:307
uint32_t name_off
Element: string-pool offset of tag name (text: 0).
Definition book.h:303
uint32_t first_child
Index of first child node, or nil.
Definition book.h:306
A book data source: resident (zero-copy) or paged (demand-fetched).
Definition book_paged.h:69
book_header_t hdr
Resident copy of the blob header.
Definition book_paged.h:75
uint32_t size
Total blob length in bytes.
Definition book_paged.h:74
const uint8_t * base
Resident blob base, or NULL in paged mode.
Definition book_paged.h:70
uint32_t frame_bytes
Paged: ra8_vmem frame size, for slice math.
Definition book_paged.h:73
ra8_vmem_t * vm
Paged page cache, or NULL in resident mode.
Definition book_paged.h:71
uint32_t object_id
Paged: the book's ra8_vsource object id.
Definition book_paged.h:72
Page-cache state (caller-owned; treat as private).
Definition ra8_vmem.h:179