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

Implementation of the demand-paged "RBKC" chunk reader. More...

#include "book_chunked.h"
#include <string.h>
#include "book_internal.h"
#include "ra8_attributes.h"
#include "ra8_check.h"
Include dependency graph for book_chunked.c:

Go to the source code of this file.

Functions

static ra8_err_t internal_table_check (const book_chunked_t *rd, const uint64_t *table_buf, uint64_t payload_len)
 Validate a loaded chunk table's shape against the payload extent.
static ra8_err_t internal_load_table (book_chunked_t *rd, uint64_t file_len, uint64_t *table_buf, uint32_t table_cap_entries)
 Load + validate the chunk table through the file reader.
static ra8_err_t internal_chunked_open_body (book_chunked_t *rd, uint64_t file_len, uint64_t *table_buf, uint32_t table_cap_entries)
 The argument-checked body of 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)
 Open a chunked .rabook container for demand-paged chunk reads.
static ra8_err_t internal_stage_and_inflate (const book_chunked_t *rd, uint32_t idx, uint8_t *buf, uint32_t len)
 Stage one chunk's compressed stream and inflate it into buf.
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.

Variables

static const char *const s_tag_chunked = "book_chunked"
 Log tag for chunk-reader diagnostics.

Detailed Description

Implementation of the demand-paged "RBKC" chunk reader.

Geometry parsing is shared with the resident open through priv_book_container_header_fields() / priv_book_container_table_entry() (book_internal.h), so the container format has exactly one in-firmware definition. This TU adds the callback-driven half: the header and chunk table are pulled through the caller's file reader at open, and each book_chunked_read stages one compressed stream and inflates it into the caller's frame.

Since
Version 0.1.0

Definition in file book_chunked.c.

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().

◆ internal_chunked_open_body()

ra8_err_t internal_chunked_open_body ( book_chunked_t * rd,
uint64_t file_len,
uint64_t * table_buf,
uint32_t table_cap_entries )
static

The argument-checked body of book_chunked_open.

Reads and parses the fixed header, then loads + validates the chunk table. The caller has already null-checked every argument and pre-bound the reader's callbacks and buffers. Split from the entry point so the null-guard macros and the staged open logic each stay within the function-size budget.

Parameters
[in,out]rdReader with callbacks/buffers pre-bound.
[in]file_lenContainer file length in bytes.
[in]table_bufCaller buffer for the chunk table.
[in]table_cap_entriesCapacity of table_buf in uint64 entries.
Returns
ra8_err_t Status code.
Return values
k_ra8_okReader bound; geometry fully validated.
k_ra8_err_invalid_argBad magic / header fields / table shape.
k_ra8_err_invalid_sizeShort file or a caller buffer too small.
k_ra8_err_*A file-read error, returned verbatim.
Precondition
Every pointer argument was null-checked by the caller.
rd->file_read / rd->staging / rd->staging_cap are pre-bound.
Postcondition
On k_ra8_ok, rd->table is bound and reads may be served.
On any error rd->table stays NULL (reader unbound).
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 181 of file book_chunked.c.

References book_chunked_t::chunk_bytes, book_chunked_t::chunk_count, book_chunked_t::file_ctx, book_chunked_t::file_read, book_chunked_t::inflated_total, internal_load_table(), k_book_container_header_len, k_ra8_err_invalid_size, k_ra8_ok, priv_book_container_header_fields(), and RA8_INTERNAL.

Referenced by book_chunked_open().

◆ internal_load_table()

ra8_err_t internal_load_table ( book_chunked_t * rd,
uint64_t file_len,
uint64_t * table_buf,
uint32_t table_cap_entries )
static

Load + validate the chunk table through the file reader.

Sizes the table from the already-parsed header fields in rd, bounds it against table_cap_entries, the file length, and the one-call uint32 read limit, reads it into table_buf in one burst, then walks it once to require offset[0] == 0, strict monotonic growth, an end offset equal to the payload length implied by file_len, and every compressed chunk length within rd->staging_cap. On success rd->table and rd->payload_off are bound.

