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

Import-time pagination cache serialiser / loader for reflow. More...

#include "reflow_cache.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_err.h"
#include "reflow.h"
Include dependency graph for reflow_cache.c:

Go to the source code of this file.

Data Structures

struct  priv_cache_key_t
 Parsed header / invalidation key of a cache blob. More...

Enumerations

enum  priv_cache_const_t : uint32_t {
  k_priv_fnv_offset = 0x811C9DC5U ,
  k_priv_fnv_prime = 0x01000193U ,
  k_priv_byte_mask = 0xFFU ,
  k_priv_shift_8 = 8U ,
  k_priv_shift_16 = 16U ,
  k_priv_shift_24 = 24U
}
 FNV-1a parameters and byte-extraction shifts / mask. More...
enum  priv_cache_off_t : size_t { k_priv_checksum_off = 48U }
 Fixed byte offsets within the serialised header. More...

Functions

static void internal_put_u32 (uint8_t *buf, size_t *off, uint32_t word)
 Append a little-endian uint32_t and advance the cursor.
static void internal_put_u16 (uint8_t *buf, size_t *off, uint16_t half)
 Append a little-endian uint16_t and advance the cursor.
static uint32_t internal_get_u32 (const uint8_t *buf, size_t *off)
 Read a little-endian uint32_t and advance the cursor.
static uint16_t internal_get_u16 (const uint8_t *buf, size_t *off)
 Read a little-endian uint16_t and advance the cursor.
static uint32_t internal_fnv1a (const uint8_t *data, size_t len)
 32-bit FNV-1a hash over a byte range.
static void internal_put_glyph (uint8_t *buf, size_t *off, const reflow_glyph_t *glyph)
 Serialise one glyph (20 bytes) and advance the cursor.
static void internal_get_glyph (const uint8_t *buf, size_t *off, reflow_glyph_t *glyph)
 Deserialise one glyph (20 bytes) and advance the cursor.
static void internal_put_page (uint8_t *buf, size_t *off, const reflow_page_t *page)
 Serialise one page record (8 bytes) and advance the cursor.
static void internal_get_page (const uint8_t *buf, size_t *off, reflow_page_t *page)
 Deserialise one page record (8 bytes) and advance the cursor.
static uint32_t internal_font_hash (const reflow_t *engine)
 Hash the engine's font blob (0 when no font is bound).
static void internal_put_header (uint8_t *buf, const reflow_t *engine, size_t content_len, uint32_t content_hash)
 Write the fixed-size header (checksum left as a zero placeholder).
static void internal_get_header (const uint8_t *buf, priv_cache_key_t *key)
 Parse the fixed-size header into a key struct.
static size_t internal_blob_size (uint32_t glyph_count, uint32_t page_count)
 Total serialised size for the given record counts.
static bool internal_key_matches (const reflow_t *engine, const priv_cache_key_t *key, const uint8_t *content, size_t content_len)
 True when the blob's key matches the engine + supplied content.
static ra8_err_t internal_parse_header (const uint8_t *buf, size_t len, priv_cache_key_t *key, size_t *need)
 Validate a blob's header structure and report its total size.
ra8_err_t reflow_cache_size (const reflow_t *engine, size_t *out_bytes)
 Report the exact serialised size of an engine's current layout.
static ra8_err_t internal_cache_precheck (const reflow_t *engine, const uint8_t *content, size_t content_len)
 Shared serialize/load precheck: init state, content args, and the #109 multi-face cache-bypass invariant.
ra8_err_t reflow_cache_serialize (const reflow_t *engine, const uint8_t *content, size_t content_len, uint8_t *out_buf, size_t out_cap, size_t *out_len)
 Serialise the laid-out pages of engine into a keyed byte blob.
ra8_err_t reflow_cache_load (reflow_t *engine, const uint8_t *content, size_t content_len, const uint8_t *buf, size_t len)
 Validate a cache blob and, if it matches, restore the layout.

Detailed Description

Import-time pagination cache serialiser / loader for reflow.

Implements reflow_cache.h: turn a laid-out engine's glyphs[] + pages[] into a keyed little-endian byte blob and back, so the expensive reflow_layout_chapter() pass can be skipped when the viewport / font / colours / font blob / chapter bytes are unchanged.

