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

Checksummed binary index and immutable body I/O for mdl_cache. More...

#include <limits.h>
#include <stdint.h>
#include <string.h>
#include "mdl_cache_internal.h"
#include "mdl_hash.h"
#include "mdl_sanitize.h"
#include "mdl_url_guard.h"
Include dependency graph for mdl_cache_io.c:

Go to the source code of this file.

Enumerations

enum  mdl_cache_binary_limit_t : uint32_t {
  k_cache_header_bytes = 32U ,
  k_cache_record_bytes = 36U ,
  k_cache_trailer_bytes = 8U ,
  k_cache_io_call_max = 2000000U ,
  k_cache_status_min = 100U ,
  k_cache_status_max = 599U ,
  k_cache_hex_high_shift = 60U ,
  k_cache_nibble_mask = 0x0FU ,
  k_cache_u64_high_shift = 56U ,
  k_cache_record_status = 24U ,
  k_cache_record_url_len = 26U ,
  k_cache_record_path_len = 28U ,
  k_cache_record_etag_len = 30U ,
  k_cache_record_time_len = 32U ,
  k_cache_record_reserved = 34U ,
  k_cache_header_count = 12U ,
  k_cache_header_host = 24U
}
 Canonical binary layout and bounded I/O constants. More...

Functions

static void internal_cache_hex16 (char *destination, uint64_t value)
 Encode exactly sixteen lowercase hexadecimal digits.
static bool internal_cache_host_leaf (char *destination, size_t capacity, uint64_t host_hash)
 Format one host-directory leaf without stdio.
static bool internal_cache_body_leaf (char *destination, size_t capacity, uint64_t url_hash, uint64_t content_hash)
 Format one immutable body leaf without stdio.
static void internal_cache_put_u16 (uint8_t *out, uint16_t value)
 Encode one big-endian uint16.
static void internal_cache_put_u64 (uint8_t *out, uint64_t value)
 Encode one big-endian uint64.
static uint16_t internal_cache_get_u16 (const uint8_t *in)
 Decode one big-endian uint16.
static uint64_t internal_cache_get_u64 (const uint8_t *in)
 Decode one big-endian uint64.
static ra8_err_t internal_cache_read_all (fw_fs_file_t *file, uint8_t *destination, uint32_t length, uint32_t *calls)
 Read exactly one bounded span from an open file.
static ra8_err_t internal_cache_ensure_directory (mdl_storage_t *storage, const char *path)
 Ensure a cache namespace component is a real directory.
static ra8_err_t internal_cache_paths (mdl_cache_t *cache, const char *url, mdl_cache_paths_t *paths)
 Derive and prepare one host-specific cache namespace.
static bool internal_cache_record_valid (const mdl_cache_record_t *record, const mdl_cache_paths_t *paths)
 Validate one decoded persistent record.
static ra8_err_t internal_cache_read_record (fw_fs_file_t *file, uint32_t *calls, uint64_t *hash, mdl_cache_record_t *record, const mdl_cache_paths_t *paths)
 Decode one variable-length record and update its payload hash.
static ra8_err_t internal_cache_decode (mdl_cache_t *cache, const mdl_cache_paths_t *paths, uint64_t size_bytes)
 Decode and authenticate one complete index file.
static ra8_err_t internal_cache_discard_index (mdl_cache_t *cache, const char *path)
 Remove one corrupt regular index.
ra8_err_t priv_mdl_cache_load (mdl_cache_t *cache, const char *url, mdl_cache_paths_t *paths, bool *rebuilt)
 Prepare a host directory and load or recover its index.
static bool internal_cache_encode_record (const mdl_cache_record_t *record, uint8_t *header, uint16_t *lengths)
 Encode one record header and compute exact string lengths.
static ra8_err_t internal_cache_payload_identity (const mdl_cache_index_t *index, uint64_t *out_bytes, uint64_t *out_hash)
 Compute payload extent and hash for the current index.
static ra8_err_t internal_cache_write_records (mdl_storage_txn_t *writer, const mdl_cache_index_t *index)
 Stream every encoded record into an active transaction.
ra8_err_t priv_mdl_cache_save (mdl_cache_t *cache, const mdl_cache_paths_t *paths)
 Transactionally publish the current host index.
static ra8_err_t internal_cache_read_body_exact (mdl_storage_t *storage, const char *body_path, char *buffer, uint64_t size_bytes)
 Read a body file's exact declared extent and confirm no trailer.
