|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
epub_open() / epub_close() lifecycle plumbing. More...
#include <stdalign.h>#include <stddef.h>#include <stdint.h>#include <string.h>#include "epub.h"#include "epub_internal.h"#include "epub_miniz_alloc.h"#include "epub_xml_shim_internal.h"#include "miniz.h"#include "ra8_attributes.h"#include "ra8_decomp_limits.h"#include "ra8_err.h"Go to the source code of this file.
Enumerations | |
| enum | epub_internal_t : uint16_t { k_epub_container_xml_buf = 4096 , k_epub_opf_xml_buf = 49152 } |
| Implementation-only sizing constants. More... | |
Functions | |
| static void | internal_byte_copy (uint8_t *dst, const uint8_t *src, size_t n) |
| Length-checked byte copy used in place of memcpy(). | |
| 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_zero (uint8_t *dst, size_t n) |
| Bounded zero-fill used in place of memset(0). | |
| void | priv_epub_dirname (const char *path, char *dst, size_t cap) |
| Copy the directory prefix of an EPUB package path. | |
| 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. | |
| static void | internal_zip_destroy (mz_zip_archive *zip) |
| Tear down an in-place archive on the failure path. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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). | |
| ra8_err_t | epub_close (epub_book_t *book) |
| Close a previously opened EPUB book. | |
epub_open() / epub_close() lifecycle plumbing.
Pulls the .epub bytes out of the opaque media handle, drives miniz to read the ZIP central directory, locates the OPF document via the bounded XML pull consumers, and populates epub_book_t.
[Ring 4 / EPUB] {World: NS}
Definition in file epub_open.c.
| enum epub_internal_t : uint16_t |
Implementation-only sizing constants.
Definition at line 40 of file epub_open.c.
|
nodiscard |
Close a previously opened EPUB book.
| [in,out] | book | Book opened by epub_open(). |
| k_ra8_ok | Book closed and slot released. |
| k_ra8_err_null_ptr | book is NULL. |
| k_ra8_err_not_initialized | book->in_use == 0. |
Definition at line 507 of file epub_open.c.
References epub_book_t::chapter_count, epub_miniz_arena_deinit(), epub_book_t::in_use, internal_zip_destroy(), k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, epub_book_t::miniz_arena, epub_book_t::zip_archive_active, and epub_book_t::zip_archive_storage.
Referenced by compile_fixture(), internal_close_compile_sources(), and rabook_import_compile_adapter().
|
nodiscard |
Open an EPUB book from an opaque media handle.
Treats media as a pointer to epub_mem_media_t, opens the ZIP via miniz, follows META-INF/container.xml to the OPF document, parses metadata + manifest + spine, and populates *out_book.
Algorithm:
| [in] | media | Opaque pointer; currently expected to be a epub_mem_media_t*. |
| [in] | path | Cosmetic file path for diagnostic logs; may be NULL. Not used to read bytes – the caller is responsible for loading the blob into media. |
| [out] | out_book | Populated book on success. |
| k_ra8_ok | Book opened. |
| k_ra8_err_null_ptr | media or out_book is NULL. |
| k_ra8_err_invalid_arg | Media payload invalid. |
| k_ra8_err_no_mem | Spine longer than k_epub_max_chapters. |
| k_ra8_err_validation_failed | ZIP/XML/OPF could not be parsed. |
Definition at line 405 of file epub_open.c.
References epub_mem_media_t::data, epub_miniz_arena_deinit(), internal_byte_zero(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_err_validation_failed, k_ra8_ok, epub_book_t::miniz_arena, priv_epub_finish_open(), priv_epub_mem_read(), priv_epub_set_miniz_alloc(), ra8_decomp_zip_entry_preflight(), epub_mem_media_t::size, epub_book_t::zip_archive_storage, epub_book_t::zip_bytes, and epub_book_t::zip_size.
Referenced by compile_fixture(), ec_render_cover_or_halt(), ep_parse_or_halt(), and est_open_or_halt().
|
nodiscard |
Open an EPUB book from a seekable stream, with no whole-file residency (#151).
The streaming counterpart to epub_open(). Instead of a fully-resident blob (epub_mem_media_t), it takes a epub_stream_media_t – a seek+read callback plus the archive size – and drives miniz's user-read reader (mz_zip_reader_init) off it. Only the ZIP tail (end-of-central-directory + central directory) is read at open, and each entry (container.xml, OPF, a chapter, the cover) is inflated on demand through the same callback, so the resident working set is bounded by the largest single entry plus the central directory – never the whole archive. This is what lets a book far larger than SRAM+SDRAM (e.g. a multi-hundred-MB manga omnibus on the SD card) be opened and parsed at all.
The parsed book is identical to one opened via epub_open(): every accessor (epub_load_chapter(), epub_get_cover_image(), epub_get_resource(), ...) works unchanged, streaming each entry from the backing on demand. epub_close() tears the reader down for both paths.
| [in] | media | Seekable media descriptor; read non-NULL, size > 0. The backing referenced by media->ctx must out-live the opened book. |
| [in] | path | Cosmetic path for diagnostics; may be NULL. Not used to read bytes – all I/O goes through media->read. |
| [out] | out_book | Populated book on success. |
| k_ra8_ok | Book opened; streams from media on demand. |
| k_ra8_err_null_ptr | media or out_book is NULL. |
| k_ra8_err_invalid_arg | media->read is NULL or media->size == 0. |
| k_ra8_err_no_mem | Spine longer than k_epub_max_chapters. |
| k_ra8_err_validation_failed | ZIP/XML/OPF could not be parsed / read. |
Definition at line 455 of file epub_open.c.
References epub_stream_media_t::ctx, epub_miniz_arena_deinit(), internal_byte_zero(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_err_validation_failed, k_ra8_ok, epub_book_t::miniz_arena, priv_epub_finish_open(), priv_epub_set_miniz_alloc(), priv_epub_stream_read(), ra8_decomp_zip_entry_preflight(), epub_stream_media_t::read, epub_stream_media_t::size, epub_book_t::stream_media, epub_book_t::zip_archive_storage, epub_book_t::zip_bytes, and epub_book_t::zip_size.
Referenced by internal_compile_temp(), and internal_stream_open().
|
static |
Length-checked byte copy used in place of memcpy().
Keeps clang-tidy's clang-analyzer-security.insecureAPI checker happy. Same effect on -O2 generated code as memcpy().
| [in] | dst | See implementation. |
| [in] | src | See implementation. |
| [in] | n | See implementation. |
Definition at line 75 of file epub_open.c.
Referenced by priv_epub_dirname(), and priv_epub_mem_read().
|
static |
Bounded zero-fill used in place of memset(0).
See implementation.
| [in] | dst | See implementation. |
| [in] | n | See implementation. |
Definition at line 108 of file epub_open.c.
Referenced by epub_open(), and epub_open_streamed().
|
static |
Extract a named entry from the open zip into a stack buffer.
Returns the actual size in *got. k_ra8_err_no_mem if the entry is larger than cap, k_ra8_err_not_found if the entry is missing.
See implementation.
| [in] | zip | See implementation. |
| [in] | name | See implementation. |
| [in] | buf | See implementation. |
| [in] | cap | See implementation. |
| [in] | got | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 163 of file epub_open.c.
References k_ra8_err_no_mem, k_ra8_err_not_found, k_ra8_err_validation_failed, k_ra8_ok, and priv_epub_zip_guard_entry().
Referenced by internal_load_toc(), and internal_parse_archive().
|
static |
Best-effort: extract and parse the book's TOC document.
priv_epub_xml_parse_opf() records which navigation document to use (book->toc_kind) and its href (book->toc_path). This helper joins that href onto the OPF directory, extracts the entry (falling back to the bare href for archives that store it un-prefixed), and dispatches to the NCX or nav parser. Any failure is swallowed: a book missing or with a malformed TOC is still fully readable via the spine, so this never propagates an error to epub_open().
| [in] | zip | Open archive. |
| [in,out] | book | Book whose toc table is populated. |
| [out] | scratch | Scratch buffer reused for the TOC bytes. |
| [in] | cap | Capacity of scratch in bytes. |
scratch non-NULL with cap > 0. Definition at line 248 of file epub_open.c.
References internal_extract(), k_epub_max_path_len, k_epub_toc_nav, k_epub_toc_none, k_ra8_err_not_found, k_ra8_ok, epub_book_t::opf_dir, priv_epub_join_path(), priv_epub_xml_parse_nav(), priv_epub_xml_parse_ncx(), epub_book_t::toc_kind, and epub_book_t::toc_path.
Referenced by internal_parse_archive().
|
static |
Run the metadata + spine parsers given an already-open zip.
Splits out of epub_open to keep that function under the NASA-Rule-4 statement budget enforced by clang-tidy (readability-function-size).
See implementation.
| [in] | zip | See implementation. |
| [in] | out_book | See implementation. |
| [in] | opf_scratch | See implementation. |
| [in] | opf_cap | See implementation. |
| k_ra8_ok | Operation succeeded. |
container.xml path inside every conformant .epub archive.
Definition at line 299 of file epub_open.c.
References internal_extract(), internal_load_toc(), k_epub_container_xml_buf, k_epub_max_path_len, k_ra8_ok, epub_book_t::opf_dir, epub_container_result_t::opf_path, priv_epub_dirname(), priv_epub_xml_parse_container(), priv_epub_xml_parse_opf(), and epub_book_t::xml_workspace.
Referenced by priv_epub_finish_open().
|
static |
Tear down an in-place archive on the failure path.
Closes miniz state but does not free the storage; the book record owns it inline.
| [in] | zip | See implementation. |
Definition at line 216 of file epub_open.c.
Referenced by epub_close(), and priv_epub_finish_open().
| void priv_epub_dirname | ( | const char * | path, |
| char * | dst, | ||
| size_t | cap ) |
Copy the directory prefix of an EPUB package path.
Test-access form of the helper used while binding the OPF base directory. Production callers keep using the public EPUB facade.
| [in] | path | NUL-terminated package path. |
| [out] | dst | Destination for the directory prefix. |
| [in] | cap | Capacity of dst. |
path points to a NUL-terminated string. cap means dst is writable for cap bytes. Definition at line 115 of file epub_open.c.
References internal_byte_copy(), and RA8_PRIV.
Referenced by internal_parse_archive().
| 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.
Test-access form of the common resident/streamed open tail. Production callers keep using epub_open or epub_open_streamed.
| [in,out] | zip | Initialized miniz reader. |
| [in,out] | out_book | Zeroed destination book. |
| k_ra8_ok | The archive parsed and the book became live. |
| k_ra8_err_null_ptr | One required object was null. |
| k_ra8_err_decomp_entries | The archive exceeded the entry-count policy. |
| k_ra8_err_decomp_output_cap | An entry exceeded the output-size policy. |
| k_ra8_err_decomp_ratio | An entry exceeded the compression-ratio policy. |
| k_ra8_err_not_found | A required EPUB package entry was absent. |
| k_ra8_err_no_mem | A required entry or spine exceeded fixed storage. |
| k_ra8_err_invalid_size | A required XML document was empty. |
| k_ra8_err_validation_failed | The archive or package metadata was invalid. |
zip is an initialized miniz reader. out_book points to zeroed writable storage. out_book live. Definition at line 374 of file epub_open.c.
References epub_book_t::in_use, internal_parse_archive(), internal_zip_destroy(), k_epub_opf_xml_buf, k_ra8_err_null_ptr, k_ra8_ok, priv_epub_zip_guard_archive(), RA8_PRIV, and epub_book_t::zip_archive_active.
Referenced by epub_open(), and epub_open_streamed().
| size_t priv_epub_mem_read | ( | void * | ctx, |
| uint64_t | offset, | ||
| void * | buf, | ||
| size_t | len ) |
Read one bounded span from resident EPUB media.
Test-access form of the callback used by the resident ZIP and decompression preflight paths; production callers keep using the public EPUB facade.
| [in] | ctx | Bound epub_mem_media_t descriptor. |
| [in] | offset | Absolute archive offset. |
| [out] | buf | Destination for exactly len bytes. |
| [in] | len | Requested byte count. |
| 0 | One guard rejected the request. |
| len | Exactly the requested bytes were copied. |
len bytes. Definition at line 83 of file epub_open.c.
References epub_mem_media_t::data, internal_byte_copy(), RA8_PRIV, and epub_mem_media_t::size.
Referenced by epub_open().
| 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.
Test-access form of the shared resident/streamed open helper. It initializes the embedded arena and installs all three allocation callbacks plus their opaque context.
| [in,out] | zip | Zeroed archive descriptor to configure. |
| [in,out] | book | Book owning the arena and workspace. |
| k_ra8_ok | The arena and callbacks were installed. |
| k_ra8_err_null_ptr | One required object was null. |
zip has not entered a miniz reader mode. book. Definition at line 342 of file epub_open.c.
References epub_miniz_workspace_t::bytes, epub_miniz_alloc(), epub_miniz_arena_init(), epub_miniz_free(), epub_miniz_realloc(), k_ra8_err_null_ptr, k_ra8_ok, epub_book_t::miniz_arena, epub_book_t::miniz_workspace, and RA8_PRIV.
Referenced by epub_open(), and epub_open_streamed().
| 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.
Test-access form of the callback installed in a streamed ZIP reader. Production callers use epub_open_streamed.
| [in] | opaque | Bound epub_stream_media_t descriptor. |
| [in] | file_ofs | Absolute archive offset. |
| [out] | buf | Destination for up to n bytes. |
| [in] | n | Requested byte count. |
| 0 | The descriptor or callback was null, or the offset reached EOF. |
| n | The backing callback supplied the full bounded request. |
| <n | The backing callback supplied a short read. |
opaque points to a live epub_stream_media_t. buf is writable for n bytes. n bytes are written to buf. Definition at line 360 of file epub_open.c.
References epub_stream_media_t::ctx, RA8_PRIV, epub_stream_media_t::read, and epub_stream_media_t::size.
Referenced by epub_open_streamed().