40typedef enum : uint16_t {
77 for (
size_t i = 0U; i < n; i++) {
86 if ((mem ==
nullptr) || (buf ==
nullptr) || (offset > (uint64_t)mem->
size) ||
87 ((uint64_t)len > ((uint64_t)mem->
size - offset))) {
110 for (
size_t i = 0U; i < n; i++) {
117 if ((dst ==
nullptr) || (cap == 0U)) {
121 if (path ==
nullptr) {
125 for (
size_t index = 0U; path[index] !=
'\0'; ++index) {
126 if (path[index] ==
'/') {
163internal_extract(mz_zip_archive* zip,
const char* name, uint8_t* buf,
size_t cap,
size_t* got)
166 int32_t idx = mz_zip_reader_locate_file(zip, name,
nullptr, 0U);
170 mz_zip_archive_file_stat st;
171 if (mz_zip_reader_file_stat(zip, (mz_uint)idx, &st) == MZ_FALSE) {
178 if ((
size_t)st.m_uncomp_size > cap) {
181 if (mz_zip_reader_extract_to_mem(zip, (mz_uint)idx, buf, cap, 0U) == MZ_FALSE) {
184 *got = (size_t)st.m_uncomp_size;
191 "k_epub_zip_archive_bytes too small for mz_zip_archive");
198static_assert(
alignof(mz_zip_archive) <=
alignof(max_align_t),
199 "mz_zip_archive alignment exceeds max_align_t");
218 if (zip ==
nullptr) {
221 mz_zip_reader_end(zip);
301 uint8_t* opf_scratch,
305 static const char*
const s_container_path =
"META-INF/container.xml";
312 internal_extract(zip, s_container_path, s_container_buf,
sizeof(s_container_buf), &got);
344 if ((zip ==
nullptr) || (book ==
nullptr)) {
363 if ((sm ==
nullptr) || (sm->
read ==
nullptr)) {
366 if (file_ofs >= sm->
size) {
369 const uint64_t avail = sm->
size - file_ofs;
370 const size_t want = ((uint64_t)n > avail) ? (
size_t)avail : n;
371 return sm->
read(sm->
ctx, (uint64_t)file_ofs, buf, want);
376 if ((zip ==
nullptr) || (out_book ==
nullptr)) {
408 if ((media ==
nullptr) || (out_book ==
nullptr)) {
412 if ((mem->
data ==
nullptr) || (mem->
size == 0U)) {
431 mz_zip_archive* zip = (mz_zip_archive*)zip_storage;
437 if (mz_zip_reader_init_mem(zip, mem->
data, mem->
size, 0U) == MZ_FALSE) {
458 if ((media ==
nullptr) || (out_book ==
nullptr)) {
461 if ((media->
read ==
nullptr) || (media->
size == 0U)) {
479 mz_zip_archive* zip = (mz_zip_archive*)zip_storage;
489 if (mz_zip_reader_init(zip, (mz_uint64)media->
size, 0U) == MZ_FALSE) {
509 if (book ==
nullptr) {
EPUB (.epub) reader and chapter iterator for ra8-firmware.
@ k_epub_zip_archive_bytes
Storage for mz_zip_archive (miniz 3.0.2 sizeof=112; margin; static_assert in .c).
@ k_epub_max_path_len
Max href length (incl.
@ k_epub_toc_nav
Parsed from an EPUB 3 nav.xhtml.
@ k_epub_toc_none
No table of contents parsed.
void priv_epub_join_path(const char *dir, const char *name, char *dst, size_t cap)
Concatenate dir + name into dst, NUL-terminated.
Test-access surface for epub internal helpers (MC/DC).
ra8_err_t priv_epub_zip_guard_entry(const mz_zip_archive_file_stat *st)
Guard one ZIP entry's declared sizes against the policy.
size_t priv_epub_mem_read(void *ctx, uint64_t offset, void *buf, size_t len)
Read one bounded span from resident EPUB media.
ra8_err_t priv_epub_zip_guard_archive(mz_zip_archive *zip)
Guard a just-opened ZIP archive against the decompression policy.
size_t priv_epub_stream_read(void *opaque, mz_uint64 file_ofs, void *buf, size_t n)
Forward one bounded miniz read to streamed EPUB media.
Caller-owned bounded-arena allocator for miniz.
void epub_miniz_free(void *opaque, void *address)
miniz-compatible free (mz_free_func).
ra8_err_t epub_miniz_arena_init(epub_miniz_arena_t *arena, void *workspace, size_t workspace_bytes)
Initialise or reset a miniz arena over caller-owned storage.
void * epub_miniz_alloc(void *opaque, size_t items, size_t size)
miniz-compatible allocator (mz_alloc_func).
void * epub_miniz_realloc(void *opaque, void *address, size_t items, size_t size)
miniz-compatible realloc (mz_realloc_func).
void epub_miniz_arena_deinit(epub_miniz_arena_t *arena)
Invalidate an arena descriptor after miniz has released its blocks.
static ra8_err_t internal_parse_archive(mz_zip_archive *zip, epub_book_t *out_book, uint8_t *opf_scratch, size_t opf_cap)
Run the metadata + spine parsers given an already-open zip.
void priv_epub_dirname(const char *path, char *dst, size_t cap)
Copy the directory prefix of an EPUB package path.
ra8_err_t priv_epub_finish_open(mz_zip_archive *zip, epub_book_t *out_book)
Finish parsing one initialized ZIP reader into an EPUB book.
epub_internal_t
Implementation-only sizing constants.
@ k_epub_container_xml_buf
Stack buffer for container.xml.
@ k_epub_opf_xml_buf
Static OPF + NCX/nav scratch (48 KiB; uint16_t-capped).
static void internal_load_toc(mz_zip_archive *zip, epub_book_t *book, uint8_t *scratch, size_t cap)
Best-effort: extract and parse the book's TOC document.
ra8_err_t epub_close(epub_book_t *book)
Close a previously opened EPUB book.
static void internal_byte_zero(uint8_t *dst, size_t n)
Bounded zero-fill used in place of memset(0).
size_t priv_epub_mem_read(void *ctx, uint64_t offset, void *buf, size_t len)
Read one bounded span from resident EPUB media.
static void internal_byte_copy(uint8_t *dst, const uint8_t *src, size_t n)
Length-checked byte copy used in place of memcpy().
ra8_err_t epub_open_streamed(const epub_stream_media_t *media, const char *path, epub_book_t *out_book)
Open an EPUB book from a seekable stream, with no whole-file residency (#151).
size_t priv_epub_stream_read(void *opaque, mz_uint64 file_ofs, void *buf, size_t n)
Forward one bounded miniz read to streamed EPUB media.
static ra8_err_t internal_extract(mz_zip_archive *zip, const char *name, uint8_t *buf, size_t cap, size_t *got)
Extract a named entry from the open zip into a stack buffer.
ra8_err_t priv_epub_set_miniz_alloc(mz_zip_archive *zip, epub_book_t *book)
Bind one ZIP reader to a book's caller-owned miniz arena.
ra8_err_t epub_open(const void *media, const char *path, epub_book_t *out_book)
Open an EPUB book from an opaque media handle.
static void internal_zip_destroy(mz_zip_archive *zip)
Tear down an in-place archive on the failure path.
ra8_err_t priv_epub_xml_parse_container(const uint8_t *xml_bytes, size_t xml_len, epub_container_result_t *out, epub_xml_workspace_t *workspace)
Parse META-INF/container.xml and copy the rootfile path out.
ra8_err_t priv_epub_xml_parse_opf(const uint8_t *xml_bytes, size_t xml_len, epub_book_t *book)
Parse the OPF document into metadata, cover and spine.
Library-private contract for the bounded EPUB XML parser.
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.
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.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Unified decompression-limits policy: one bound set for every decoder.
ra8_err_t ra8_decomp_zip_entry_preflight(ra8_decomp_read_fn read, void *ctx, uint64_t archive_size)
Reject an over-cap ZIP from its EOCD before directory allocation.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
@ 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_not_found
Requested item not found (lookup / search missed).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
char toc_path[k_epub_max_path_len]
Nav/NCX href (rel.
epub_miniz_workspace_t miniz_workspace
Per-book bounded allocator workspace; never shared with another book.
size_t zip_size
Length of the EPUB blob.
uint16_t chapter_count
Spine length actually stored.
epub_xml_workspace_t xml_workspace
Per-book XML parser state; never shared with another book.
uint8_t toc_kind
epub_toc_kind_t: source of the TOC.
epub_miniz_arena_t miniz_arena
Per-book allocator descriptor bound through miniz's opaque pointer.
epub_stream_media_t stream_media
Streamed media descriptor; {} for the resident path.
uint8_t zip_archive_storage[k_epub_zip_archive_bytes]
Zip archive storage.
uint8_t zip_archive_active
1 = mz_zip_reader_init succeeded.
uint8_t in_use
1 = open, 0 = closed.
char opf_dir[k_epub_max_path_len]
Directory portion of the OPF.
const uint8_t * zip_bytes
Pointer to the EPUB blob.
Out-parameter struct returned by priv_epub_xml_parse_container().
char opf_path[k_epub_max_path_len]
Rootfile path, NUL-terminated.
uint8_t bytes[k_epub_miniz_pool_bytes]
Allocator backing bytes.