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

Zero-heap streaming RBKC container writer. More...

#include "ra8_rabook_container.h"
#include <stddef.h>
#include <stdint.h>
#include "book.h"
#include "ra8_attributes.h"
#include "ra8_compress.h"
Include dependency graph for ra8_rabook_container.c:

Go to the source code of this file.

Enumerations

enum  rbkc_layout_t : uint8_t {
  k_rbkc_chunk_bytes_off = 4U ,
  k_rbkc_total_off = 8U ,
  k_rbkc_count_off = 16U ,
  k_rbkc_reserved_off = 20U ,
  k_rbkc_u32_bytes = 4U ,
  k_rbkc_u64_bytes = 8U
}
 RBKC fixed-field sizes and offsets. More...
enum  rbkc_bits_t : uint8_t { k_rbkc_bits_per_byte = 8U }
 Number of bits shifted per little-endian output byte. More...

Functions

static void internal_put_u32 (uint8_t *out, uint32_t value)
 Encode one uint32 in little-endian order.
static void internal_put_u64 (uint8_t *out, uint64_t value)
 Encode one uint64 in little-endian order.
static ra8_err_t internal_write_exact (ra8_rabook_write_at_fn write_at, void *ctx, uint64_t offset, const uint8_t *src, uint32_t len)
 Call the destination once and require an exact successful write.
static ra8_err_t internal_validate_pointers (ra8_rabook_flat_read_fn read, ra8_rabook_write_at_fn write_at, const ra8_rabook_container_workspace_t *ws, const uint64_t *out_len, const uint32_t *out_count)
 Reject a missing callback, result, workspace, or workspace member.
static ra8_err_t internal_validate (ra8_rabook_flat_read_fn read, uint32_t flat_len, uint32_t chunk_bytes, ra8_rabook_write_at_fn write_at, const ra8_rabook_container_workspace_t *ws, const uint64_t *out_len, uint32_t *out_count)
 Validate pointers and workspace capacities before output mutation.
static ra8_err_t internal_write_prefix (ra8_rabook_write_at_fn write_at, void *ctx, uint32_t flat_len, uint32_t chunk_bytes, uint32_t count)
 Write the fixed header and reserve a zero-filled offset table.
static ra8_err_t internal_write_chunks (ra8_rabook_flat_read_fn read, void *read_ctx, uint32_t flat_len, uint32_t chunk_bytes, ra8_rabook_write_at_fn write_at, void *write_ctx, ra8_rabook_container_workspace_t *ws, uint32_t count, uint64_t payload_off)
 Read, compress, and append every independent chunk payload.
static ra8_err_t internal_write_table (ra8_rabook_write_at_fn write_at, void *ctx, const ra8_rabook_container_workspace_t *ws, uint32_t count)
 Back-fill the little-endian table after all payload streams exist.
ra8_err_t ra8_rabook_container_write (ra8_rabook_flat_read_fn read, void *read_ctx, uint32_t flat_len, uint32_t chunk_bytes, ra8_rabook_write_at_fn write_at, void *write_ctx, ra8_rabook_container_workspace_t *ws, uint64_t *out_len)
 Stream one flat RABOOK1 blob into a chunked RBKC staging object.

Detailed Description

Zero-heap streaming RBKC container writer.

Serializes the documented RBKC header and offset table around independently zlib-compressed flat-blob chunks. All storage and I/O arrive through the public contract in ra8_rabook_container.h.

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

Since
0.1.0

Definition in file ra8_rabook_container.c.

Enumeration Type Documentation

◆ rbkc_bits_t

enum rbkc_bits_t : uint8_t

Number of bits shifted per little-endian output byte.

Enumerator
k_rbkc_bits_per_byte 

Binary bits represented by one output byte.

Definition at line 36 of file ra8_rabook_container.c.

◆ rbkc_layout_t

enum rbkc_layout_t : uint8_t

RBKC fixed-field sizes and offsets.

Enumerator
k_rbkc_chunk_bytes_off 

uint32 chunk size.

k_rbkc_total_off 

uint64 inflated total.

k_rbkc_count_off 

uint32 chunk count.

k_rbkc_reserved_off 

uint32 reserved zero.

k_rbkc_u32_bytes 

Little-endian uint32.

k_rbkc_u64_bytes 

Little-endian uint64.

Definition at line 26 of file ra8_rabook_container.c.

Function Documentation

◆ internal_put_u32()

void internal_put_u32 ( uint8_t * out,
uint32_t value )
static