The serialisation is explicit per field (no memcpy of whole structs), which keeps the format compiler-independent and – crucially – keeps the body checksum deterministic because struct padding bytes are never hashed. Every loop is bounded by a count that the loader first checks against the engine's static pools (k_reflow_max_glyphs / k_reflow_max_pages) and the blob length, so a malformed blob can never overrun (NASA P10 Rules 2 and 7).

[Ring 4 / Reflow] {World: NS}

Since
0.1.0

Definition in file reflow_cache.c.

Enumeration Type Documentation

◆ priv_cache_const_t

enum priv_cache_const_t : uint32_t

FNV-1a parameters and byte-extraction shifts / mask.

Enumerator
k_priv_fnv_offset 

FNV-1a 32-bit offset basis.

k_priv_fnv_prime 

FNV-1a 32-bit prime.

k_priv_byte_mask 

Low-byte mask.

k_priv_shift_8 

Shift to byte 1.

k_priv_shift_16 

Shift to byte 2.

k_priv_shift_24 

Shift to byte 3.

Definition at line 46 of file reflow_cache.c.

◆ priv_cache_off_t

enum priv_cache_off_t : size_t

Fixed byte offsets within the serialised header.

Enumerator
k_priv_checksum_off 

Body-checksum field offset.

Definition at line 59 of file reflow_cache.c.

Function Documentation

◆ internal_blob_size()

size_t internal_blob_size ( uint32_t glyph_count,
uint32_t page_count )
static

Total serialised size for the given record counts.

header + glyph_count * glyph_bytes + page_count * page_bytes. Shared by the size query, the serialiser and the loader so all three agree on the layout.

Parameters
[in]glyph_countNumber of glyph records.
[in]page_countNumber of page records.
Returns
The total blob size in bytes.
Return values
value>= k_reflow_cache_header_bytes.
Precondition
glyph_count and page_count are within the engine pools.
The product does not overflow size_t (counts are pool-bounded).
Postcondition
The result includes the fixed header.
Zero counts return exactly the header size.
Note
Pure function of its arguments.
Since
0.1.0

Definition at line 489 of file reflow_cache.c.

References k_reflow_cache_glyph_bytes, k_reflow_cache_header_bytes, and k_reflow_cache_page_bytes.

Referenced by internal_parse_header(), reflow_cache_serialize(), and reflow_cache_size().

◆ internal_cache_precheck()

ra8_err_t internal_cache_precheck ( const reflow_t * engine,
const uint8_t * content,
size_t content_len )
static

Shared serialize/load precheck: init state, content args, and the #109 multi-face cache-bypass invariant.