ra8_err_t priv_mdl_cache_read_body (mdl_storage_t *storage, const mdl_cache_paths_t *paths, const mdl_cache_record_t *record, char *buffer, size_t capacity, size_t *out_length)
 Read and hash-check one retained body into caller storage.
ra8_err_t priv_mdl_cache_publish_body (mdl_storage_t *storage, const mdl_cache_paths_t *paths, uint64_t url_hash, uint64_t content_hash, const char *buffer, size_t length, char *relative_path, size_t relative_capacity)
 Publish one new body under its immutable content-derived leaf.

Variables

static const uint8_t s_cache_magic [k_cache_trailer_bytes]
 Canonical cache index magic.

Detailed Description

Checksummed binary index and immutable body I/O for mdl_cache.

Owns portable namespace, stream, and transaction operations while the policy state machine remains in mdl_cache.c.

Definition in file mdl_cache_io.c.

Enumeration Type Documentation

◆ mdl_cache_binary_limit_t

enum mdl_cache_binary_limit_t : uint32_t

Canonical binary layout and bounded I/O constants.

Enumerator
k_cache_header_bytes 

Fixed index header width.

k_cache_record_bytes 

Fixed record header width.

k_cache_trailer_bytes 

Payload-hash trailer width.

k_cache_io_call_max 

Short-I/O progress ceiling.

k_cache_status_min 

Smallest retained HTTP code.

k_cache_status_max 

Largest retained HTTP code.

k_cache_hex_high_shift 

Shift of the first hash nibble.

k_cache_nibble_mask 

Low hexadecimal nibble mask.

k_cache_u64_high_shift 

Shift of the first uint64 byte.

k_cache_record_status 

Record HTTP-status offset.

k_cache_record_url_len 

Record URL-length offset.

k_cache_record_path_len 

Record path-length offset.

k_cache_record_etag_len 

Record ETag-length offset.

k_cache_record_time_len 

Record modified-length offset.

k_cache_record_reserved 

Record reserved-field offset.

k_cache_header_count 

Header record-count offset.

k_cache_header_host 

Header host-hash offset.

Definition at line 19 of file mdl_cache_io.c.

Function Documentation

◆ internal_cache_body_leaf()

bool internal_cache_body_leaf ( char * destination,
size_t capacity,
uint64_t url_hash,
uint64_t content_hash )
static

Format one immutable body leaf without stdio.

Combines full URL and content identities so a new entity never truncates or overwrites an older cache-body generation.

Parameters
[out]destinationWritable destination.
[in]capacityDestination extent.
[in]url_hashURL identity.
[in]content_hashBody identity.
Returns
Whether the exact leaf fit.
Return values
trueThe canonical leaf and NUL were written.
falseThe destination capacity was insufficient.
Precondition
destination is non-NULL.
Capacity describes the complete writable span.
Postcondition
Success writes the canonical content-derived leaf and NUL.
Failure leaves the destination unspecified.
Note
Both hashes retain all sixteen hexadecimal digits.
Since
0.1.0

Definition at line 114 of file mdl_cache_io.c.

References internal_cache_hex16(), memcpy(), and RA8_INTERNAL.

Referenced by priv_mdl_cache_publish_body().

◆ internal_cache_decode()

ra8_err_t internal_cache_decode ( mdl_cache_t * cache,
const mdl_cache_paths_t * paths,
uint64_t size_bytes )
static

Decode and authenticate one complete index file.

Validates magic, schema, lengths, host binding, every record, exact file extent, and the payload trailer before accepting the index.

Parameters
[in,out]cacheCache binding and destination workspace.
[in]pathsBound host paths.
[in]size_bytesSnapshotted file extent.
Returns
Canonical open, parse, or authentication status.
Return values
k_ra8_okThe complete index was authenticated.
k_ra8_err_invalid_stateStructural or payload identity checks failed.
otherOpening, reading, or closing the index failed.
Precondition
Index path is a regular file of size_bytes.
Cache workspace is exclusively owned.
Postcondition
Success publishes a complete validated index.
Failure leaves the workspace unspecified for caller reset.
Note
Exact extent and payload hash are both checked.
Since
0.1.0

Definition at line 452 of file mdl_cache_io.c.