Encode one uint32 in little-endian order.

Writes all four bytes explicitly so output is host-endian independent.

Parameters
[out]outDestination spanning four writable bytes.
[in]valueInteger to serialize.
Precondition
out is non-NULL and has four writable bytes.
value is the complete field value, without prior byte swapping.
Postcondition
out[0..4) contains the little-endian representation of value.
Memory outside the four-byte destination is unchanged.
Note
Thread-safe for distinct output buffers.
Since
0.1.0

Definition at line 52 of file ra8_rabook_container.c.

References k_rbkc_bits_per_byte, k_rbkc_u32_bytes, and RA8_INTERNAL.

Referenced by internal_write_prefix().

◆ internal_put_u64()

void internal_put_u64 ( uint8_t * out,
uint64_t value )
static

Encode one uint64 in little-endian order.

Writes all eight bytes explicitly so output is host-endian independent.

Parameters
[out]outDestination spanning eight writable bytes.
[in]valueInteger to serialize.
Precondition
out is non-NULL and has eight writable bytes.
value is the complete field value, without prior byte swapping.
Postcondition
out[0..8) contains the little-endian representation of value.
Memory outside the eight-byte destination is unchanged.
Note
Thread-safe for distinct output buffers.
Since
0.1.0

Definition at line 71 of file ra8_rabook_container.c.

References k_rbkc_bits_per_byte, k_rbkc_u64_bytes, and RA8_INTERNAL.

Referenced by internal_write_prefix(), and internal_write_table().

◆ internal_validate()

ra8_err_t internal_validate ( ra8_rabook_flat_read_fn read,
uint32_t flat_len,
uint32_t chunk_bytes,
ra8_rabook_write_at_fn write_at,
const ra8_rabook_container_workspace_t * ws,
const uint64_t * out_len,
uint32_t * out_count )
static

Validate pointers and workspace capacities before output mutation.

Derives the bounded chunk count only after required callback and workspace members pass their preconditions.

Parameters
[in]readSource callback.
[in]flat_lenDeclared flat-blob length.
[in]chunk_bytesRequested inflated chunk size.
[in]write_atDestination callback.
[in]wsCaller-owned workspace to validate.
[in]out_lenRequired public result pointer.
[out]out_countReceives the derived chunk count.
Returns
Argument/workspace validation status.
Return values
k_ra8_okAll arguments fit and out_count is set.
k_ra8_err_null_ptrA callback, result, workspace, or member is NULL.
k_ra8_err_invalid_argA required size is zero.
k_ra8_err_invalid_sizeA scratch or offset-table capacity is insufficient.
Precondition
The caller has not mutated the staging destination yet.
Non-NULL ws members describe their true capacities.
Postcondition
Success produces a nonzero out_count fitting ws.
Failure does not call either callback or mutate workspace bytes.
Note
Thread-safe for distinct argument objects.
Since
0.1.0

Definition at line 190 of file ra8_rabook_container.c.

References ra8_rabook_container_workspace_t::compressor_cap, ra8_rabook_container_workspace_t::input_cap, internal_validate_pointers(), k_ra8_compress_scratch_bytes, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, ra8_rabook_container_workspace_t::offset_cap, and RA8_INTERNAL.

Referenced by ra8_rabook_container_write().

◆ internal_validate_pointers()

ra8_err_t internal_validate_pointers ( ra8_rabook_flat_read_fn read,
ra8_rabook_write_at_fn write_at,
const ra8_rabook_container_workspace_t * ws,
const uint64_t * out_len,
const uint32_t * out_count )
static

Reject a missing callback, result, workspace, or workspace member.

Isolates the pointer-only precondition chain so the caller's own size and capacity checks stay readable as a short, flat sequence.

Parameters
[in]readSource callback.
[in]write_atDestination callback.
[in]wsCaller-owned workspace to validate.
[in]out_lenRequired public result pointer.
[in]out_countRequired chunk-count result pointer.
Returns
Pointer validation status.
Return values
k_ra8_okEvery required pointer is non-NULL.
k_ra8_err_null_ptrA callback, result, workspace, or member is NULL.
Precondition
None of the supplied pointers have been dereferenced yet.
ws, when non-NULL, has not been mutated by this call.
Postcondition
No pointer is dereferenced.
The return value fully identifies whether validation may continue.
Note
Thread-safe for distinct argument objects.
Since
0.1.0

Definition at line 131 of file ra8_rabook_container.c.