Per-glyph embedded face indices (#109) are not part of the cache key/format, so a book with any registered @font-face is never cached: it live-layouts instead, and a persisted page can never be mis-served under a different face set. The caller checks its own NULL pointers first.

Parameters
[in]engineEngine (already NULL-checked by the caller).
[in]contentChapter bytes, or NULL iff content_len is 0.
[in]content_lenLength of content, bytes.
Returns
ra8_err_t Status code.
Return values
k_ra8_okEngine is initialised, content args are valid, and no @font-face faces are registered.
k_ra8_err_not_initializedEngine in_use flag is clear.
k_ra8_err_invalid_argcontent is NULL but content_len is non-zero.
k_ra8_err_invalid_stateAt least one @font-face face is registered; the cache must be bypassed for this chapter.
Precondition
engine is non-NULL (the caller validates this before calling).
If content is non-NULL, content[0 .. content_len) is readable.
Postcondition
No engine state or caller memory is modified.
The return code unambiguously names the first failing precondition.
Note
Not thread-safe; relies on the caller's synchronisation context.
Since
0.1.0

Definition at line 665 of file reflow_cache.c.

References reflow_t::face_count, reflow_t::in_use, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_not_initialized, and k_ra8_ok.

Referenced by reflow_cache_load(), and reflow_cache_serialize().

◆ internal_fnv1a()

uint32_t internal_fnv1a ( const uint8_t * data,
size_t len )
static

32-bit FNV-1a hash over a byte range.

Standard FNV-1a: seed with the offset basis, then for each byte XOR-in and multiply by the FNV prime. Used for both the font and content key hashes and the body checksum.

Parameters
[in]dataBytes to hash (may be NULL only when len == 0).
[in]lenNumber of bytes.
Returns
The FNV-1a digest.
Return values
valueThe 32-bit hash of data[0 .. len).
Precondition
data is non-NULL or len == 0.
data[0 .. len) is readable.
Postcondition
No input is modified.
len == 0 yields the FNV offset basis.
Note
Not a cryptographic hash; collision-resistance is not required.
Since
0.1.0

Definition at line 233 of file reflow_cache.c.

References k_priv_fnv_offset, and k_priv_fnv_prime.

Referenced by internal_font_hash(), reflow_cache_load(), and reflow_cache_serialize().

◆ internal_font_hash()

uint32_t internal_font_hash ( const reflow_t * engine)
static

Hash the engine's font blob (0 when no font is bound).

Computes the FNV-1a digest over engine->font_data so a different font face / subset invalidates a cached layout.

Parameters
[in]engineEngine whose font blob is hashed.
Returns
The font-blob hash, or 0 when no font is bound.
Return values
0engine->font_data is NULL.
valueFNV-1a of font_data[0 .. font_len).
Precondition
engine is non-NULL.
When bound, font_data[0 .. font_len) is readable.
Postcondition
No state is modified.
Equal blobs hash equal.
Note
Shared by serialise and key-compare so both see the same value.
Since
0.1.0

Definition at line 379 of file reflow_cache.c.

References reflow_t::font_data, reflow_t::font_len, and internal_fnv1a().

Referenced by internal_key_matches(), and internal_put_header().

◆ internal_get_glyph()

void internal_get_glyph ( const uint8_t * buf,
size_t * off,
reflow_glyph_t * glyph )
static

Deserialise one glyph (20 bytes) and advance the cursor.

Reads the seven serialised fields, including the reserved link id, so the restored struct is byte-identical to the original (no field is silently zeroed).

Parameters
[in]bufSource buffer (>= 20 bytes readable at *off).
[in,out]offRead cursor (advanced by 20).
[out]glyphReceives the decoded glyph.
Precondition
buf, off and glyph are non-NULL.
*off + 20 does not exceed the buffer length.
Postcondition
*off has advanced by 20.
glyph->reserved equals the serialised link id.
Note
Mirror of internal_put_glyph().
Since
0.1.0

Definition at line 295 of file reflow_cache.c.

References reflow_glyph_t::color, reflow_glyph_t::cp, reflow_glyph_t::font_px, internal_get_u16(), internal_get_u32(), reflow_glyph_t::reserved, reflow_glyph_t::style, reflow_glyph_t::x, and reflow_glyph_t::y.

Referenced by reflow_cache_load().

◆ internal_get_header()

void internal_get_header ( const uint8_t * buf,
priv_cache_key_t * key )
static

Parse the fixed-size header into a key struct.

Decodes every header field in the same order internal_put_header() wrote them, skipping the two reserved half-words.

Parameters
[in]bufSource buffer (>= header bytes readable).
[out]keyReceives the parsed header fields.
Precondition
buf and key are non-NULL.
buf has at least k_reflow_cache_header_bytes readable.
Postcondition
*key is fully populated from the header.
buf is not modified.
Note
Pairs with internal_put_header().
Since
0.1.0

Definition at line 447 of file reflow_cache.c.

References priv_cache_key_t::body_checksum, priv_cache_key_t::body_color, priv_cache_key_t::content_hash, priv_cache_key_t::content_len, priv_cache_key_t::font_hash, priv_cache_key_t::font_len, priv_cache_key_t::font_px, priv_cache_key_t::glyph_count, internal_get_u16(), internal_get_u32(), priv_cache_key_t::link_color, priv_cache_key_t::magic, priv_cache_key_t::page_count, priv_cache_key_t::version, priv_cache_key_t::viewport_h, and priv_cache_key_t::viewport_w.

Referenced by internal_parse_header().

◆ internal_get_page()

void internal_get_page ( const uint8_t * buf,
size_t * off,
reflow_page_t * page )
static

Deserialise one page record (8 bytes) and advance the cursor.

Reads the two uint32_t glyph-range fields little-endian.

Parameters
[in]bufSource buffer (>= 8 bytes readable at *off).
[in,out]offRead cursor (advanced by 8).
[out]pageReceives the decoded page record.
Precondition
buf, off and page are non-NULL.
*off + 8 does not exceed the buffer length.
Postcondition
*off has advanced by 8.
Both page-range fields are populated.
Note
Mirror of internal_put_page().
Since
0.1.0

Definition at line 348 of file reflow_cache.c.

References reflow_page_t::glyph_count, reflow_page_t::glyph_first, and internal_get_u32().

Referenced by reflow_cache_load().

◆ internal_get_u16()

uint16_t internal_get_u16 ( const uint8_t * buf,
size_t * off )
static

Read a little-endian uint16_t and advance the cursor.

Reads two bytes least-significant-first from *off and advances *off by 2.

Parameters
[in]bufSource buffer (>= 2 bytes readable at *off).
[in,out]offRead cursor (advanced by 2).
Returns
The decoded 16-bit value.
Return values
valueThe little-endian half-word assembled from two bytes.
Precondition
buf and off are non-NULL.
*off + 2 does not exceed the buffer length.
Postcondition
*off has advanced by 2.
The buffer is not modified.
Note
Internal byte cursor; no bounds check (caller pre-validates).
Since
0.1.0

Definition at line 198 of file reflow_cache.c.

References k_priv_shift_8.

Referenced by internal_get_glyph(), and internal_get_header().

◆ internal_get_u32()

uint32_t internal_get_u32 ( const uint8_t * buf,
size_t * off )
static

Read a little-endian uint32_t and advance the cursor.

Reads four bytes least-significant-first from *off and advances *off by 4.

Parameters
[in]bufSource buffer (>= 4 bytes readable at *off).
[in,out]offRead cursor (advanced by 4).
Returns
The decoded 32-bit value.
Return values
valueThe little-endian word assembled from four bytes.
Precondition
buf and off are non-NULL.
*off + 4 does not exceed the buffer length.
Postcondition
*off has advanced by 4.
The buffer is not modified.
Note
Internal byte cursor; no bounds check (caller pre-validates).
Since
0.1.0

Definition at line 165 of file reflow_cache.c.

References k_priv_shift_16, k_priv_shift_24, and k_priv_shift_8.

Referenced by internal_get_glyph(), internal_get_header(), and internal_get_page().

◆ internal_key_matches()

bool internal_key_matches ( const reflow_t * engine,
const priv_cache_key_t * key,
const uint8_t * content,
size_t content_len )
static

True when the blob's key matches the engine + supplied content.

Compares every keyed attribute – viewport, font size, body / link colours, font length + hash, and content length + hash – so any change that would alter the layout is detected.

Parameters
[in]engineEngine holding the current viewport / font / colours.
[in]keyParsed blob header.
[in]contentChapter bytes to hash and compare.
[in]content_lenLength of content, bytes.
Returns
Whether the blob is valid for this engine + content.
Return values
trueEvery keyed attribute matches.
falseAt least one attribute differs (layout is stale).
Precondition
engine and key are non-NULL.
content is non-NULL or content_len == 0.
Postcondition
No state is modified.
A true result means the cached glyphs are safe to restore.
Note
Recomputes the font and content hashes on each call.
Since
0.1.0

Definition at line 520 of file reflow_cache.c.

References priv_cache_key_t::body_color, reflow_t::body_color, priv_cache_key_t::content_hash, priv_cache_key_t::content_len, priv_cache_key_t::font_hash, priv_cache_key_t::font_len, reflow_t::font_len, priv_cache_key_t::font_px, reflow_t::font_px, internal_fnv1a(), internal_font_hash(), priv_cache_key_t::link_color, reflow_t::link_color, priv_cache_key_t::viewport_h, reflow_t::viewport_h, priv_cache_key_t::viewport_w, and reflow_t::viewport_w.

Referenced by reflow_cache_load().

◆ internal_parse_header()

ra8_err_t internal_parse_header ( const uint8_t * buf,
size_t len,
priv_cache_key_t * key,
size_t * need )
static

Validate a blob's header structure and report its total size.

Checks, in order, that len covers the fixed header, that the magic and format version match, and that the record counts do not exceed the engine's static pools (k_reflow_max_glyphs / k_reflow_max_pages), then computes the expected total blob size and confirms len covers it. Pure structural validation – the invalidation key and the body checksum are verified by the caller.

Parameters
[in]bufSerialised blob (at least len readable bytes).
[in]lenLength of buf, bytes.
[out]keyReceives the parsed header fields.
[out]needReceives the expected total blob size, bytes.
Returns
ra8_err_t
Return values
k_ra8_okHeader valid; *need set.
k_ra8_err_not_foundMagic mismatch (not a cache blob).
k_ra8_err_invalid_stateFormat version mismatch.
k_ra8_err_invalid_sizeShort header, record counts beyond the engine pools, or len below the size.
Precondition
buf, key and need are non-NULL.
len is the readable length of buf.
Postcondition
On k_ra8_ok, *key is fully populated and *need <= len.
On any failure the return code names the first failed check.
Note
Internal helper for reflow_cache_load(); depends only on its inputs (no shared state).
Since
0.1.0

Definition at line 592 of file reflow_cache.c.

References priv_cache_key_t::glyph_count, internal_blob_size(), internal_get_header(), k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_not_found, k_ra8_ok, k_reflow_cache_header_bytes, k_reflow_cache_magic, k_reflow_cache_version, k_reflow_max_glyphs, k_reflow_max_pages, priv_cache_key_t::magic, priv_cache_key_t::page_count, and priv_cache_key_t::version.

Referenced by reflow_cache_load().

◆ internal_put_glyph()

void internal_put_glyph ( uint8_t * buf,
size_t * off,
const reflow_glyph_t * glyph )
static

Serialise one glyph (20 bytes) and advance the cursor.

Writes the seven meaningful fields (x, y, cp, colour, font_px, style, reserved). reserved holds the 1-based <a> link id (0 = not a link), which is layout state the renderer needs for hyperlink hit-testing – it is not padding, so it is stored.

Parameters
[out]bufDestination buffer (>= 20 bytes free at *off).
[in,out]offWrite cursor (advanced by 20).
[in]glyphGlyph to serialise.
Precondition
buf, off and glyph are non-NULL.
*off + 20 does not exceed the buffer capacity.
Postcondition
*off has advanced by 20.
The glyph's seven fields are encoded little-endian.
Note
Mirror of internal_get_glyph().
Since
0.1.0

Definition at line 263 of file reflow_cache.c.

References reflow_glyph_t::color, reflow_glyph_t::cp, reflow_glyph_t::font_px, internal_put_u16(), internal_put_u32(), reflow_glyph_t::reserved, reflow_glyph_t::style, reflow_glyph_t::x, and reflow_glyph_t::y.

Referenced by reflow_cache_serialize().

◆ internal_put_header()

void internal_put_header ( uint8_t * buf,
const reflow_t * engine,
size_t content_len,
uint32_t content_hash )
static

Write the fixed-size header (checksum left as a zero placeholder).

Encodes the magic, version, the invalidation key (viewport / font / colours / font hash / content hash) and the record counts. The body-checksum field is written as zero and back-patched by the caller once the payload exists.

Parameters
[out]bufDestination buffer (>= header bytes).
[in]engineEngine providing viewport / font / colours.
[in]content_lenChapter byte length for the key.
[in]content_hashFNV-1a of the chapter bytes for the key.
Precondition
buf and engine are non-NULL.
buf has at least k_reflow_cache_header_bytes capacity.
Postcondition
Header bytes [0, k_reflow_cache_header_bytes) are written.
The body-checksum field holds a zero placeholder.
Note
Pairs with internal_get_header().
Since
0.1.0

Definition at line 409 of file reflow_cache.c.

References reflow_t::body_color, reflow_t::font_len, reflow_t::font_px, reflow_t::glyph_count, internal_font_hash(), internal_put_u16(), internal_put_u32(), k_reflow_cache_magic, k_reflow_cache_version, reflow_t::link_color, reflow_t::page_count, reflow_t::viewport_h, and reflow_t::viewport_w.

Referenced by reflow_cache_serialize().

◆ internal_put_page()

void internal_put_page ( uint8_t * buf,
size_t * off,
const reflow_page_t * page )
static

Serialise one page record (8 bytes) and advance the cursor.

Writes the two uint32_t glyph-range fields little-endian.

Parameters
[out]bufDestination buffer (>= 8 bytes free at *off).
[in,out]offWrite cursor (advanced by 8).
[in]pagePage record to serialise.
Precondition
buf, off and page are non-NULL.
*off + 8 does not exceed the buffer capacity.
Postcondition
*off has advanced by 8.
Both page-range fields are encoded little-endian.
Note
Mirror of internal_get_page().
Since
0.1.0

Definition at line 325 of file reflow_cache.c.

References reflow_page_t::glyph_count, reflow_page_t::glyph_first, and internal_put_u32().

Referenced by reflow_cache_serialize().

◆ internal_put_u16()

void internal_put_u16 ( uint8_t * buf,
size_t * off,
uint16_t half )
static

Append a little-endian uint16_t and advance the cursor.

Writes the two bytes least-significant-first at *off and advances *off by 2.

Parameters
[out]bufDestination buffer (>= 2 bytes free at *off).
[in,out]offWrite cursor (advanced by 2).
[in]halfValue to store.
Precondition
buf and off are non-NULL.
*off + 2 does not exceed the buffer capacity.
Postcondition
*off has advanced by 2.
Two little-endian bytes of half are written.
Note
Internal byte cursor; no bounds check (caller pre-sizes).
Since
0.1.0

Definition at line 137 of file reflow_cache.c.

References k_priv_byte_mask, and k_priv_shift_8.

Referenced by internal_put_glyph(), and internal_put_header().

◆ internal_put_u32()

void internal_put_u32 ( uint8_t * buf,
size_t * off,
uint32_t word )
static

Append a little-endian uint32_t and advance the cursor.

Writes the four bytes least-significant-first at *off and advances *off by 4.

Parameters
[out]bufDestination buffer (>= 4 bytes free at *off).
[in,out]offWrite cursor (advanced by 4).
[in]wordValue to store.
Precondition
buf and off are non-NULL.
*off + 4 does not exceed the buffer capacity.
Postcondition
*off has advanced by 4.
Four little-endian bytes of word are written.
Note
Internal byte cursor; no bounds check (caller pre-sizes).
Since
0.1.0

Definition at line 107 of file reflow_cache.c.

References k_priv_byte_mask, k_priv_shift_16, k_priv_shift_24, and k_priv_shift_8.

Referenced by internal_put_glyph(), internal_put_header(), internal_put_page(), and reflow_cache_serialize().

◆ reflow_cache_load()

ra8_err_t reflow_cache_load ( reflow_t * engine,
const uint8_t * content,
size_t content_len,
const uint8_t * buf,
size_t len )
nodiscard

Validate a cache blob and, if it matches, restore the layout.

Parses the blob header, then validates – in order – the magic, the format version, the record counts (against the engine's static pools and the blob length), the invalidation key (viewport / font / colours / font hash / content hash) and the body checksum. Only when all pass are the glyphs[] and pages[] arrays copied back into engine and engine->xhtml_buf / xhtml_len repointed at content (so a later reflow_set_font_size() can still re-flow). On any mismatch the engine is left untouched and the caller should re-lay-out.

Parameters
[in,out]engineEngine initialised with the same viewport / font / colours the blob was made with (the load validates this).
[in]contentChapter bytes (hashed and compared to the blob's content hash). May be NULL only when content_len == 0.
[in]content_lenLength of content, bytes.
[in]bufSerialised blob.
[in]lenLength of buf, bytes.
Returns
ra8_err_t
Return values
k_ra8_okLoaded; glyphs / pages restored.
k_ra8_err_null_ptrengine or buf is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
k_ra8_err_invalid_argcontent NULL with content_len>0.
k_ra8_err_not_foundMagic mismatch (not a cache blob).
k_ra8_err_invalid_stateVersion or key mismatch – the layout is stale; re-lay-out and re-serialise.
k_ra8_err_invalid_sizeTruncated blob or counts exceed pools.
k_ra8_err_checksum_mismatchBody checksum failed (corrupt blob).
Precondition
engine->in_use == 1.
Postcondition
On k_ra8_ok, engine->glyph_count / page_count and the restored arrays match the serialised layout and rendering may proceed without reflow_layout_chapter().
On any non-k_ra8_ok return the engine is unchanged.
See also
reflow_cache_serialize()
Since
0.1.0

Definition at line 716 of file reflow_cache.c.

References priv_cache_key_t::body_checksum, priv_cache_key_t::glyph_count, reflow_t::glyph_count, reflow_t::glyphs, internal_cache_precheck(), internal_fnv1a(), internal_get_glyph(), internal_get_page(), internal_key_matches(), internal_parse_header(), k_ra8_err_checksum_mismatch, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, k_reflow_cache_header_bytes, priv_cache_key_t::page_count, reflow_t::page_count, reflow_t::pages, reflow_t::xhtml_buf, and reflow_t::xhtml_len.

Referenced by internal_pc_invalidate_check_or_halt(), and internal_pc_reload_check_or_halt().

◆ reflow_cache_serialize()

ra8_err_t reflow_cache_serialize ( const reflow_t * engine,
const uint8_t * content,
size_t content_len,
uint8_t * out_buf,
size_t out_cap,
size_t * out_len )
nodiscard

Serialise the laid-out pages of engine into a keyed byte blob.

Writes the header (magic, version, the invalidation key, glyph / page counts and a body checksum) followed by the flat glyphs[] array and the pages[] index ranges, each field little-endian. The key captures the engine's viewport, font size, colours, the font blob (length + FNV-1a hash) and the supplied content (length + FNV-1a hash) so a later reflow_cache_load() can detect any change that would invalidate the layout.

Parameters
[in]engineLaid-out engine handle.
[in]contentChapter bytes the layout was produced from (hashed into the key). May be NULL only when content_len == 0.
[in]content_lenLength of content, bytes.
[out]out_bufDestination buffer.
[in]out_capCapacity of out_buf, bytes.
[out]out_lenReceives the number of bytes written.
Returns
ra8_err_t
Return values
k_ra8_okSerialised; *out_len bytes written.
k_ra8_err_null_ptrengine, out_buf or out_len NULL.
k_ra8_err_not_initializedengine->in_use == 0.
k_ra8_err_invalid_argcontent NULL with content_len > 0.
k_ra8_err_invalid_sizeout_cap smaller than the blob size.
Precondition
engine->in_use == 1; a chapter has been laid out.
Postcondition
On success the first *out_len bytes of out_buf are a valid blob accepted by reflow_cache_load().
See also
reflow_cache_size()
reflow_cache_load()
Since
0.1.0

Definition at line 679 of file reflow_cache.c.

References reflow_t::glyph_count, reflow_t::glyphs, internal_blob_size(), internal_cache_precheck(), internal_fnv1a(), internal_put_glyph(), internal_put_header(), internal_put_page(), internal_put_u32(), k_priv_checksum_off, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, k_reflow_cache_header_bytes, reflow_t::page_count, and reflow_t::pages.

Referenced by internal_pc_live_layout_or_halt(), and internal_pc_reload_check_or_halt().

◆ reflow_cache_size()

ra8_err_t reflow_cache_size ( const reflow_t * engine,
size_t * out_bytes )
nodiscard

Report the exact serialised size of an engine's current layout.

Lets the caller size (or bounds-check) the destination buffer before calling reflow_cache_serialize(). The value is k_reflow_cache_header_bytes + engine->glyph_count * k_reflow_cache_glyph_bytes + engine->page_count * k_reflow_cache_page_bytes.

Parameters
[in]engineInitialised engine (a chapter need not be laid out yet; an empty layout serialises to just the header).
[out]out_bytesReceives the required buffer size in bytes.
Returns
ra8_err_t
Return values
k_ra8_okSize reported.
k_ra8_err_null_ptrengine or out_bytes is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
Precondition
engine non-NULL and engine->in_use == 1.
Postcondition
*out_bytes >= k_reflow_cache_header_bytes.
Since
0.1.0

Definition at line 622 of file reflow_cache.c.

References reflow_t::glyph_count, reflow_t::in_use, internal_blob_size(), k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, and reflow_t::page_count.