ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
rabook_import.c File Reference

On-import EPUB -> .rabook compile-and-cache manager (#151). More...

#include "rabook_import.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_fs.h"
#include "ra8_log.h"
#include "rabook_import_internal.h"
Include dependency graph for rabook_import.c:

Go to the source code of this file.

Enumerations

enum  ra8_import_crc_const_t : uint32_t {
  k_crc32_poly = 0xEDB88320U ,
  k_crc32_seed = 0xFFFFFFFFU
}
 CRC-32/ISO-HDLC parameters (reflected, matches zlib.crc32). More...
enum  ra8_import_misc_t : uint32_t {
  k_crc32_bits = 8U ,
  k_import_max_chunks = 131072U
}
 Small fixed quantities used by the name + CRC helpers. More...

Functions

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.
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_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_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.
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_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_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_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_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 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_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 bool internal_file_exists (ra8_fs_mount_t *mount, const char *path)
 Report whether a root-level file can be opened for reading.
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 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.
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_atomic_replace (ra8_fs_mount_t *mount, const char *tmp_path, const char *dst_path)
 Atomically replace dst_path with tmp_path (temp+rename).
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 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_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 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.

Variables

static const char *const s_tag = "rabook_import"
 Log tag for this module.

Detailed Description

On-import EPUB -> .rabook compile-and-cache manager (#151).

Validates import inputs, selects cache paths, and coordinates the injected compiler and storage seams without retaining source ownership.

Since
Version 0.1.0

[Ring 4 / EPUB Import] {World: NS}

Definition in file rabook_import.c.

Enumeration Type Documentation

◆ ra8_import_crc_const_t

enum ra8_import_crc_const_t : uint32_t

CRC-32/ISO-HDLC parameters (reflected, matches zlib.crc32).

Since
Version 0.1.0
Enumerator
k_crc32_poly 

Reflected ISO-HDLC polynomial.

k_crc32_seed 

Pre/post conditioning (init = final).

Definition at line 35 of file rabook_import.c.

◆ ra8_import_misc_t

enum ra8_import_misc_t : uint32_t

Small fixed quantities used by the name + CRC helpers.

Since
Version 0.1.0
Enumerator
k_crc32_bits 

Bits processed per input byte.

k_import_max_chunks 

Loop bound: chunks streamed for the CRC.

Definition at line 45 of file rabook_import.c.

Function Documentation

◆ internal_atomic_replace()

ra8_err_t internal_atomic_replace ( ra8_fs_mount_t * mount,
const char * tmp_path,
const char * dst_path )
static

Atomically replace dst_path with tmp_path (temp+rename).

Unlinks dst_path first because ra8_fs_rename will not overwrite.

Parameters
[in]mountMounted volume.
[in]tmp_pathExisting temp file to promote.
[in]dst_pathFinal cache path.
Returns
Error code from the rename.
Return values
k_ra8_okPromoted.
k_ra8_err_null_ptrA pointer argument is NULL.
k_ra8_err_*Filesystem rename error.
Precondition
tmp_path exists; dst_path is its intended final name.
mount names a mounted volume.
Postcondition
On success dst_path holds the temp's bytes and the temp is gone.
On error the temp remains for a retry; no half cache is published.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 675 of file rabook_import.c.

References RA8_CHECK_NULL_PTR, ra8_fs_rename(), ra8_fs_unlink(), and s_tag.

Referenced by internal_compile_and_cache().

◆ internal_cache_is_fresh()

bool internal_cache_is_fresh ( ra8_fs_mount_t * mount,
const char * mark_path,
const rabook_import_stamp_t * want )
static

Decide if the cached marker matches the expected stamp.

Compares every serialized field explicitly so padding bytes cannot affect cache freshness. Focused vectors vary each field while the preceding comparisons remain true.

Parameters
[in]mountMounted volume.
[in]mark_pathMarker path (root-level).
[in]wantStamp the running firmware expects for this source.
Returns
true if the marker exists and exactly equals want.
Return values
trueThe marker read back and its bytes equal want exactly.
falsemount or want is NULL, the marker read failed, or the bytes differ.
Precondition
mount names a mounted volume.
want is non-NULL.
Postcondition
want and the marker file are unmodified.
Returns false on any read error (treated as stale).
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 608 of file rabook_import.c.

References rabook_import_stamp_t::format_version, rabook_import_stamp_t::importer_version, internal_read_stamp(), k_ra8_ok, rabook_import_stamp_t::magic, RA8_INTERNAL, rabook_import_stamp_t::source_crc32, and rabook_import_stamp_t::source_size.

Referenced by rabook_import_open().

◆ internal_compile_and_cache()

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 )
static

Compile-on-miss: temp compile, atomic promote, fresh marker.

Unlinks any stale temp, runs the injected cfg->compile seam to build tmp_name, atomically promotes it to cache_name via internal_atomic_replace, then stamps mark_name; the first failing step short-circuits and the live cache is left untouched.

Parameters
[in]cfgInjected dependencies + versioning.
[in]epub_pathSource path passed to the compiler.
[in]cache_nameFinal cache name to publish.
[in]tmp_nameTemp name the compiler writes to first.
[in]mark_nameMarker name to stamp on success.
[in]wantStamp to persist.
Returns
Error code from compile / promote / marker write.
Return values
k_ra8_okCache + marker published.
k_ra8_err_*Propagated compiler or filesystem error.
Precondition
cfg and its compile seam are non-NULL.
The names are distinct paths derived from the same source stem.
Postcondition
On success the cache + marker are present and consistent.
On error the cache is left untouched (no partial publish).
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 738 of file rabook_import.c.

References rabook_import_cfg_t::compile, rabook_import_cfg_t::compile_ctx, internal_atomic_replace(), internal_write_stamp(), k_ra8_ok, rabook_import_cfg_t::mount, RA8_CHECK_NULL_PTR, ra8_fs_unlink(), RA8_INTERNAL, ra8_log_error, and s_tag.

Referenced by rabook_import_open().

◆ internal_compute_source_key()

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 )
static