References ra8_rabook_container_workspace_t::compressed, ra8_rabook_container_workspace_t::compressor, ra8_rabook_container_workspace_t::input, k_ra8_err_null_ptr, k_ra8_ok, ra8_rabook_container_workspace_t::offsets, and RA8_INTERNAL.

Referenced by internal_validate().

◆ internal_write_chunks()

ra8_err_t internal_write_chunks ( ra8_rabook_flat_read_fn read,
void * read_ctx,
uint32_t flat_len,
uint32_t chunk_bytes,
ra8_rabook_write_at_fn write_at,
void * write_ctx,
ra8_rabook_container_workspace_t * ws,
uint32_t count,
uint64_t payload_off )
static

Read, compress, and append every independent chunk payload.

Each exact flat range becomes one RFC 1950 stream; payload-relative start offsets are recorded for the later table back-fill.

Parameters
[in]readSource callback.
[in,out]read_ctxSource callback context.
[in]flat_lenDeclared flat-blob length.
[in]chunk_bytesInflated bytes per chunk.
[in]write_atDestination callback.
[in,out]write_ctxDestination callback context.
[in,out]wsExclusive input/compression/table workspace.
[in]countDerived chunk count.
[in]payload_offAbsolute first-payload byte offset.
Returns
Source, compression, or destination status.
Return values
k_ra8_okEvery stream and the terminal table offset were produced.
k_ra8_err_invalid_sizeA callback was short or an offset overflowed.
Precondition
Prefix/table reservation succeeded and all arguments passed internal_validate.
ws buffers do not overlap and remain live throughout the loop.
Postcondition
Success sets offsets [0..count] monotonically with offset zero first.
Failure leaves no successful final-length claim.
Note
Not thread-safe with respect to callback contexts or ws.
Since
0.1.0

Definition at line 299 of file ra8_rabook_container.c.

References ra8_rabook_container_workspace_t::compressed, ra8_rabook_container_workspace_t::compressed_cap, ra8_rabook_container_workspace_t::compressor, ra8_rabook_container_workspace_t::compressor_cap, ra8_rabook_container_workspace_t::input, internal_write_exact(), k_ra8_err_invalid_size, k_ra8_ok, ra8_rabook_container_workspace_t::offsets, ra8_compress_zlib(), and RA8_INTERNAL.

Referenced by ra8_rabook_container_write().

◆ internal_write_exact()

ra8_err_t internal_write_exact ( ra8_rabook_write_at_fn write_at,
void * ctx,
uint64_t offset,
const uint8_t * src,
uint32_t len )
static

Call the destination once and require an exact successful write.

Preserves backend errors and converts a successful short write into k_ra8_err_invalid_size, preventing a torn container from succeeding.

Parameters
[in]write_atDestination callback.
[in,out]ctxDestination callback context.
[in]offsetAbsolute staging-object byte offset.
[in]srcSource spanning len readable bytes.
[in]lenExact number of bytes to write.
Returns
Exact-write or backend status.
Return values
k_ra8_okThe callback stored exactly len bytes.
k_ra8_err_invalid_sizeThe callback reported a successful short write.
Precondition
write_at, ctx, and src satisfy the public callback contract.
The destination range [offset, offset + len) is representable.
Postcondition
Success means the complete requested range reached the backend.
A backend failure is returned unchanged.
Note
Not thread-safe unless the supplied backend context is synchronized.
Since
0.1.0

Definition at line 98 of file ra8_rabook_container.c.

References k_ra8_err_invalid_size, k_ra8_ok, and RA8_INTERNAL.

Referenced by internal_write_chunks(), internal_write_prefix(), and internal_write_table().

◆ internal_write_prefix()

ra8_err_t internal_write_prefix ( ra8_rabook_write_at_fn write_at,
void * ctx,
uint32_t flat_len,
uint32_t chunk_bytes,
uint32_t count )
static

Write the fixed header and reserve a zero-filled offset table.

Serializes canonical little-endian geometry, then writes exactly count + 1 zero entries so later payload writes never depend on sparse-file behavior.

Parameters
[in]write_atDestination callback.
[in,out]ctxDestination callback context.
[in]flat_lenDeclared inflated RABOOK1 length.
[in]chunk_bytesInflated bytes per chunk.
[in]countDerived nonzero chunk count.
Returns
Prefix-write status.
Return values
k_ra8_okHeader and complete table reservation were written.
k_ra8_err_invalid_sizeA successful callback was short.
Precondition
Arguments were accepted by internal_validate.
The destination is a private empty or overwrite-safe staging object.
Postcondition
Success reserves bytes through the future payload offset.
Failure is explicit and the caller will abort the staging object.
Note
Not thread-safe with respect to ctx.
Since
0.1.0