References mdl_storage_t::file_workspace, mdl_storage_t::file_workspace_bytes, mdl_storage_t::fs, fw_fs_close(), fw_fs_open(), mdl_cache_paths_t::host_hash, mdl_cache_t::index, mdl_cache_paths_t::index_path, internal_cache_get_u16(), internal_cache_get_u64(), internal_cache_read_all(), internal_cache_read_record(), k_cache_header_bytes, k_cache_header_count, k_cache_header_host, k_cache_trailer_bytes, k_fw_fs_open_read, k_mdl_cache_record_max, k_mdl_cache_schema_version, k_mdl_fnv_offset, k_ra8_err_invalid_state, k_ra8_ok, memcmp(), mdl_cache_index_t::record_count, mdl_cache_index_t::records, s_cache_magic, mdl_cache_t::storage, and fw_fs_t::streams.

Referenced by priv_mdl_cache_load().

◆ internal_cache_discard_index()

ra8_err_t internal_cache_discard_index ( mdl_cache_t * cache,
const char * path )
static

Remove one corrupt regular index.

Restats the rejected path and unlinks it only when it remains a regular file, preserving symlinks and special nodes fail-closed.

Parameters
[in,out]cacheCache binding.
[in]pathIndex path.
Returns
Canonical inspection or unlink status.
Return values
k_ra8_okThe path is absent after the operation.
k_ra8_err_invalid_stateThe path is not a regular file.
otherStat or unlink failed.
Precondition
Both pointers are non-NULL.
Load or validation has already rejected the file.
Postcondition
Success leaves the path absent.
Non-regular objects are preserved and rejected.
Note
Cache data is disposable; library state is not handled here.
Since
0.1.0

Definition at line 516 of file mdl_cache_io.c.

References fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_stat(), fw_fs_unlink(), k_fw_fs_node_file, k_ra8_err_invalid_state, k_ra8_ok, fw_fs_t::names, RA8_INTERNAL, mdl_cache_t::storage, and fw_fs_stat_t::type.

Referenced by priv_mdl_cache_load().

◆ internal_cache_encode_record()

bool internal_cache_encode_record ( const mdl_cache_record_t * record,
uint8_t * header,
uint16_t * lengths )
static

Encode one record header and compute exact string lengths.

Measures every persistent string before initializing the canonical fixed-width header, preventing truncated identities.

Parameters
[in]recordValidated record.
[out]headerCanonical fixed header.
[out]lengthsFour encoded string extents.
Returns
Whether every string extent fits uint16.
Return values
trueHeader and field lengths are complete.
falseAt least one encoded field exceeds uint16.
Precondition
Every pointer is non-NULL.
Record strings are NUL-terminated.
Postcondition
Success initializes all header bytes and lengths.
Failure performs no I/O.
Note
Signed time is retained bit-for-bit as uint64.
Since
0.1.0

Definition at line 591 of file mdl_cache_io.c.

References mdl_cache_record_t::content_hash, mdl_cache_record_t::etag, mdl_cache_record_t::fetched_at, internal_cache_put_u16(), internal_cache_put_u64(), k_cache_record_bytes, k_cache_record_etag_len, k_cache_record_path_len, k_cache_record_status, k_cache_record_time_len, k_cache_record_url_len, mdl_cache_record_t::last_modified, memset(), mdl_cache_record_t::relative_path, mdl_cache_record_t::response_status, strlen(), mdl_cache_record_t::url, and mdl_cache_record_t::url_hash.

Referenced by internal_cache_payload_identity(), and internal_cache_write_records().

◆ internal_cache_ensure_directory()

ra8_err_t internal_cache_ensure_directory ( mdl_storage_t * storage,
const char * path )
static

Ensure a cache namespace component is a real directory.

Stats before and after optional creation so symlinks and special nodes can never satisfy the cache-directory contract.

Parameters
[in,out]storageBound portable filesystem.
[in]pathCanonical absolute directory path.
Returns
Canonical stat or mkdir status.
Return values
k_ra8_okA real directory exists at the path.
k_ra8_err_invalid_stateThe path resolves to another node type.
otherNamespace inspection or creation failed.
Precondition
Both pointers are non-NULL.
path is confined by the filesystem binding.
Postcondition
Success proves a directory exists at path.
A symlink or special node is never accepted.
Note
Safe for an existing directory.
Since
0.1.0

Definition at line 277 of file mdl_cache_io.c.

References fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_mkdir(), fw_fs_stat(), k_fw_fs_node_directory, k_ra8_err_invalid_state, k_ra8_ok, fw_fs_t::names, RA8_INTERNAL, and fw_fs_stat_t::type.

Referenced by internal_cache_paths().