Stream a source file through CRC-32, reporting its size and key.

Opens epub_path read-only, delegates the fold to internal_crc_stream, and closes on every path. The NULL/open guards on mount, epub_path, and buf are delegated to ra8_fs_open and internal_crc_stream respectively.

Parameters
[in]mountMounted volume.
[in]epub_pathSource path (root-level).
[in]bufStreaming scratch buffer (> 0 bytes).
[in]capCapacity of buf (> 0).
[out]out_sizeReceives the source byte length.
[out]out_crcReceives the finalised CRC-32 cache key.
Returns
Error code.
Return values
k_ra8_okKey computed.
k_ra8_err_null_ptrout_size or out_crc is NULL.
k_ra8_err_invalid_sizecap is zero.
k_ra8_err_*Open/read error (e.g. source missing).
Precondition
out_size and out_crc are non-NULL.
cap > 0.
Postcondition
On success *out_size/*out_crc describe the whole source.
The source file is closed on every return path.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 356 of file rabook_import.c.

References internal_crc_stream(), k_ra8_err_invalid_size, k_ra8_fs_mode_read, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_fs_close(), ra8_fs_open(), RA8_INTERNAL, and s_tag.

Referenced by rabook_import_open().

◆ internal_copy_name()

ra8_err_t internal_copy_name ( char * dst,
uint32_t cap,
const char * src )
static

Copy a NUL-terminated name into a caller buffer, bounded by capacity.

Copies src into dst byte-for-byte, stopping after the first NUL (which is copied too). If no terminator appears within the first cap bytes the copy is abandoned with k_ra8_err_invalid_size.

Parameters
[out]dstDestination buffer.
[in]capCapacity of dst.
[in]srcNUL-terminated source name.
Returns
Error code.
Return values
k_ra8_okCopied incl. terminator.
k_ra8_err_null_ptrA pointer argument is NULL.
k_ra8_err_invalid_sizesrc did not terminate within cap.
Precondition
dst and src are non-NULL.
src is a NUL-terminated name.
Postcondition
On success dst equals src including the terminator.
On error dst contents are unspecified.
Note
Thread-safe: writes only dst.
Since
Version 0.1.0

Definition at line 703 of file rabook_import.c.

References k_ra8_err_invalid_size, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, and s_tag.

Referenced by rabook_import_open().

◆ internal_crc32_block()

uint32_t internal_crc32_block ( uint32_t crc,
const uint8_t * data,
uint32_t len )
static

Fold a byte block into a running CRC-32/ISO-HDLC accumulator.

Bitwise reflected update; the caller seeds with k_crc32_seed and XORs the final value with the same seed. Used to key the cache by source content (not a .rabook body CRC – that is the compiler's job inside the emitted blob).

Parameters
[in]crcRunning accumulator (seeded value before the first call).
[in]dataInput bytes; may be NULL (treated as a no-op block).
[in]lenNumber of bytes at data.
Returns
Updated accumulator.
Return values
uint32_tReflected CRC-32 over crc plus len bytes; returns crc unchanged when data is NULL or len is 0.
Precondition
crc holds the running value from any prior block.
data points at len readable bytes, or is NULL.
Postcondition
The result reflects all bytes folded so far.
data and the input are unmodified.
Note
Thread-safe: pure function over its arguments.
Since
Version 0.1.0

Definition at line 76 of file rabook_import.c.

References k_crc32_bits, k_crc32_poly, and RA8_INTERNAL.

Referenced by internal_crc_stream_read_chunk().

◆ internal_crc_stream()

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 )
static

Fold an already-open file through CRC-32 in bounded chunks.

Snapshots the file size, rejects sizes that cannot be represented by the on-disk import stamp or completed inside the read budget, and then requires exact bounded reads plus EOF. The working set is one chunk, never the whole .epub.

Parameters
[in]fileOpen, readable file handle.
[in]bufStreaming scratch buffer (>= cap bytes).
[in]capChunk size in bytes (> 0).
[out]out_sizeReceives the total byte length read.
[out]out_crcReceives the finalised CRC-32 cache key.
Returns
Error code.
Return values
k_ra8_okStream consumed to EOF.
k_ra8_err_null_ptrfile or buf is NULL.
k_ra8_err_invalid_sizeThe file exceeds the stamp/read budget, a read is short/oversized, or the file changes.
k_ra8_err_*Size/read error.
Precondition
file is open for reading; buf holds cap bytes.
out_size and out_crc are non-NULL.
Postcondition
On success *out_size/*out_crc describe every byte read.
file's offset is at EOF (no close performed here).
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 308 of file rabook_import.c.

References internal_import_fs_read(), k_import_max_chunks, k_ra8_ok, priv_rabook_import_crc_stream(), RA8_CHECK_NULL_PTR, ra8_fs_size(), RA8_INTERNAL, and s_tag.

Referenced by internal_compute_source_key().

◆ internal_crc_stream_read_chunk()

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 )
static

Read and CRC-fold one bounded chunk of the expected stream.

Requests up to cap bytes (less near the end of the expected size), rejects a zero-byte or over-large read, and folds the bytes read into the running CRC and total.

Parameters
[in]read_fnCaller-owned positioned reader.
[in,out]read_ctxReader-specific context.
[in]expected_sizeTotal expected stream size in bytes.
[in,out]bufCaller-owned scratch buffer of at least cap bytes.
[in]capCapacity of buf in bytes.
[in,out]crcRunning CRC accumulator.
[in,out]totalRunning byte count read so far.
Returns
Read/validation status.
Return values
k_ra8_okOne chunk was read and folded.
k_ra8_err_invalid_sizeThe reader returned zero or too many bytes.
otherThe injected reader failed.
Precondition
total is strictly less than expected_size on entry.
buf holds at least cap writable bytes and cap is non-zero.
Postcondition
On success crc and total reflect the newly read chunk.
On any failure crc and total are left at their entry values.
Note
Not thread-safe: mutates caller-owned scratch state.
Since
Version 0.1.0

Definition at line 121 of file rabook_import.c.

References internal_crc32_block(), k_ra8_err_invalid_size, k_ra8_ok, and RA8_INTERNAL.

Referenced by priv_rabook_import_crc_stream().

◆ internal_crc_stream_validate_args()

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 )
static

Validate the crc-stream entry point's arguments.

Rejects any null pointer argument, an empty read capacity, an expected size that cannot fit a uint32_t, and a read budget too small to cover the expected size.

Parameters
[in]read_fnCaller-owned positioned reader.
[in]bufCaller-owned scratch buffer.
[in]out_sizeDestination for the read byte count.
[in]out_crcDestination for the folded CRC.
[in]expected_sizeTotal expected stream size in bytes.
[in]capCapacity of buf in bytes.
[in]max_readsBounded read-attempt budget.
Returns
Argument validation status.
Return values
k_ra8_okEvery argument is present and within bounds.
k_ra8_err_null_ptrA required pointer argument is NULL.
k_ra8_err_invalid_sizeA capacity, size, or budget bound is violated.
Precondition
None; every argument is treated as untrusted.
max_reads is the caller's bounded read budget for the whole stream.
Postcondition
No argument or output state is modified.
Success proves the read loop terminates within max_reads iterations.
Note
Not thread-safe with respect to concurrent callers.
Since
Version 0.1.0

Definition at line 170 of file rabook_import.c.

References k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_log_error, and s_tag.

Referenced by priv_rabook_import_crc_stream().

◆ internal_derive_names()

ra8_err_t internal_derive_names ( const char * stem,
char * cache_name,
char * tmp_name,
char * mark_name )
static

Derive the cache (.rabook), temp (.rabook.tmp), and marker (.rabook.mrk) names from the source stem.

All three share the source stem and differ only in extension.

Parameters
[in]stemSource-name stem (NUL-terminated).
[out]cache_nameReceives <stem>.rabook (cap k_rabook_import_name_cap).
[out]tmp_nameReceives <stem>.rabook.tmp.
[out]mark_nameReceives <stem>.rabook.mrk.
Returns
Error code from the first failing name build.
Return values
k_ra8_okAll three names written.
k_ra8_err_null_ptrA destination buffer (or stem) is NULL.
k_ra8_err_invalid_sizeA derived name overflows the name buffer.
Precondition
cache_name, tmp_name, mark_name each hold the name cap.
stem is the finalised source stem.
Postcondition
On success the three buffers hold consistent, distinct names.
On error the buffers' contents are unspecified.
Note
Thread-safe: writes only the destinations.
Since
Version 0.1.0

Definition at line 491 of file rabook_import.c.

References internal_make_name(), k_ra8_ok, k_rabook_import_name_cap, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by rabook_import_open().

◆ internal_derive_stem()

ra8_err_t internal_derive_stem ( const char * epub_path,
char * out,
uint32_t cap )
static

Extract the cache-name stem from a source path: its basename, minus a trailing extension.

Takes the run after the last '/', then drops a final .ext when the dot is not the basename's first character (so .hidden keeps its name). The stem is copied NUL-terminated and bounded by cap; an empty or oversized stem is refused rather than truncated.

Parameters
[in]epub_pathSource path (root-level; long names permitted).
[out]outStem buffer.
[in]capCapacity of out (k_rabook_import_name_cap).
Returns
Error code.
Return values
k_ra8_okStem written + NUL-terminated.
k_ra8_err_null_ptrepub_path or out is NULL.
k_ra8_err_invalid_argThe basename is empty (no usable stem).
k_ra8_err_invalid_sizeThe stem does not fit cap.
Precondition
epub_path is NUL-terminated; out holds cap bytes.
cap > 0.
Postcondition
On success out is a NUL-terminated non-empty stem.
On error out is not relied upon.
Note
Thread-safe: writes only out.
Since
Version 0.1.0

Definition at line 404 of file rabook_import.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, memcpy(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, and s_tag.

Referenced by rabook_import_open().

◆ internal_file_exists()

bool internal_file_exists ( ra8_fs_mount_t * mount,
const char * path )
static

Report whether a root-level file can be opened for reading.

Probes existence by attempting a read-only ra8_fs_open; on success it immediately closes the handle. NULL arguments and any open failure are reported as "not present".

Parameters
[in]mountMounted volume.
[in]pathRoot-level path.
Returns
true if the file exists and opens; false otherwise.
Return values
truepath opened read-only (and was closed again).
falsemount or path is NULL, or the open failed.
Precondition
mount and path describe a mounted volume + candidate name.
A free file slot is available for the probe open.
Postcondition
Any handle opened by the probe is closed before return.
mount is otherwise unchanged.
Note
Thread-safe only if the caller serialises filesystem access.
Since
Version 0.1.0

Definition at line 528 of file rabook_import.c.

References k_ra8_fs_mode_read, k_ra8_ok, ra8_fs_close(), ra8_fs_open(), and RA8_INTERNAL.

Referenced by rabook_import_open().

◆ internal_import_fs_read()

ra8_err_t internal_import_fs_read ( void * ctx,
uint8_t * buf,
uint32_t requested,
uint32_t * out_read )
static

Adapt the generic bounded CRC reader to one open filesystem file.

Casts the injected context back to the repository file handle and preserves the portable read operation's count and error semantics.

Parameters
[in,out]ctxOpen ra8_fs_file_t supplied as opaque context.
[out]bufDestination for up to requested bytes.
[in]requestedMaximum bytes to read.
[out]out_readReceives the accepted byte count.
Returns
Portable filesystem read status.
Return values
k_ra8_okA bounded prefix, including EOF, was reported.
k_ra8_err_*The filesystem read failed, returned verbatim.
Precondition
ctx points to an open readable repository file handle.
buf and out_read address their advertised writable storage.
Postcondition
Success writes at most requested bytes and reports that count.
The file offset advances by the reported count.
Note
Not thread-safe for concurrent access to the same file handle.
Since
Version 0.1.0

Definition at line 279 of file rabook_import.c.

References ra8_fs_read().

Referenced by internal_crc_stream().

◆ internal_make_name()

ra8_err_t internal_make_name ( const char * stem,
const char * suffix,
char * out,
uint32_t cap )
static

Build <stem><suffix> into out, bounded by cap.

Concatenates the source stem and one of the fixed .rabook* extensions and NUL-terminates. A combination that does not fit cap is refused rather than truncated.

Parameters
[in]stemSource-name stem (NUL-terminated).
[in]suffixExtension to append (NUL-terminated, e.g. .rabook).
[out]outDestination buffer.
[in]capCapacity of out.
Returns
Error code.
Return values
k_ra8_okName written + NUL-terminated.
k_ra8_err_null_ptrA pointer argument is NULL.
k_ra8_err_invalid_sizestem + suffix + NUL exceeds cap.
Precondition
stem, suffix, and out are non-NULL.
cap > 0.
Postcondition
On success out is <stem><suffix> NUL-terminated.
On error out is unmodified.
Note
Thread-safe: writes only out.
Since
Version 0.1.0

Definition at line 455 of file rabook_import.c.

References k_ra8_err_invalid_size, k_ra8_ok, memcpy(), RA8_CHECK_NULL_PTR, s_tag, and strlen().

Referenced by internal_derive_names().

◆ internal_read_stamp()

ra8_err_t internal_read_stamp ( ra8_fs_mount_t * mount,
const char * path,
rabook_import_stamp_t * out )
static

Read a freshness marker file into a stamp record.

Opens path read-only, reads exactly sizeof(*out) bytes into out, and closes on every path; a short read (marker smaller than one stamp) is reported as k_ra8_err_invalid_size.

Parameters
[in]mountMounted volume.
[in]pathMarker path (root-level).
[out]outReceives the stamp on success.
Returns
Error code.
Return values
k_ra8_okStamp read in full.
k_ra8_err_null_ptrA pointer argument is NULL.
k_ra8_err_invalid_sizeMarker shorter than a stamp.
k_ra8_err_*Open/read error (e.g. marker absent).
Precondition
out is non-NULL.
path names the candidate marker.
Postcondition
On success *out holds the on-disk stamp.
The marker file is closed on every path.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 566 of file rabook_import.c.

References k_ra8_err_invalid_size, k_ra8_fs_mode_read, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_fs_close(), ra8_fs_open(), ra8_fs_read(), and s_tag.

Referenced by internal_cache_is_fresh().

◆ internal_validate_open_args()

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 )
static

Validate the public entry's arguments and the mount dependency.

cfg->scratch and cfg->compile are not checked here – they are guarded at their point of use (internal_crc_stream and internal_compile_and_cache respectively), so a NULL either still yields k_ra8_err_null_ptr without inflating this validator.

Parameters
[in]cfgConfig (and its mount).
[in]epub_pathSource path.
[in]out_cache_pathCaller output buffer.
[in]cache_path_capCapacity of out_cache_path.
[in]out_outcomeCaller outcome output.
Returns
Error code.
Return values
k_ra8_okArguments valid.
k_ra8_err_null_ptrA required pointer is NULL.
k_ra8_err_invalid_sizecache_path_cap is zero. (The output buffer is fit-checked against the derived name later.)
Precondition
Called first from rabook_import_open.
cfg may be NULL (checked here before any dereference).
Postcondition
On k_ra8_ok cfg and cfg->mount are safe to dereference.
On error the caller returns immediately without side effects.
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 785 of file rabook_import.c.

References k_ra8_err_invalid_size, k_ra8_ok, rabook_import_cfg_t::mount, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by rabook_import_open().

◆ internal_write_stamp()

ra8_err_t internal_write_stamp ( ra8_fs_mount_t * mount,
const char * path,
const rabook_import_stamp_t * stamp )
static

Write a fresh marker file, replacing any stale one.

ra8_fs_write_file replaces an existing name by itself since #603, so the unlink is belt-and-braces: it keeps the marker absent rather than stale if the write fails partway.

Parameters
[in]mountMounted volume.
[in]pathMarker path (root-level).
[in]stampStamp to persist.
Returns
Error code from the write.
Return values
k_ra8_okMarker written.
k_ra8_err_null_ptrA pointer argument is NULL.
k_ra8_err_*Filesystem write error.
Precondition
stamp is non-NULL.
path names the marker for the current source.
Postcondition
On success path holds exactly stamp.
On error no partial marker is relied upon (re-derived next open).
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 648 of file rabook_import.c.

References RA8_CHECK_NULL_PTR, ra8_fs_unlink(), ra8_fs_write_file(), and s_tag.

Referenced by internal_compile_and_cache().

◆ priv_rabook_import_crc_stream()

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.

Consumes the immutable size in fixed-capacity chunks, rejects short or oversized callback results, and requires one final exact EOF read before publishing either source-key output.

Parameters
[in]read_fnSequential read callback.
[in,out]read_ctxOpaque callback context.
[in]expected_sizeImmutable source-size snapshot.
[out]bufCaller-owned transfer buffer.
[in]capTransfer-buffer capacity.
[in]max_readsMaximum data-bearing callback calls.
[out]out_sizePublished exact size on success only.
[out]out_crcPublished CRC-32/ISO-HDLC on success only.
Returns
Exact-stream validation status.
Return values
k_ra8_okThe size snapshot was consumed and EOF confirmed.
k_ra8_err_invalid_sizeGeometry, callback count, or read length was invalid.
k_ra8_err_*Callback failure, returned verbatim.
Precondition
Pointer arguments are non-NULL; buf holds cap bytes.
expected_size is stable and representable by the published uint32_t size.
Postcondition
Success publishes both outputs; failure leaves both unchanged.
Success confirms one additional callback returned exact EOF.
Note
Not thread-safe unless the injected reader serializes its context.
Since
Version 0.1.0

Definition at line 196 of file rabook_import.c.

References internal_crc_stream_read_chunk(), internal_crc_stream_validate_args(), k_crc32_seed, k_ra8_err_invalid_size, k_ra8_ok, and RA8_PRIV.

Referenced by internal_crc_stream(), and rabook_import_crc_stream_test().

◆ rabook_import_crc_stream_test()

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.

Forwards every argument unchanged to the module-private production implementation so fault-vector tests cover the exact shipped loop.

Parameters
[in]read_fnSequential read callback.
[in,out]read_ctxOpaque callback context.
[in]expected_sizeImmutable source-size snapshot.
[out]bufCaller-owned transfer buffer.
[in]capTransfer-buffer capacity.
[in]max_readsMaximum data-bearing callback calls.
[out]out_sizePublished exact size on success only.
[out]out_crcPublished CRC-32/ISO-HDLC on success only.
Returns
Exact-stream validation status from the production helper.
Return values
k_ra8_okThe size snapshot was consumed and EOF confirmed.
k_ra8_err_invalid_sizeGeometry, count, or callback length was invalid.
k_ra8_err_*An injected callback error, returned verbatim.
Precondition
Pointer arguments are non-NULL and buf holds cap bytes.
max_reads bounds every possible data-bearing callback.
Postcondition
Success publishes both result objects.
Failure leaves both output objects unchanged.
Note
Test helper; thread safety follows the injected reader context.
Since
Version 0.1.0

Definition at line 241 of file rabook_import.c.

References priv_rabook_import_crc_stream(), and RA8_TEST_HELPER.

◆ rabook_import_open()

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 )
nodiscard

Resolve a source .epub to a fresh cached .rabook, compiling once.

State machine on "open `epub_path`":

  1. Derive the cache names from the source's own basename: <name>.rabook (cache), <name>.rabook.tmp (temp) and <name>.rabook.mrk (marker).
  2. Stream the source bytes through CRC-32 to derive (size, crc); the crc keys the freshness stamp (not the file name), so a content change under the same source name still forces a re-derive.
  3. If the marker <name>.rabook.mrk matches the expected stamp AND the cache file is present -> hit: emit the cache path, do not invoke compile.
  4. Otherwise -> miss/stale: clear any stale temp, call compile to <name>.rabook.tmp, atomically rename it over <name>.rabook, write the fresh marker, and emit the cache path.
Parameters
[in]cfgInjected dependencies + versioning (see struct).
[in]epub_pathRoot-level path of the source .epub.
[out]out_cache_pathReceives the NUL-terminated cache .rabook path the caller then opens with book_open.
[in]cache_path_capCapacity of out_cache_path in bytes; must hold the derived <name>.rabook name and its terminator.
[out]out_outcomeReceives k_rabook_import_hit or k_rabook_import_compiled on success.
Returns
Error code.
Return values
k_ra8_okCache is fresh (hit) or freshly written (compiled).
k_ra8_err_null_ptrA required pointer (incl. an injected dependency) is NULL.
k_ra8_err_invalid_argepub_path has no usable basename.
k_ra8_err_invalid_sizecache_path_cap is too small for the derived name, the derived name overflows the fixed buffer, or scratch_cap is zero.
k_ra8_err_not_foundThe source .epub does not exist.
k_ra8_err_*Propagated filesystem or compiler error (on a compile error the cache is left untouched).
Precondition
cfg, epub_path, out_cache_path, and out_outcome are non-NULL.
cfg->mount, cfg->compile, and cfg->scratch are non-NULL.
Postcondition
On k_ra8_ok, out_cache_path is a NUL-terminated path to a present cache file and *out_outcome records hit vs compiled.
On any error the source .epub is unmodified and no half cache remains.
Note
Not thread-safe; callers serialise imports.
See also
rabook_import_compiler.h
Since
Version 0.1.0

Definition at line 806 of file rabook_import.c.

References rabook_import_cfg_t::format_version, rabook_import_cfg_t::importer_version, internal_cache_is_fresh(), internal_compile_and_cache(), internal_compute_source_key(), internal_copy_name(), internal_derive_names(), internal_derive_stem(), internal_file_exists(), internal_validate_open_args(), k_ra8_err_invalid_size, k_ra8_ok, k_rabook_import_compiled, k_rabook_import_hit, k_rabook_import_name_cap, k_rabook_import_stamp_magic, rabook_import_cfg_t::mount, rabook_import_cfg_t::scratch, rabook_import_cfg_t::scratch_cap, and strlen().

Referenced by imp_run().

Variable Documentation

◆ s_tag

const char* const s_tag = "rabook_import"
static

Log tag for this module.

Since
Version 0.1.0

Definition at line 51 of file rabook_import.c.