Definition at line 245 of file ra8_rabook_container.c.

References internal_put_u32(), internal_put_u64(), internal_write_exact(), k_book_container_entry_len, k_book_container_header_len, k_book_container_magic_len, k_ra8_ok, k_rbkc_chunk_bytes_off, k_rbkc_count_off, k_rbkc_reserved_off, k_rbkc_total_off, and RA8_INTERNAL.

Referenced by ra8_rabook_container_write().

◆ internal_write_table()

ra8_err_t internal_write_table ( ra8_rabook_write_at_fn write_at,
void * ctx,
const ra8_rabook_container_workspace_t * ws,
uint32_t count )
static

Back-fill the little-endian table after all payload streams exist.

Serializes every caller-workspace offset independently, including the terminal payload length at entry count.

Parameters
[in]write_atDestination callback.
[in,out]ctxDestination callback context.
[in]wsWorkspace holding count + 1 finalized offsets.
[in]countNumber of compressed payload streams.
Returns
Table-write status.
Return values
k_ra8_okEvery offset entry was stored exactly.
k_ra8_err_invalid_sizeA successful callback was short.
Precondition
internal_write_chunks succeeded and populated all entries.
The table reservation from internal_write_prefix still exists.
Postcondition
Success makes the complete payload independently addressable.
Backend errors are propagated unchanged.
Note
Not thread-safe with respect to ctx.
Since
0.1.0

Definition at line 370 of file ra8_rabook_container.c.

References internal_put_u64(), internal_write_exact(), k_book_container_entry_len, k_book_container_header_len, k_ra8_ok, ra8_rabook_container_workspace_t::offsets, and RA8_INTERNAL.

Referenced by ra8_rabook_container_write().

◆ ra8_rabook_container_write()

ra8_err_t ra8_rabook_container_write ( ra8_rabook_flat_read_fn read,
void * read_ctx,
uint32_t flat_len,
uint32_t chunk_bytes,
ra8_rabook_write_at_fn write_at,
void * write_ctx,
ra8_rabook_container_workspace_t * ws,
uint64_t * out_len )
nodiscard

Stream one flat RABOOK1 blob into a chunked RBKC staging object.

Writes the fixed little-endian header, reserves the complete offset table, then reads and zlib-compresses each independent flat chunk. The table is back-filled only after all streams succeed. The caller must target a private staging object and validate it before atomic publication; this function deliberately owns neither filenames nor commit policy.

Parameters
[in]readSource read callback.
[in,out]read_ctxContext passed to read.
[in]flat_lenExact nonzero flat RABOOK1 length.
[in]chunk_bytesInflated bytes per independently compressed chunk.
[in]write_atRandom-write callback for the staging destination.
[in,out]write_ctxContext passed to write_at.
[in,out]wsExclusive caller-owned workspace.
[out]out_lenFinal RBKC byte length.
Returns
Container write status.
Return values
k_ra8_okComplete RBKC bytes were written and out_len was set.
k_ra8_err_null_ptrA required pointer or workspace member was NULL.
k_ra8_err_invalid_argflat_len or chunk_bytes was zero.
k_ra8_err_invalid_sizeA workspace/table bound was insufficient, an offset overflowed, or a callback was short.
k_ra8_err_no_memThe compressed-chunk destination was too small.
Returns
Any other source, destination, or compressor error is propagated.
Precondition
ws storage is non-overlapping and exclusively owned for the call.
read serves every byte in [0, flat_len) repeatably.
write_at targets a private staging object and supports back-filling.
Postcondition
On success the output conforms to book_container_t.
On failure out_len is zero and the caller must abort its staging object.
No dynamically allocated memory or global mutable state is used.
Note
Not thread-safe with respect to the supplied callbacks or workspace.
Since
0.1.0

Definition at line 389 of file ra8_rabook_container.c.

References internal_validate(), internal_write_chunks(), internal_write_prefix(), internal_write_table(), k_book_container_entry_len, k_book_container_header_len, k_ra8_err_invalid_size, k_ra8_ok, and ra8_rabook_container_workspace_t::offsets.

Referenced by internal_emit_container(), and priv_media_download_format_rabook().