Parameters
[in,out]rdReader carrying parsed header fields.
[in]file_lenContainer file length in bytes.
[out]table_bufCaller buffer receiving the table.
[in]table_cap_entriesCapacity of table_buf in uint64 entries.
Returns
ra8_err_t Status code.
Return values
k_ra8_okTable loaded and validated; rd bound.
k_ra8_err_invalid_argTable shape invalid (start, monotonicity, end).
k_ra8_err_invalid_sizeTable exceeds the caller buffer / file bounds / one-call read limit, or a chunk exceeds staging.
k_ra8_err_*A file-read error, returned verbatim.
Precondition
rd's header fields were populated by the caller.
table_buf covers table_cap_entries uint64 slots.
Postcondition
On k_ra8_ok, rd->table == table_buf and rd->payload_off is set.
On any error rd->table stays NULL (reader unbound).
Note
Not thread-safe.
Since
Version 0.1.0

Definition at line 117 of file book_chunked.c.

References book_chunked_t::chunk_count, book_chunked_t::file_ctx, book_chunked_t::file_read, internal_table_check(), k_book_container_entry_len, k_book_container_header_len, k_ra8_err_invalid_size, k_ra8_ok, book_chunked_t::payload_off, RA8_INTERNAL, book_chunked_t::table, and book_chunked_t::table_cap_entries.

Referenced by internal_chunked_open_body().

◆ internal_stage_and_inflate()

ra8_err_t internal_stage_and_inflate ( const book_chunked_t * rd,
uint32_t idx,
uint8_t * buf,
uint32_t len )
static

Stage one chunk's compressed stream and inflate it into buf.

The I/O tail of book_chunked_read after the geometry checks: reads chunk idx's zlib stream into the staging buffer through the file reader, inflates it into buf, and requires the produced length to equal the requested span. Split out so the contract checks and the staged I/O each stay within the function-size budget.

Parameters
[in]rdBound reader (table validated at open).
[in]idxChunk index (< chunk_count, caller-bounded).
[out]bufDestination for exactly len inflated bytes.
[in]lenThe chunk's exact inflated span.
Returns
ra8_err_t Status code.
Return values
k_ra8_okChunk inflated into buf.
k_ra8_err_invalid_sizeThe stream inflated to the wrong length.
k_ra8_err_*A file-read or inflater error, verbatim.
Precondition
idx was bounds-checked against the validated chunk count.
buf addresses at least len writable bytes.
Postcondition
On k_ra8_ok, buf[0..len) holds the chunk's inflated bytes.
On any error buf contents are unspecified.
Note
Not thread-safe: the staging buffer is reused across calls.
Since
Version 0.1.0

Definition at line 258 of file book_chunked.c.

References book_chunked_t::file_ctx, book_chunked_t::file_read, book_chunked_t::inflate_cb, k_ra8_err_invalid_size, k_ra8_ok, book_chunked_t::payload_off, book_chunked_t::staging, and book_chunked_t::table.

Referenced by book_chunked_read().

◆ internal_table_check()

ra8_err_t internal_table_check ( const book_chunked_t * rd,
const uint64_t * table_buf,
uint64_t payload_len )
static

Validate a loaded chunk table's shape against the payload extent.

Requires table[0] == 0, strictly increasing entries, an end offset equal to payload_len (the streams exactly tile the rest of the file), and every chunk's compressed length within the staging budget. Split from internal_load_table so each half stays within the function-size budget.

Parameters
[in]rdReader carrying the parsed header fields.
[in]table_bufLoaded table (chunk_count + 1 entries).
[in]payload_lenStream bytes remaining in the file after the table.
Returns
ra8_err_t Status code.
Return values
k_ra8_okTable well-formed; every stream fits staging.
k_ra8_err_invalid_argBad start / non-monotonic / bad end offset.
k_ra8_err_invalid_sizeA compressed chunk exceeds the staging budget.
Precondition
rd->chunk_count and rd->staging_cap were populated by the caller.
table_buf holds rd->chunk_count + 1 decoded entries.
Postcondition
No state is modified (pure validation).
On k_ra8_ok every stream span is loadable through the staging buffer.
Note
Thread-safe: reads only its arguments.
Since
Version 0.1.0

Definition at line 59 of file book_chunked.c.

References book_chunked_t::chunk_count, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, and book_chunked_t::staging_cap.

Referenced by internal_load_table().

Variable Documentation

◆ s_tag_chunked

const char* const s_tag_chunked = "book_chunked"
static

Log tag for chunk-reader diagnostics.

Definition at line 28 of file book_chunked.c.

Referenced by book_chunked_open(), and book_chunked_read().