◆ internal_cache_get_u16()

uint16_t internal_cache_get_u16 ( const uint8_t * in)
static

Decode one big-endian uint16.

Reassembles both bytes explicitly so unaligned file data never depends on host representation.

Parameters
[in]inTwo readable bytes.
Returns
Decoded unsigned value.
Return values
uint16_tThe exact represented value.
Precondition
in is non-NULL.
Two bytes are readable.
Postcondition
Input is unchanged.
Result is independent of alignment.
Note
Host endianness is irrelevant.
Since
0.1.0

Definition at line 190 of file mdl_cache_io.c.

References RA8_INTERNAL.

Referenced by internal_cache_decode(), and internal_cache_read_record().

◆ internal_cache_get_u64()

uint64_t internal_cache_get_u64 ( const uint8_t * in)
static

Decode one big-endian uint64.

Folds each byte into the accumulator in encoded order without an unaligned integer load.

Parameters
[in]inEight readable bytes.
Returns
Decoded unsigned value.
Return values
uint64_tThe exact represented value.
Precondition
in is non-NULL.
Eight bytes are readable.
Postcondition
Input is unchanged.
Result is independent of alignment.
Note
Host endianness is irrelevant.
Since
0.1.0

Definition at line 209 of file mdl_cache_io.c.

References RA8_INTERNAL.

Referenced by internal_cache_decode(), and internal_cache_read_record().

◆ internal_cache_hex16()

void internal_cache_hex16 ( char * destination,
uint64_t value )
static

Encode exactly sixteen lowercase hexadecimal digits.

Emits one digit per nibble from most significant to least so cache namespace spelling is fixed regardless of host endianness.

Parameters
[out]destinationWritable sixteen-byte destination.
[in]valueUnsigned value to encode.
Precondition
destination spans at least sixteen bytes.
Integer input uses its declared width.
Postcondition
Every destination byte is an ASCII hexadecimal digit.
Leading zeroes are retained.
Note
No libc formatting or locale is involved.
Since
0.1.0

Definition at line 56 of file mdl_cache_io.c.

References k_cache_hex_high_shift, k_cache_nibble_mask, and RA8_INTERNAL.

Referenced by internal_cache_body_leaf(), and internal_cache_host_leaf().

◆ internal_cache_host_leaf()

bool internal_cache_host_leaf ( char * destination,
size_t capacity,
uint64_t host_hash )
static

Format one host-directory leaf without stdio.

Concatenates the fixed prefix and the complete host hash only after proving the destination can hold the canonical spelling.

Parameters
[out]destinationWritable destination.
[in]capacityDestination extent.
[in]host_hashHost identity.
Returns
Whether the exact leaf fit.
Return values
trueThe complete leaf and NUL were written.
falseThe destination capacity was insufficient.
Precondition
destination is non-NULL.
Capacity describes the complete writable span.
Postcondition
Success writes host- plus sixteen digits and NUL.
Failure leaves the destination unspecified.
Note
The representation is stable across platforms.
Since
0.1.0

Definition at line 83 of file mdl_cache_io.c.

References internal_cache_hex16(), and memcpy().

Referenced by internal_cache_paths().

◆ internal_cache_paths()

ra8_err_t internal_cache_paths ( mdl_cache_t * cache,
const char * url,
mdl_cache_paths_t * paths )
static

Derive and prepare one host-specific cache namespace.

Parses the canonical host, hashes its exact spelling, derives fixed leaves, and verifies both cache directory components.

Parameters
[in,out]cacheCache binding.
[in]urlAbsolute URL.
[out]pathsDerived paths and identity.
Returns
Canonical URL, path, or namespace status.
Return values
k_ra8_okEvery path and the host identity were initialized.
k_ra8_err_invalid_argThe URL or cache binding was invalid.
k_ra8_err_invalid_sizeA derived path exceeded its bound.
otherDirectory inspection or creation failed.
Precondition
All pointers are non-NULL.
Cache root is canonical and absolute.
Postcondition
Success initializes every paths field.
Success proves root and host directory are real directories.
Note
Host names are represented by a fixed hash leaf.
Since
0.1.0

Definition at line 318 of file mdl_cache_io.c.

References mdl_cache_paths_t::directory, mdl_cache_paths_t::host, mdl_cache_paths_t::host_hash, mdl_cache_paths_t::index_path, internal_cache_ensure_directory(), internal_cache_host_leaf(), k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, mdl_hash_str(), mdl_path_join(), mdl_url_host(), mdl_cache_t::root, and mdl_cache_t::storage.

