40 const size_t alignment = _Alignof(max_align_t);
41 const size_t mask = alignment - 1U;
42 if ((out ==
nullptr) || (bytes > (SIZE_MAX - mask))) {
45 *out = (bytes + mask) & ~mask;
68 if ((alloc ==
nullptr) || (alloc->
ws ==
nullptr) || (address ==
nullptr)) {
73 (block !=
nullptr) && ((uint8_t*)block < end) && (block->span >=
sizeof(*block));
74 block = ((uint8_t*)block + block->span < end)
77 if ((
const void*)(block + 1) == address) {
104 if ((alloc ==
nullptr) || (alloc->
ws ==
nullptr) || (items == 0U) || (size == 0U) ||
105 (items > (SIZE_MAX / size))) {
106 if (alloc !=
nullptr) {
111 const size_t bytes = items * size;
120 (block !=
nullptr) && ((uint8_t*)block < end) && (block->span >=
sizeof(*block));
121 block = ((uint8_t*)block + block->span < end)
124 if (block->free && ((block->span -
sizeof(*block)) >= bytes)) {
125 block->bytes = bytes;
133 if (block ==
nullptr) {
137 block->
span = block_span;
138 block->
bytes = bytes;
140 if (alloc->
first ==
nullptr) {
141 alloc->
first = block;
163 if (block !=
nullptr) {
190 if (address ==
nullptr) {
193 if ((alloc ==
nullptr) || (items == 0U) || (size == 0U) || (items > (SIZE_MAX / size))) {
194 if (alloc !=
nullptr) {
200 const size_t bytes = items * size;
201 if ((block ==
nullptr) || block->
free) {
205 if ((block->
span -
sizeof(*block)) >= bytes) {
206 block->
bytes = bytes;
210 if (replacement ==
nullptr) {
236 memset(zip, 0,
sizeof(*zip));
241 zip->m_pAlloc_opaque = alloc;
258 if ((alloc !=
nullptr) && (alloc->
ws !=
nullptr)) {
311 memset(cover, 0,
sizeof(*cover));
312 if ((meta ==
nullptr) || (meta->
cover_path[0] ==
'\0')) {
318 for (
size_t i = 0U; i < count; ++i) {
340 const int written = snprintf(cover->
entry,
sizeof(cover->
entry),
"cover/cover.%s", ext);
374 for (
size_t i = 0U; i < count; ++i) {
414 size_t comic_pages = count;
418 comic_meta = &cover_meta;
421 char comic_xml[4096];
429 (
const uint8_t*)comic_xml,
475 zip.m_pIO_opaque = output;
476 if (mz_zip_writer_init(&zip, 0) == MZ_FALSE) {
496 if ((rc ==
k_ra8_ok) && (mz_zip_writer_finalize_archive(&zip) == MZ_FALSE)) {
499 (void)mz_zip_writer_end(&zip);
ra8_err_t fw_fs_stat(const fw_fs_namespace_t *names, const char *path, fw_fs_stat_t *out)
Query a path; a miss is success with out->exists == false.
@ k_fw_fs_node_file
Regular byte stream.
@ k_fw_fs_path_cap
Largest portable path including its NUL.
Package a downloaded chapter folder into a reader-openable container.
void * mdl_export_workspace_take(mdl_export_workspace_t *ws, size_t bytes, size_t alignment)
Reserve aligned bytes from an exporter arena.
struct mdl_export_workspace mdl_export_workspace_t
Caller-owned bounded arena for all exporter scratch state.
ra8_err_t mdl_export_build_comicinfo_pages(const mdl_export_meta_t *meta, size_t page_count, char *buf, size_t cap)
Generate ComicInfo.xml including page count and direction semantics.
Module-private contracts shared by chapter export writers.
@ k_cover_ext_bytes
Canonical image extension buffer.
@ k_name_max
Maximum entry-name bytes.
bool priv_mdl_export_snprintf_fit(int written, size_t cap)
Report whether an snprintf result fit its destination.
ra8_err_t priv_mdl_export_zip_add_file(mz_zip_archive *zip, mdl_storage_t *storage, const char *member, const char *path, mz_uint flags)
Add one portable source file through miniz callbacks.
ra8_err_t priv_mdl_export_path_join(char *out, size_t capacity, const char *directory, const char *leaf)
Join a canonical directory and leaf without truncation.
size_t priv_mdl_export_zip_write(void *opaque, mz_uint64 file_offset, const void *bytes, size_t length)
Adapt random-offset miniz output to the active export stage.
ra8_err_t priv_mdl_export_zip_add_memory(mz_zip_archive *zip, const char *member, const uint8_t *bytes, size_t length, mz_uint flags)
Add caller-owned memory through the deterministic ZIP read seam.
ra8_err_t priv_mdl_export_cbz(mdl_storage_t *storage, const char *dir, char names[][k_name_max], size_t count, mdl_export_output_t *output, const mdl_export_meta_t *meta, mdl_export_workspace_t *ws)
Write a CBZ with pages, canonical cover, and ComicInfo metadata.
static void * internal_zip_workspace_realloc(void *opaque, void *address, size_t items, size_t size)
Resize a miniz block within the bounded reusable arena.
ra8_err_t priv_mdl_zip_workspace_error(const mdl_zip_allocator_t *alloc)
Map a miniz failure to bounded exhaustion when applicable.
static void internal_zip_workspace_free(void *opaque, void *address)
Release a miniz block for reuse within the current writer.
void priv_mdl_zip_workspace_bind(mz_zip_archive *zip, mdl_zip_allocator_t *alloc, mdl_export_workspace_t *ws)
Bind one zeroed miniz archive to a bounded allocator.
static ra8_err_t internal_cbz_add_metadata(mz_zip_archive *zip, const mdl_export_meta_t *meta, size_t count, const mdl_external_cover_t *cover, const mdl_zip_allocator_t *allocator)
Build and append ComicInfo metadata to a CBZ writer.
static bool internal_zip_align_size(size_t bytes, size_t *out)
Round a byte count up to maximum host alignment.
void priv_mdl_zip_workspace_release(mdl_zip_allocator_t *alloc)
Release all miniz allocations while preserving high-water.
static void * internal_zip_workspace_alloc(void *opaque, size_t items, size_t size)
Allocate reusable miniz storage from a bounded exporter arena.
static mdl_zip_block_t * internal_zip_find_block(mdl_zip_allocator_t *alloc, const void *address)
Find an allocator block by its payload address.
ra8_err_t priv_mdl_export_prepare_cover(mdl_storage_t *storage, const mdl_export_meta_t *meta, const char names[][k_name_max], size_t count, mdl_external_cover_t *cover)
Validate and canonicalize a cover not already present as a page.
static ra8_err_t internal_cbz_add_pages(mz_zip_archive *zip, mdl_storage_t *storage, const char *dir, char names[][k_name_max], size_t count)
Add every discovered page to an initialized CBZ writer.
Bounded URL naming and portable image-classification helpers.
ra8_err_t mdl_urlname_sniff_file(mdl_storage_t *storage, const char *file_path, const char *content_type, char *out_ext, size_t ext_cap, char *out_mime, size_t mime_cap)
Sniff true image extension and MIME type from portable storage.
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).
@ k_ra8_fail
Generic unspecified failure.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
size_t strnlen(const char *s, size_t maxlen)
Calculate bounded string length.
Result of a portable metadata query.
uint64_t size_bytes
File length; zero for a directory.
bool exists
False means a clean lookup miss.
fw_fs_node_type_t type
Kind of node at the path.
fw_fs_namespace_t names
Namespace operations.
One validated staged publication, including random ZIP backfill.
ra8_err_t error
First callback error, if any.
size_t used
Current allocation high edge.
uint8_t * data
Writable arena bytes.
Validated external cover details retained without owning storage.
const char * source
Trusted caller-owned source path.
char entry[k_cover_entry_bytes]
Canonical relative member path.
char mime[k_cover_mime_bytes]
MIME derived from magic bytes.
bool external
True when a separate cover exists.
One non-reentrant downloader filesystem dependency bundle.
const fw_fs_t * fs
Injected portable filesystem.
Per-writer adapter from miniz callbacks to one caller workspace.
size_t floor
Cursor restored after writer end.
mdl_export_workspace_t * ws
Exclusive caller-owned workspace.
mdl_zip_block_t * first
First miniz block, or NULL.
bool exhausted
A callback exceeded bounded space.
Metadata stored immediately before each bounded miniz allocation.
size_t bytes
Requested payload bytes currently preserved.
bool free
Whether this block can satisfy a later request.
size_t span
Aligned header-plus-payload bytes in this block.