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

Demand-paged chunk reader for the "RBKC" .rabook container. More...

#include <stdint.h>
#include "book.h"
#include "book_stream.h"
#include "ra8_err.h"
#include "ra8_vsource.h"
Include dependency graph for book_chunked.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  book_chunked_t
 One open chunked .rabook file: parsed geometry + caller storage. More...

Functions

ra8_err_t book_chunked_open (book_chunked_t *rd, ra8_vsource_read_fn file_read, void *file_ctx, uint64_t file_len, book_inflate_fn inflate, uint64_t *table_buf, uint32_t table_cap_entries, uint8_t *staging, uint32_t staging_cap)
 Open a chunked .rabook container for demand-paged chunk reads.
ra8_err_t book_chunked_read (void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
 Serve one chunk-aligned read of the inflated flat blob.
ra8_err_t book_chunked_validate_strict (book_chunked_t *rd, uint8_t *chunk, uint32_t chunk_cap, uint8_t *scratch, uint32_t scratch_cap, book_header_t *out_header)
 Strictly validate the complete flat blob behind an open RBKC reader.

Detailed Description

Demand-paged chunk reader for the "RBKC" .rabook container.

The bridge between the chunked on-disk container (see book_container_t in book.h) and the #147 page-cache stack: where book_open() inflates every chunk into one resident SDRAM buffer, this reader inflates single chunks on demand, so a book far larger than RAM is read through an ::ra8_vmem cache with a bounded resident working set.

book_chunked_read has exactly the ra8_vsource_read_fn signature, so a bound reader plugs straight into ra8_vsource_add_paged as the backing of a paged object whose byte space is the inflated flat blob:

err = book_chunked_open(&rd, sd_file_read, &file, file_len, sh_inflate,
table_buf, k_table_entries, staging, sizeof
staging); err = ra8_vsource_add_paged(&vs, book_chunked_read, &rd, 0U,
rd.inflated_total, &book_obj); err = book_src_paged(&src, &vm, book_obj,
rd.chunk_bytes, (uint32_t)rd.inflated_total);
ra8_err_t book_chunked_read(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
Serve one chunk-aligned read of the inflated flat blob.
ra8_err_t book_chunked_open(book_chunked_t *rd, ra8_vsource_read_fn file_read, void *file_ctx, uint64_t file_len, book_inflate_fn inflate, uint64_t *table_buf, uint32_t table_cap_entries, uint8_t *staging, uint32_t staging_cap)
Open a chunked .rabook container for demand-paged chunk reads.
ra8_err_t book_src_paged(book_src_t *out, ra8_vmem_t *vm, uint32_t object_id, uint32_t frame_bytes, uint32_t size)
Bind a paged book source over an ra8_vmem cache + ra8_vsource object.
Definition book_paged.c:61
ra8_err_t ra8_vsource_add_paged(ra8_vsource_t *vs, ra8_vsource_read_fn read, void *ctx, uint64_t base, uint64_t size, uint32_t *out_id)
Register a storage-paged object; returns its object_id.
Definition ra8_vsource.c:42
ra8_err_t sh_inflate(const void *src, size_t src_len, void *dst, size_t dst_cap, size_t *out_len)
Heap-free zlib inflater matching book_inflate_fn (miniz; main.c).
Definition main.c:160
One open chunked .rabook file: parsed geometry + caller storage.
uint64_t inflated_total
Served flat-blob length.
uint32_t chunk_bytes
Inflated bytes per chunk.

One chunk equals one cache frame equals one inflate call: the container is produced with chunk_bytes equal to the reader's ::ra8_vmem frame size, each chunk's zlib stream is staged through a caller-owned compressed-bytes buffer and inflated directly into the frame ra8_vsource_loader hands over – no double-buffering and no second decompressed-chunk cache. Reads are therefore chunk-aligned by contract: offset must be a multiple of chunk_bytes and len must equal the chunk's exact inflated span, which is precisely what ra8_vsource_loader passes when the cache's frame_bytes equals the container's chunk_bytes (it clips the final frame to the object end).

Zero allocation (NASA P10 Rule 3): the caller supplies the chunk-table and staging storage at open.

Note
Not thread-safe; the single-threaded reader loop serialises access.
See also
book.h Container layout + the resident open.
book_paged.h Binds the paged object as a book source.
ra8_vsource.h The registry book_chunked_read plugs into.
Since
Version 0.1.0

Definition in file book_chunked.h.

Function Documentation

◆ book_chunked_open()

ra8_err_t book_chunked_open ( book_chunked_t * rd,
ra8_vsource_read_fn file_read,
void * file_ctx,
uint64_t file_len,
book_inflate_fn inflate,
uint64_t * table_buf,
uint32_t table_cap_entries,
uint8_t * staging,
uint32_t staging_cap )
nodiscard

Open a chunked .rabook container for demand-paged chunk reads.

Reads the fixed "RBKC" header through file_read, validates it (magic, non-zero geometry, chunk count consistent with the inflated total), loads the chunk table into table_buf, then validates the table: offset[0] == 0, strictly increasing, offset[chunk_count] equal to the payload length implied by file_len, and every chunk's compressed length within staging_cap. On success rd is bound and book_chunked_read may serve reads; the caller-owned table_buf and staging must out-live it.

Parameters
[out]rdReader to populate (caller-owned).
[in]file_readByte reader over the container file (non-NULL).
[in]file_ctxContext passed to file_read.
[in]file_lenContainer file length in bytes.
[in]inflatezlib decompressor (see book_inflate_fn).
[in]table_bufCaller buffer for the chunk table (non-NULL).
[in]table_cap_entriesCapacity of table_buf in uint64 entries; must be >= chunk_count + 1.
[in]stagingCaller buffer for one compressed chunk (non-NULL).
[in]staging_capCapacity of staging in bytes; must cover the largest compressed chunk in the file.
Returns
ra8_err_t Error code.
Return values
k_ra8_okReader bound; geometry fully validated.
k_ra8_err_null_ptrA required pointer argument was NULL.
k_ra8_err_invalid_argBad magic / header fields / chunk-table shape.
k_ra8_err_invalid_sizefile_len shorter than header + table, the table needs more than table_cap_entries, a compressed chunk exceeds staging_cap, or the table's byte length overflows one read call.
k_ra8_err_*A file_read error, returned verbatim.
Precondition
file_read serves offsets [0, file_len) of the container file.
table_buf and staging out-live every read through rd.
Postcondition
On k_ra8_ok, rd is bound and book_chunked_read serves [0, rd->inflated_total) of the flat blob.
On any error rd is left unbound (its table stays NULL).
Note
Not thread-safe.
See also
book_chunked_read()
Since
Version 0.1.0

Definition at line 202 of file book_chunked.c.

References book_chunked_t::file_ctx, book_chunked_t::file_read, book_chunked_t::inflate_cb, internal_chunked_open_body(), RA8_CHECK_NULL_PTR, s_tag_chunked, book_chunked_t::staging, and book_chunked_t::staging_cap.

Referenced by internal_rabook_open_reader(), priv_mdl_verify_rabook(), ra8_fmt_rabook_inspect_stream(), and sh_paged_open().

◆ book_chunked_read()

ra8_err_t book_chunked_read ( void * ctx,
uint64_t offset,
uint8_t * buf,
uint32_t len )
nodiscard

Serve one chunk-aligned read of the inflated flat blob.

The ra8_vsource_read_fn implementation: looks the chunk covering offset up in the resident table, reads its compressed zlib stream into the staging buffer through the file reader, and inflates it directly into buf. By contract offset is chunk-aligned and len equals the chunk's exact inflated span, min(chunk_bytes, inflated_total - offset) – exactly what ra8_vsource_loader passes when the ::ra8_vmem frame_bytes equals the container's chunk_bytes. One call is one SD-read burst plus one inflate.

Parameters
[in]ctxThe bound book_chunked_t (as a void cookie).
[in]offsetChunk-aligned byte offset within the inflated blob.
[out]bufDestination for exactly len inflated bytes (non-NULL).
[in]lenThe chunk's exact inflated span at offset.
Returns
ra8_err_t Error code.
Return values
k_ra8_okChunk inflated into buf.
k_ra8_err_null_ptrctx or buf was NULL.
k_ra8_err_invalid_statectx was never bound by book_chunked_open.
k_ra8_err_invalid_argoffset is not chunk-aligned, or len is not the chunk's exact inflated span.
k_ra8_err_out_of_rangeoffset is at or past the inflated total.
k_ra8_err_invalid_sizeThe stream inflated to the wrong length.
k_ra8_err_*A file-read or inflater error, verbatim.
Precondition
ctx was populated by book_chunked_open.
buf addresses at least len writable bytes.
Postcondition
On k_ra8_ok, buf[0..len) holds the flat blob's bytes at offset.
On any error buf contents are unspecified.
Note
Not thread-safe: the staging buffer is reused across calls.
See also
ra8_vsource_add_paged()
Since
Version 0.1.0

Definition at line 277 of file book_chunked.c.

References book_chunked_t::chunk_bytes, book_chunked_t::inflated_total, internal_stage_and_inflate(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, s_tag_chunked, and book_chunked_t::table.

Referenced by internal_load_chunk(), mdl_rabook_vfs_read_chunk(), and sh_paged_bind().

◆ book_chunked_validate_strict()

ra8_err_t book_chunked_validate_strict ( book_chunked_t * rd,
uint8_t * chunk,
uint32_t chunk_cap,
uint8_t * scratch,
uint32_t scratch_cap,
book_header_t * out_header )
nodiscard

Strictly validate the complete flat blob behind an open RBKC reader.

Adapts the chunk-aligned book_chunked_read interface to the random-read strict validator. chunk receives one complete inflated chunk at a time; scratch is the independent bounded CRC transfer and node-ownership workspace. The full-body pass requests every chunk, proving every compressed stream, its exact inflated length, and the inner RABOOK1 CRC without retaining the whole book.

Parameters
[in,out]rdOpen chunk reader whose table is already validated.
[out]chunkCaller buffer for one inflated chunk.
[in]chunk_capCapacity of chunk; must cover rd->chunk_bytes.
[out]scratchCaller transfer buffer for strict validation.
[in]scratch_capCapacity of scratch; must be at least one byte and at least ceil(node_count/8) after header decode.
[out]out_headerReceives the decoded header on success.
Returns
Validation status.
Return values
k_ra8_okEvery RBKC stream and inner RABOOK1 field is valid.
k_ra8_err_null_ptrA required pointer is NULL.
k_ra8_err_invalid_argCaller workspace spans overlap, including a detectable out_header alias.
k_ra8_err_invalid_staterd is not open or its geometry/table is inconsistent.
k_ra8_err_invalid_sizeA workspace or wire extent is inconsistent.
k_ra8_err_*A file-reader, inflater, or strict-validator error.
Precondition
rd and its table remain alive and immutable; its staging is exclusively mutable.
chunk and scratch do not overlap each other or rd storage.
out_header does not overlap rd, the callback context reachable through rd->file_ctx, or any reader/caller workspace.
Postcondition
On success out_header describes the complete validated flat blob.
On failure out_header is zeroed and must not be consumed, provided the no-alias precondition holds. A detectable output alias is rejected without modifying the aliased storage.
Note
No heap allocation or recursion is used; the reader is not thread-safe.
Since
Version 0.1.0

Definition at line 401 of file book_chunked_validate.c.

References book_validate_stream_strict(), book_chunked_t::chunk_bytes, book_chunked_t::inflated_total, internal_chunk_flat_read(), internal_output_is_aliased(), internal_validate_reader(), internal_validate_workspaces(), k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by internal_rabook_validate_open(), priv_mdl_verify_rabook(), and ra8_fmt_rabook_inspect_stream().