Referenced by priv_mdl_cache_load().

◆ internal_cache_payload_identity()

ra8_err_t internal_cache_payload_identity ( const mdl_cache_index_t * index,
uint64_t * out_bytes,
uint64_t * out_hash )
static

Compute payload extent and hash for the current index.

Runs the same canonical record encoder used by publication and folds every header and string byte without materializing a blob.

Parameters
[in]indexValidated cache index.
[out]out_bytesExact encoded payload extent.
[out]out_hashExact encoded payload FNV identity.
Returns
Canonical validation or overflow status.
Return values
k_ra8_okExact payload extent and identity were computed.
k_ra8_err_invalid_sizeA record field cannot be encoded.
Precondition
All pointers are non-NULL.
Record count is within capacity.
Postcondition
Success initializes both outputs.
No storage operation occurs.
Note
The same encoder is used by publication.
Since
0.1.0

Definition at line 630 of file mdl_cache_io.c.

References mdl_cache_record_t::etag, internal_cache_encode_record(), k_cache_record_bytes, k_mdl_fnv_offset, k_ra8_err_invalid_size, k_ra8_ok, mdl_cache_record_t::last_modified, mdl_hash_bytes_seed(), RA8_INTERNAL, mdl_cache_index_t::record_count, mdl_cache_index_t::records, mdl_cache_record_t::relative_path, and mdl_cache_record_t::url.

Referenced by priv_mdl_cache_save().

◆ internal_cache_put_u16()

void internal_cache_put_u16 ( uint8_t * out,
uint16_t value )
static

Encode one big-endian uint16.

Writes the most-significant byte first to define a host-independent persistent representation.

Parameters
[out]outTwo writable bytes.
[in]valueValue to encode.
Precondition
out is non-NULL.
Two bytes are writable.
Postcondition
Both bytes are initialized canonically.
Decoding recovers value.
Note
Host endianness is irrelevant.
Since
0.1.0

Definition at line 150 of file mdl_cache_io.c.

References RA8_INTERNAL.

Referenced by internal_cache_encode_record(), and priv_mdl_cache_save().

◆ internal_cache_put_u64()

void internal_cache_put_u64 ( uint8_t * out,
uint64_t value )
static

Encode one big-endian uint64.

Walks every byte from the most-significant position down to define a stable binary representation without alignment assumptions.

Parameters
[out]outEight writable bytes.
[in]valueValue to encode.
Precondition
out is non-NULL.
Eight bytes are writable.
Postcondition
Every byte is initialized canonically.
Decoding recovers value.
Note
Host endianness is irrelevant.
Since
0.1.0

Definition at line 169 of file mdl_cache_io.c.

References k_cache_u64_high_shift, and RA8_INTERNAL.

Referenced by internal_cache_encode_record(), and priv_mdl_cache_save().

◆ internal_cache_read_all()

ra8_err_t internal_cache_read_all ( fw_fs_file_t * file,
uint8_t * destination,
uint32_t length,
uint32_t * calls )
static

Read exactly one bounded span from an open file.

Retries positive short reads while bounding the total backend-call count and rejecting zero progress.

Parameters
[in,out]fileOpen readable file.
[out]destinationWritable destination bytes.
[in]lengthExact requested extent.
[in,out]callsShared operation-call counter.
Returns
Canonical read or progress status.
Return values
k_ra8_okExactly the requested bytes were read.
k_ra8_err_invalid_stateThe backend reported zero progress.
k_ra8_err_invalid_sizeThe call-count ceiling was exhausted.
otherThe backend read failed.
Precondition
Every pointer is non-NULL.
Destination spans length bytes.
Postcondition
Success initializes exactly length bytes.
Zero progress and call exhaustion fail closed.
Note
Short successful reads are retried.
Since
0.1.0

Definition at line 239 of file mdl_cache_io.c.

References fw_fs_read(), k_cache_io_call_max, k_ra8_err_invalid_size, k_ra8_err_invalid_state, and k_ra8_ok.

Referenced by internal_cache_decode(), internal_cache_read_body_exact(), and internal_cache_read_record().

◆ internal_cache_read_body_exact()

ra8_err_t internal_cache_read_body_exact ( mdl_storage_t * storage,
const char * body_path,
char * buffer,
uint64_t size_bytes )
static

Read a body file's exact declared extent and confirm no trailer.

