35typedef enum : uint32_t {
45typedef enum : uint32_t {
51static const char*
const s_tag =
"rabook_import";
78 if (data ==
nullptr) {
84 uint32_t running_crc = crc;
85 for (uint32_t i = 0U; i < len; i++) {
86 running_crc ^= data[i];
88 const bool lsb = (running_crc & 1U) != 0U;
123 uint64_t expected_size,
129 uint64_t remain = expected_size - (uint64_t)*total;
130 uint32_t request = cap;
131 if (remain < (uint64_t)request) {
132 request = (uint32_t)remain;
135 const ra8_err_t err = read_fn(read_ctx, buf, request, &got);
139 if ((got == 0U) || (got > request)) {
172 const uint32_t* out_size,
173 const uint32_t* out_crc,
174 uint64_t expected_size,
178 if (read_fn ==
nullptr) {
185 if ((cap == 0U) || (expected_size > (uint64_t)UINT32_MAX)) {
188 const uint64_t required_reads =
189 (expected_size / (uint64_t)cap) + (((expected_size % (uint64_t)cap) != 0U) ? 1U : 0U);
190 if (required_reads > (uint64_t)max_reads) {
198 uint64_t expected_size,
218 for (uint32_t i = 0U; (i < max_reads) && ((uint64_t)total < expected_size); ++i) {
225 if ((uint64_t)total != expected_size) {
229 const ra8_err_t err = read_fn(read_ctx, buf, 1U, &extra);
243 uint64_t expected_size,
317 uint64_t expected_size = 0U;
357 const char* epub_path,
411 for (; epub_path[i] !=
'\0'; i++) {
412 if (epub_path[i] ==
'/') {
416 size_t len = i - start;
417 for (
size_t j = len; j > 1U; j--) {
418 if (epub_path[start + j - 1U] ==
'.') {
426 if (len >= (
size_t)cap) {
429 (void)
memcpy(out, &epub_path[start], len);
460 const size_t sn =
strlen(stem);
461 const size_t xn =
strlen(suffix);
462 if ((sn + xn + 1U) > (
size_t)cap) {
465 (void)
memcpy(out, stem, sn);
466 (void)
memcpy(&out[sn], suffix, xn);
496 static const char*
const ext_cache =
".rabook";
497 static const char*
const ext_tmp =
".rabook.tmp";
498 static const char*
const ext_mark =
".rabook.mrk";
530 if (mount ==
nullptr) {
533 if (path ==
nullptr) {
578 err =
ra8_fs_read(file, (uint8_t*)out, (uint32_t)
sizeof(*out), &got);
583 if (got != (uint32_t)
sizeof(*out)) {
609 const char* mark_path,
612 if (mount ==
nullptr) {
615 if (want ==
nullptr) {
654 return ra8_fs_write_file(mount, path, (
const uint8_t*)stamp, (uint32_t)
sizeof(*stamp));
707 for (uint32_t i = 0U; i < cap; i++) {
709 if (src[i] ==
'\0') {
739 const char* epub_path,
740 const char* cache_name,
741 const char* tmp_name,
742 const char* mark_name,
786 const char* epub_path,
787 const char* out_cache_path,
788 uint32_t cache_path_cap,
796 if (cache_path_cap == 0U) {
807 const char* epub_path,
808 char* out_cache_path,
809 uint32_t cache_path_cap,
832 if ((
strlen(cache_name) + 1U) > (
size_t)cache_path_cap) {
836 uint32_t src_size = 0U;
837 uint32_t src_crc = 0U;
852 .source_size = src_size,
853 .source_crc32 = src_crc,
@ k_crc32_poly
Reflected CRC-32 polynomial.
@ k_crc32_bits
Bits folded per input byte.
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_TEST_HELPER
Mark a symbol as externally-linked but only callable from tests.
#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.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ 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_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.
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.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
ra8_err_t ra8_fs_rename(const ra8_fs_mount_t *handle, const char *old_path, const char *new_path)
Rename a file within its own directory.
ra8_err_t ra8_fs_size(const ra8_fs_file_t *file, uint64_t *out_bytes)
Report the file's size in bytes (64-bit on exFAT, #676).
ra8_err_t ra8_fs_read(ra8_fs_file_t *file, uint8_t *buf, uint32_t max_len, uint32_t *got_len)
Read up to max_len bytes; advance the cluster chain on cluster crossings.
ra8_err_t ra8_fs_unlink(const ra8_fs_mount_t *handle, const char *path)
Delete a file: mark its dir entry deleted and free its clusters.
ra8_err_t ra8_fs_open(ra8_fs_mount_t *handle, const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file)
Open or create a file by path, 8.3 or long.
ra8_err_t ra8_fs_close(ra8_fs_file_t *file)
Close an open file, stamping its final modification time.
ra8_err_t ra8_fs_write_file(ra8_fs_mount_t *handle, const char *path, const uint8_t *data, uint32_t len)
Create a whole file in one call (provisioning helper).
@ k_ra8_fs_mode_read
Read-only, must exist.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_error(tag, message)
RA8 log error.
static ra8_err_t internal_crc_stream(ra8_fs_file_t *file, uint8_t *buf, uint32_t cap, uint32_t *out_size, uint32_t *out_crc)
Fold an already-open file through CRC-32 in bounded chunks.
static ra8_err_t internal_derive_names(const char *stem, char *cache_name, char *tmp_name, char *mark_name)
Derive the cache (.rabook), temp (.rabook.tmp), and marker (.rabook.mrk) names from the source stem.
static ra8_err_t internal_compute_source_key(ra8_fs_mount_t *mount, const char *epub_path, uint8_t *buf, uint32_t cap, uint32_t *out_size, uint32_t *out_crc)
Stream a source file through CRC-32, reporting its size and key.
static ra8_err_t internal_read_stamp(ra8_fs_mount_t *mount, const char *path, rabook_import_stamp_t *out)
Read a freshness marker file into a stamp record.
static ra8_err_t internal_crc_stream_validate_args(rabook_import_read_fn read_fn, const uint8_t *buf, const uint32_t *out_size, const uint32_t *out_crc, uint64_t expected_size, uint32_t cap, uint32_t max_reads)
Validate the crc-stream entry point's arguments.
ra8_import_crc_const_t
CRC-32/ISO-HDLC parameters (reflected, matches zlib.crc32).
@ k_crc32_seed
Pre/post conditioning (init = final).
static ra8_err_t internal_validate_open_args(const rabook_import_cfg_t *cfg, const char *epub_path, const char *out_cache_path, uint32_t cache_path_cap, const rabook_import_outcome_t *out_outcome)
Validate the public entry's arguments and the mount dependency.
ra8_err_t priv_rabook_import_crc_stream(rabook_import_read_fn read_fn, void *read_ctx, uint64_t expected_size, uint8_t *buf, uint32_t cap, uint32_t max_reads, uint32_t *out_size, uint32_t *out_crc)
Compute one exact bounded source CRC through an injected reader.
static ra8_err_t internal_crc_stream_read_chunk(rabook_import_read_fn read_fn, void *read_ctx, uint64_t expected_size, uint8_t *buf, uint32_t cap, uint32_t *crc, uint32_t *total)
Read and CRC-fold one bounded chunk of the expected stream.
static ra8_err_t internal_write_stamp(ra8_fs_mount_t *mount, const char *path, const rabook_import_stamp_t *stamp)
Write a fresh marker file, replacing any stale one.
static ra8_err_t internal_import_fs_read(void *ctx, uint8_t *buf, uint32_t requested, uint32_t *out_read)
Adapt the generic bounded CRC reader to one open filesystem file.
static ra8_err_t internal_derive_stem(const char *epub_path, char *out, uint32_t cap)
Extract the cache-name stem from a source path: its basename, minus a trailing extension.
static bool internal_file_exists(ra8_fs_mount_t *mount, const char *path)
Report whether a root-level file can be opened for reading.
static bool internal_cache_is_fresh(ra8_fs_mount_t *mount, const char *mark_path, const rabook_import_stamp_t *want)
Decide if the cached marker matches the expected stamp.
ra8_err_t rabook_import_crc_stream_test(rabook_import_read_fn read_fn, void *read_ctx, uint64_t expected_size, uint8_t *buf, uint32_t cap, uint32_t max_reads, uint32_t *out_size, uint32_t *out_crc)
Exercise the bounded source-key CRC contract from focused tests.
static ra8_err_t internal_atomic_replace(ra8_fs_mount_t *mount, const char *tmp_path, const char *dst_path)
Atomically replace dst_path with tmp_path (temp+rename).
ra8_import_misc_t
Small fixed quantities used by the name + CRC helpers.
@ k_import_max_chunks
Loop bound: chunks streamed for the CRC.
static ra8_err_t internal_compile_and_cache(const rabook_import_cfg_t *cfg, const char *epub_path, const char *cache_name, const char *tmp_name, const char *mark_name, const rabook_import_stamp_t *want)
Compile-on-miss: temp compile, atomic promote, fresh marker.
static ra8_err_t internal_make_name(const char *stem, const char *suffix, char *out, uint32_t cap)
Build <stem><suffix> into out, bounded by cap.
static ra8_err_t internal_copy_name(char *dst, uint32_t cap, const char *src)
Copy a NUL-terminated name into a caller buffer, bounded by capacity.
static uint32_t internal_crc32_block(uint32_t crc, const uint8_t *data, uint32_t len)
Fold a byte block into a running CRC-32/ISO-HDLC accumulator.
ra8_err_t rabook_import_open(const rabook_import_cfg_t *cfg, const char *epub_path, char *out_cache_path, uint32_t cache_path_cap, rabook_import_outcome_t *out_outcome)
Resolve a source .epub to a fresh cached .rabook, compiling once.
On-import EPUB -> .rabook compile-and-cache manager (#151).
@ k_rabook_import_name_cap
Cache/temp/marker name buffer bytes incl.
rabook_import_outcome_t
How rabook_import_open satisfied the request.
@ k_rabook_import_hit
Fresh cache reused; the compiler was NOT invoked.
@ k_rabook_import_compiled
Miss/stale; the book was compiled and cached.
@ k_rabook_import_stamp_magic
Importer marker tag "RBK1".
Module-private bounded source-key streaming contracts.
ra8_err_t(* rabook_import_read_fn)(void *ctx, uint8_t *buf, uint32_t requested, uint32_t *out_read)
Exact sequential-reader seam used by the source-key CRC pass.
Cached parse of one mounted FAT volume.
Injected dependencies + versioning for rabook_import_open.
uint32_t scratch_cap
Capacity of scratch in bytes.
ra8_fs_mount_t * mount
Mounted FAT volume (cache + source).
void * compile_ctx
Cookie forwarded to compile.
rabook_import_compile_fn compile
Compile-on-miss seam (non-NULL).
uint32_t format_version
.rabook format version stamp.
uint8_t * scratch
Streaming buffer for the source CRC.
uint32_t importer_version
Importer/compiler version stamp.
Body of the sidecar freshness marker (<name>.rabook.mrk).
uint32_t format_version
.rabook (RABOOK1) on-disk layout revision.
uint32_t importer_version
Compiler/importer stamp; bump to invalidate.
uint32_t source_size
Byte length of the source .epub.
uint32_t magic
k_rabook_import_stamp_magic.
uint32_t source_crc32
CRC-32/ISO-HDLC of the source .epub bytes.