Opens body_path, reads exactly size_bytes into buffer, then probes for one more byte to reject a file that grew past its recorded size between stat and read, and always closes the handle even on a read failure.

Parameters
[in,out]storageBound filesystem interface and shared read workspace.
[in]body_pathComplete path of the body file.
[out]bufferDestination of exactly size_bytes on success.
[in]size_bytesExact expected body length in bytes.
Returns
Read-and-close status.
Return values
k_ra8_okExactly size_bytes were read and the file closed cleanly.
k_ra8_err_invalid_stateA byte remained after size_bytes.
otherThe open, read, or close call failed.
Precondition
storage, body_path, and buffer are non-NULL.
buffer holds at least size_bytes writable bytes.
Postcondition
The file handle is closed on every return path.
On success exactly size_bytes sit in buffer; a failure leaves its contents unspecified.
Note
Not thread-safe; shares the caller's file workspace.
Since
Version 0.1.0

Definition at line 766 of file mdl_cache_io.c.

References mdl_storage_t::file_workspace, mdl_storage_t::file_workspace_bytes, mdl_storage_t::fs, fw_fs_close(), fw_fs_open(), fw_fs_read(), internal_cache_read_all(), k_fw_fs_open_read, k_ra8_err_invalid_state, k_ra8_ok, RA8_INTERNAL, and fw_fs_t::streams.

Referenced by priv_mdl_cache_read_body().

◆ internal_cache_read_record()

ra8_err_t internal_cache_read_record ( fw_fs_file_t * file,
uint32_t * calls,
uint64_t * hash,
mdl_cache_record_t * record,
const mdl_cache_paths_t * paths )
static

Decode one variable-length record and update its payload hash.

Authenticates the fixed header and each bounded string while advancing the file and running payload identity in lockstep.

Parameters
[in,out]fileOpen index file.
[in,out]callsRead-call counter.
[in,out]hashRunning payload hash.
[out]recordDestination record.
[in]pathsBound host identity.
Returns
Canonical parse or validation status.
Return values
k_ra8_okOne complete canonical record was decoded.
k_ra8_err_invalid_sizeAn encoded field exceeded its destination.
k_ra8_err_invalid_stateReserved or semantic fields were invalid.
otherExact file reads failed.
Precondition
Every pointer is non-NULL.
File is positioned at a record header.
Postcondition
Success initializes record and advances to the next record.
Hash covers the complete encoded record.
Note
Lengths are checked before string reads.
Since
0.1.0

Definition at line 390 of file mdl_cache_io.c.

References mdl_cache_record_t::etag, internal_cache_get_u16(), internal_cache_get_u64(), internal_cache_read_all(), internal_cache_record_valid(), k_cache_record_bytes, k_cache_record_etag_len, k_cache_record_path_len, k_cache_record_reserved, k_cache_record_status, k_cache_record_time_len, k_cache_record_url_len, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_ok, mdl_cache_record_t::last_modified, mdl_hash_bytes_seed(), RA8_INTERNAL, mdl_cache_record_t::relative_path, and mdl_cache_record_t::url.

Referenced by internal_cache_decode().

◆ internal_cache_record_valid()

bool internal_cache_record_valid ( const mdl_cache_record_t * record,
const mdl_cache_paths_t * paths )
static

Validate one decoded persistent record.

Checks bounded strings, status/time domains, exact URL hash, and the parsed host identity before a record becomes selectable.

Parameters
[in]recordCandidate record.
[in]pathsBound host identity.
Returns
Whether all fields and identities are canonical.
Return values
trueThe record is safe to retain and select.
falseA field or derived identity was invalid.
Precondition
Both pointers are non-NULL.
String fields are NUL-terminated within their arrays.
Postcondition
Inputs remain unchanged.
True implies exact URL and host hashes match.
Note
Body existence is validated separately.
Since
0.1.0

Definition at line 353 of file mdl_cache_io.c.

References mdl_cache_record_t::etag, mdl_cache_record_t::fetched_at, mdl_cache_paths_t::host_hash, k_cache_status_max, k_cache_status_min, k_mdl_gov_host_max, mdl_cache_record_t::last_modified, mdl_hash_str(), mdl_url_host(), RA8_INTERNAL, mdl_cache_record_t::relative_path, mdl_cache_record_t::response_status, mdl_cache_record_t::url, and mdl_cache_record_t::url_hash.

Referenced by internal_cache_read_record(), and priv_mdl_cache_save().

◆ internal_cache_write_records()

ra8_err_t internal_cache_write_records ( mdl_storage_txn_t * writer,
const mdl_cache_index_t * index )
static

Stream every encoded record into an active transaction.

Writes each fixed record header followed by its four exact string spans, matching the prior payload-identity pass byte for byte.

Parameters
[in,out]writerActive index transaction.
[in]indexValidated cache index.
Returns
Canonical encoding or write status.
Return values
k_ra8_okEvery record byte was staged.
k_ra8_err_invalid_sizeA record field cannot be encoded.
otherTransaction writing failed.
Precondition
Both pointers are non-NULL.
writer owns an active transaction.
Postcondition
Success writes the exact payload used for identity calculation.
Failure leaves the transaction active for caller abort.
Note
Strings are written without terminating NUL bytes.
Since
0.1.0

Definition at line 675 of file mdl_cache_io.c.

References mdl_cache_record_t::etag, internal_cache_encode_record(), k_cache_record_bytes, k_ra8_err_invalid_size, k_ra8_ok, mdl_cache_record_t::last_modified, mdl_storage_txn_write(), RA8_INTERNAL, mdl_cache_index_t::record_count, mdl_cache_index_t::records, mdl_cache_record_t::relative_path, and mdl_cache_record_t::url.

Referenced by priv_mdl_cache_save().

◆ priv_mdl_cache_load()

ra8_err_t priv_mdl_cache_load ( mdl_cache_t * cache,
const char * url,
mdl_cache_paths_t * paths,
bool * rebuilt )

Prepare a host directory and load or recover its index.

Derives a host-bound namespace, authenticates an existing index, and discards only a corrupt regular index before resetting it.

Parameters
[in,out]cacheCache binding and index workspace.
[in]urlRequest URL used to select the host.
[out]pathsDerived host paths.
[out]rebuiltWhether a corrupt regular index was discarded.
Returns
Canonical path, namespace, or parse status.
Return values
k_ra8_okPaths and a valid or empty index are available.
k_ra8_err_invalid_stateA non-regular index or invalid namespace exists.
otherURL parsing, directory, file, or cleanup failed.
Precondition
All pointers are non-NULL and cache root is canonical.
Cache storage and index workspace are exclusively owned.
Postcondition
Success initializes both paths and cache->index.
Success reports corrupt-index recovery through rebuilt.
Note
A non-regular index fails closed and is never removed.
Since
0.1.0

Definition at line 532 of file mdl_cache_io.c.

References fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_stat(), mdl_cache_paths_t::host_hash, mdl_cache_t::index, mdl_cache_paths_t::index_path, internal_cache_decode(), internal_cache_discard_index(), internal_cache_paths(), k_fw_fs_node_file, k_mdl_cache_schema_version, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, fw_fs_t::names, RA8_PRIV, fw_fs_stat_t::size_bytes, mdl_cache_t::storage, and fw_fs_stat_t::type.

Referenced by internal_cache_prepare().

◆ priv_mdl_cache_publish_body()

ra8_err_t priv_mdl_cache_publish_body ( mdl_storage_t * storage,
const mdl_cache_paths_t * paths,
uint64_t url_hash,
uint64_t content_hash,
const char * buffer,
size_t length,
char * relative_path,
size_t relative_capacity )

Publish one new body under its immutable content-derived leaf.

Derives the leaf from both URL and content identities, streams the exact bytes into a transaction, and commits only on full success.

Parameters
[in,out]storageExclusive storage binding.
[in]pathsMatching host directory.
[in]url_hashStable URL identity.
[in]content_hashExact body identity.
[in]bufferComplete body bytes.
[in]lengthBody extent.
[out]relative_pathPublished relative leaf.
[in]relative_capacityWritable leaf capacity.
Returns
Canonical transaction status.
Return values
k_ra8_okThe immutable body is completely published.
k_ra8_err_invalid_argA pointer or length contract is invalid.
k_ra8_err_invalid_sizeThe leaf or full path exceeded its bound.
otherTransaction begin, write, commit, or abort failed.
Precondition
Body is nonempty and pointers/capacities are valid.
Storage and transaction workspace are exclusively owned.
Postcondition
Success publishes exactly length bytes atomically.
Success returns the exact relative leaf in relative_path.
Note
Orphaned immutable bodies are harmless after an index-save failure.
Since
0.1.0

Definition at line 832 of file mdl_cache_io.c.

References mdl_cache_paths_t::directory, internal_cache_body_leaf(), k_fw_fs_path_cap, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_ok, mdl_path_join(), mdl_storage_txn_abort(), mdl_storage_txn_begin(), mdl_storage_txn_commit(), mdl_storage_txn_write(), and RA8_PRIV.

Referenced by internal_cache_publish().

◆ priv_mdl_cache_read_body()

ra8_err_t priv_mdl_cache_read_body ( mdl_storage_t * storage,
const mdl_cache_paths_t * paths,
const mdl_cache_record_t * record,
char * buffer,
size_t capacity,
size_t * out_length )

Read and hash-check one retained body into caller storage.

Requires a regular exact-sized file, reads it completely with bounded progress, checks EOF, then authenticates the content hash.

Parameters
[in,out]storageExclusive storage binding.
[in]pathsMatching host directory.
[in]recordPersistent body identity.
[out]bufferDestination storage.
[in]capacityDestination capacity.
[out]out_lengthExact body extent.
Returns
Canonical file, size, or identity status.
Return values
k_ra8_okExact authenticated bytes are available.
k_ra8_err_not_foundThe retained body is absent.
k_ra8_err_validation_failedThe body hash differs.
otherSize, open, read, or close failed.
Precondition
Every pointer is non-NULL.
buffer spans capacity nonzero writable bytes.
Postcondition
Success publishes only an exact hash-matching body.
Failure leaves out_length equal to zero.
Note
A mismatched body is treated as validation failure.
Since
0.1.0

Definition at line 797 of file mdl_cache_io.c.

References mdl_cache_record_t::content_hash, mdl_cache_paths_t::directory, fw_fs_stat_t::exists, mdl_storage_t::fs, fw_fs_stat(), internal_cache_read_body_exact(), k_fw_fs_node_file, k_fw_fs_path_cap, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_not_found, k_ra8_err_validation_failed, k_ra8_ok, mdl_hash_bytes(), mdl_path_join(), fw_fs_t::names, RA8_PRIV, mdl_cache_record_t::relative_path, fw_fs_stat_t::size_bytes, and fw_fs_stat_t::type.

Referenced by internal_cache_finish_304(), and internal_cache_prepare().

◆ priv_mdl_cache_save()

ra8_err_t priv_mdl_cache_save ( mdl_cache_t * cache,
const mdl_cache_paths_t * paths )

Transactionally publish the current host index.

Encodes a checksummed generation directly into a portable storage transaction and commits only after every record is written.

Parameters
[in,out]cacheCache binding containing the index.
[in]pathsMatching host paths from priv_mdl_cache_load.
Returns
Canonical serialization or publication status.
Return values
k_ra8_okThe complete index generation was published.
k_ra8_err_invalid_argThe index and host paths do not match.
otherValidation, transaction writing, commit, or abort failed.
Precondition
Index invariants and host identity are valid.
Cache storage and transaction workspace are exclusively owned.
Postcondition
Success publishes one complete checksummed generation.
Failure never exposes a partial index generation.
Note
Existing indexes require truthful atomic-replace support.
Since
0.1.0

Definition at line 699 of file mdl_cache_io.c.

References mdl_cache_index_t::host_hash, mdl_cache_paths_t::host_hash, mdl_cache_t::index, mdl_cache_paths_t::index_path, internal_cache_payload_identity(), internal_cache_put_u16(), internal_cache_put_u64(), internal_cache_record_valid(), internal_cache_write_records(), k_cache_header_bytes, k_cache_header_count, k_cache_header_host, k_cache_trailer_bytes, k_mdl_cache_record_max, k_mdl_cache_schema_version, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, mdl_storage_txn_abort(), mdl_storage_txn_begin(), mdl_storage_txn_commit(), mdl_storage_txn_write(), memcpy(), RA8_PRIV, mdl_cache_index_t::record_count, mdl_cache_index_t::records, s_cache_magic, mdl_cache_index_t::schema_version, and mdl_cache_t::storage.

Referenced by internal_cache_finish_304(), and internal_cache_publish().

Variable Documentation

◆ s_cache_magic

const uint8_t s_cache_magic[k_cache_trailer_bytes]
static
Initial value:
=
{'M', 'D', 'L', 'C', 'A', 'C', 'H', '1'}

Canonical cache index magic.

Definition at line 40 of file mdl_cache_io.c.

Referenced by internal_cache_decode(), and priv_mdl_cache_save().