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

In-memory model and coverage queries for persistent series state. More...

#include "mdl_state.h"
#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "mdl_state_internal.h"
#include "ra8_attributes.h"
Include dependency graph for mdl_state.c:

Go to the source code of this file.

Enumerations

enum  mdl_state_coverage_t : uint16_t {
  k_state_gap_cap = 12 ,
  k_state_http_status_min = 100 ,
  k_state_http_status_max = 599
}
 Maximum missing chapter numbers rendered in one coverage summary. More...

Functions

static bool internal_mdl_state_page_response_valid (int64_t fetched_at, uint16_t response_status)
 Whether persisted HTTP observation metadata is canonical.
void mdl_state_init (mdl_state_t *st)
 Reset a state object to an empty, current-version library.
void priv_mdl_state_set_opt (char *dst, size_t cap, const char *val)
 Copy val into a bounded field when val is non-NULL.
bool priv_mdl_state_field_valid (const char *text, size_t cap)
 True when a record field fits and cannot inject a line or column.
bool priv_mdl_state_relative_path_valid (const char *path, size_t cap)
 Validate a bounded relative path.
static bool internal_mdl_state_chapter_number_valid (double number, bool known)
 Validate an explicit chapter-number tuple.
bool priv_mdl_state_valid (const mdl_state_t *st)
 Validate every bound and cross-field invariant before persistence.
bool mdl_state_set_series_metadata (mdl_state_t *st, const char *summary, const char *writer, const char *artist, const char *cover_url, const char *cover_path, const char *language, mdl_state_reading_direction_t direction)
 Set the optional rich metadata persisted for a series.
void mdl_state_set_series (mdl_state_t *st, const char *url, const char *title, const char *site_name, const char *site_host, const char *config_path)
 Record the series identity and the descriptor used.
mdl_chapter_rec_tmdl_state_find_chapter (mdl_state_t *st, const char *id)
 Find a chapter record by its stable identifier.
mdl_chapter_rec_tmdl_state_add_chapter (mdl_state_t *st, const char *id, const char *url, long number)
 Find or append a chapter record, returning it.
mdl_chapter_rec_tmdl_state_add_chapter_numbered (mdl_state_t *st, const char *id, const char *url, double number, bool number_known)
 Find or append a chapter with explicit parsed-number presence.
bool mdl_state_set_chapter_metadata (mdl_chapter_rec_t *chapter, const char *title, double number, bool number_known)
 Set a chapter's display title and explicit parsed number.
bool mdl_state_chapter_complete (const mdl_state_t *st, const char *id)
 Whether a chapter is recorded fully fetched and verified.
uint16_t mdl_state_chapter_pages (const mdl_state_t *st, const char *id)
 Recorded page count for a chapter (0 when unknown).
const mdl_page_rec_tmdl_state_find_page (const mdl_state_t *st, uint64_t url_hash)
 Find a page record by its source-URL hash (the dedup lookup).
bool mdl_state_add_page (mdl_state_t *st, uint64_t url_hash, uint64_t content_hash, const char *rel_path, const char *etag, const char *last_modified, int64_t fetched_at, uint16_t response_status)
 Add or replace a URL-keyed page cache record.
bool mdl_state_note_page_response (mdl_state_t *st, uint64_t url_hash, int64_t fetched_at, uint16_t response_status)
 Refresh the observed HTTP result for one existing URL cache entry.
static bool internal_mdl_state_chapter_number_as_long (const mdl_chapter_rec_t *chapter, long *out)
 Convert an exactly integral chapter number to long.
static bool internal_mdl_state_complete_span (const mdl_state_t *st, long *lo, long *hi, size_t *n)
 Number span [lo,hi] of complete integral chapters.
static bool internal_mdl_state_has_complete_number (const mdl_state_t *st, long num)
 True when a complete chapter with parsed number num exists.
static void internal_mdl_state_append_gaps (const mdl_state_t *st, long lo, long hi, char *buf, size_t cap)
 Append the missing-chapter list within [lo,hi] to buf (bounded).
void mdl_state_coverage (const mdl_state_t *st, char *buf, size_t cap)
 Render a one-line coverage summary (chapter span, count, gaps).

Detailed Description

In-memory model and coverage queries for persistent series state.

Maintains bounded chapter and page records, metadata, completion, and coverage calculations independently of storage encoding.

Definition in file mdl_state.c.

Enumeration Type Documentation

◆ mdl_state_coverage_t

enum mdl_state_coverage_t : uint16_t

Maximum missing chapter numbers rendered in one coverage summary.

Enumerator
k_state_gap_cap 

Max missing chapters listed.

k_state_http_status_min 

Smallest valid HTTP status.

k_state_http_status_max 

Largest valid HTTP status.

Definition at line 21 of file mdl_state.c.

Function Documentation

◆ internal_mdl_state_append_gaps()

void internal_mdl_state_append_gaps ( const mdl_state_t * st,
long lo,
long hi,
char * buf,
size_t cap )
static

Append the missing-chapter list within [lo,hi] to buf (bounded).

Walks the inclusive integral range, appending absent chapter numbers as a comma-separated list while preserving NUL termination at cap.

Parameters
[in]stValidated bounded state used for membership checks.
[in]loInclusive lower chapter number.
[in]hiInclusive upper chapter number.
[in,out]bufExisting report buffer to append to.
[in]capTotal capacity of buf in bytes.
Precondition
st and buf are non-NULL and buf is NUL-terminated within cap.
lo is no greater than hi and range iteration cannot overflow long.
Postcondition
buf remains NUL-terminated within cap.
Persistent state and chapter records remain unchanged.
Note
Values that do not fit are omitted rather than written partially.
Since
0.1.0

Definition at line 536 of file mdl_state.c.

References internal_mdl_state_has_complete_number(), k_state_gap_cap, and strlen().

Referenced by mdl_state_coverage().

◆ internal_mdl_state_chapter_number_as_long()

bool internal_mdl_state_chapter_number_as_long ( const mdl_chapter_rec_t * chapter,
long * out )
static

Convert an exactly integral chapter number to long.

Rejects unknown, fractional, and out-of-range binary64 chapter numbers before performing the narrowing conversion.

Parameters
[in]chapterValidated chapter record to inspect.
[out]outReceives the integral value on success.
Returns
Whether the chapter number has an exact long representation.
Return values
trueout was initialized with the exact integral value.
falseThe number was unknown, fractional, or outside long range.
Precondition
chapter and out are non-NULL.
chapter is a readable initialized record.
Postcondition
Success initializes out exactly once.
Failure leaves persistent state and chapter records unchanged.
Note
Performs no locale-sensitive decimal conversion.
Since
0.1.0

Definition at line 430 of file mdl_state.c.

References mdl_chapter_rec_t::number, mdl_chapter_rec_t::number_known, and RA8_INTERNAL.

Referenced by internal_mdl_state_complete_span(), and internal_mdl_state_has_complete_number().

◆ internal_mdl_state_chapter_number_valid()

bool internal_mdl_state_chapter_number_valid ( double number,
bool known )
static

Validate an explicit chapter-number tuple.

Requires a finite number and canonical 0.0 when presence is false.

Parameters
[in]numberCandidate parsed chapter number.
[in]knownWhether the number was explicitly present.
Returns
Whether the tuple satisfies the persisted invariant.
Return values
trueThe number is finite and canonical for known.
falseThe number is non-finite or unknown-but-nonzero.
Precondition
known is a canonical C Boolean.
number is passed by value.
Postcondition
No state is modified.
The result is deterministic for the supplied tuple.
Note
Thread-safe: has no shared state.
Since
0.1.0

Definition at line 136 of file mdl_state.c.

References RA8_INTERNAL.

Referenced by mdl_state_add_chapter_numbered(), mdl_state_set_chapter_metadata(), and priv_mdl_state_valid().

◆ internal_mdl_state_complete_span()

bool internal_mdl_state_complete_span ( const mdl_state_t * st,
long * lo,
long * hi,
size_t * n )
static

Number span [lo,hi] of complete integral chapters.

Scans bounded chapter records, considers only complete chapters with exact integral numbers, and returns their minimum, maximum, and count.

Parameters
[in]stValidated bounded state to scan.
[out]loReceives the minimum complete integral chapter number.
[out]hiReceives the maximum complete integral chapter number.
[out]nReceives the number of complete integral chapters.
Returns
Whether at least one qualifying chapter exists.
Return values
truelo, hi, and n describe the complete integral span.
falseNo complete integral chapter exists; outputs are not authoritative.
Precondition
st, lo, hi, and n are non-NULL.
st contains no more than its fixed chapter capacity.
Postcondition
No state record is modified.
Success initializes all three output values.
Note
Fractional and unknown chapter numbers do not contribute to the span.
Since
0.1.0

Definition at line 464 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_state_t::chapters, mdl_chapter_rec_t::complete, and internal_mdl_state_chapter_number_as_long().

Referenced by mdl_state_coverage().

◆ internal_mdl_state_has_complete_number()

bool internal_mdl_state_has_complete_number ( const mdl_state_t * st,
long num )
static

True when a complete chapter with parsed number num exists.

Scans only the bounded chapter prefix and requires both completion and an exact integral-number match.

Parameters
[in]stValidated bounded state to scan.
[in]numIntegral chapter number being queried.
Returns
Whether a complete record has exactly num.
Return values
trueA complete exact-number match exists.
falseNo complete exact-number match exists.
Precondition
st is non-NULL and readable.
st contains no more than its fixed chapter capacity.
Postcondition
No state record or caller storage is modified.
The result reflects only records marked complete.
Note
The scan is deterministic and allocation-free.
Since
0.1.0

Definition at line 506 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_state_t::chapters, mdl_chapter_rec_t::complete, internal_mdl_state_chapter_number_as_long(), and RA8_INTERNAL.

Referenced by internal_mdl_state_append_gaps().

◆ internal_mdl_state_page_response_valid()

bool internal_mdl_state_page_response_valid ( int64_t fetched_at,
uint16_t response_status )
static

Whether persisted HTTP observation metadata is canonical.

Accepts the exact legacy unknown pair or a nonnegative completion time paired with a three-digit HTTP response status.

Parameters
[in]fetched_atMost recent fetch completion time in epoch seconds.
[in]response_statusMost recent HTTP status, or zero if unknown.
Returns
Whether the observation pair can be retained in persistent state.
Return values
trueThe pair is the legacy unknown value or a valid observation.
falseThe time is negative or the response status is out of range.
Precondition
Integer arguments use their declared widths.
Legacy callers encode unknown metadata as the exact pair (0, 0).
Postcondition
The arguments are not modified.
No state, storage, or network operation occurs.
Note
A zero epoch is valid when paired with an actual HTTP status.
Since
0.1.0

Definition at line 43 of file mdl_state.c.

References k_state_http_status_max, k_state_http_status_min, and RA8_INTERNAL.

Referenced by mdl_state_add_page(), mdl_state_note_page_response(), and priv_mdl_state_valid().

◆ mdl_state_add_chapter()

mdl_chapter_rec_t * mdl_state_add_chapter ( mdl_state_t * st,
const char * id,
const char * url,
long number )

Find or append a chapter record, returning it.

Parameters
[in,out]stState to update (never NULL).
[in]idChapter identifier (never NULL).
[in]urlChapter page URL (never NULL).
[in]numberParsed chapter number (0 when unnumbered).
Returns
The existing or newly-added record, or NULL when the table is full.
Return values
NULLA NULL argument, or k_mdl_max_chapters already reached.
Precondition
st, id, url are non-NULL and NUL-terminated.
The caller treats NULL as "table full" and degrades, never crashes.
Postcondition
A new record starts incomplete with page_count == 0; a nonzero number is marked known and zero retains legacy "unknown" semantics.
st->chapter_count grows by at most one.
Note
Not thread-safe.
Since
0.1.0

Definition at line 257 of file mdl_state.c.

References mdl_state_add_chapter_numbered().

◆ mdl_state_add_chapter_numbered()

mdl_chapter_rec_t * mdl_state_add_chapter_numbered ( mdl_state_t * st,
const char * id,
const char * url,
double number,
bool number_known )

Find or append a chapter with explicit parsed-number presence.

Unlike the source-compatible mdl_state_add_chapter wrapper, this API keeps chapter zero distinct from an unknown number and preserves fractional chapter numbers. An unknown number must be supplied canonically as 0.0.

Parameters
[in,out]stState to update (never NULL).
[in]idChapter identifier (never NULL).
[in]urlChapter page URL (never NULL).
[in]numberFinite parsed chapter number, or 0.0 if unknown.
[in]number_knownWhether number was explicitly parsed.
Returns
The existing or newly-added record, or NULL when invalid/full.
Return values
NULLA NULL/malformed argument, invalid number, or full table.
Precondition
st, id, and url are non-NULL.
id and url are NUL-terminated and fit their fixed fields.
Postcondition
A new record stores number and number_known exactly.
An existing record is returned without changing its metadata.
Note
Not thread-safe.
Since
0.1.0

Definition at line 262 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_chapter_rec_t::chapter_id, mdl_state_t::chapters, internal_mdl_state_chapter_number_valid(), k_mdl_chapter_id_max, k_mdl_max_chapters, k_mdl_url_max, mdl_state_find_chapter(), memset(), mdl_chapter_rec_t::number, mdl_chapter_rec_t::number_known, priv_mdl_state_field_valid(), and mdl_chapter_rec_t::source_url.

Referenced by internal_mdl_fetch_process_chapter(), internal_mdl_state_apply_chapter_values(), and mdl_state_add_chapter().

◆ mdl_state_add_page()

bool mdl_state_add_page ( mdl_state_t * st,
uint64_t url_hash,
uint64_t content_hash,
const char * rel_path,
const char * etag,
const char * last_modified,
int64_t fetched_at,
uint16_t response_status )

Add or replace a URL-keyed page cache record.

Adds or refreshes a bounded page identity and its optional HTTP validators. The URL hash is the sole cache key: when magic-byte validation changes a page's canonical extension or a combined layout relocates it, the existing record is replaced instead of leaving an older path first in lookup order. Empty or NULL validator strings are stored as empty values.

Parameters
[in,out]stState to update (never NULL).
[in]url_hashFNV-1a 64 of the page's source URL.
[in]content_hashFNV-1a 64 of the fetched page bytes.
[in]rel_pathPage path relative to the series dir (never NULL).
[in]etagCached ETag, or NULL when unavailable.
[in]last_modifiedCached Last-Modified, or NULL when unavailable.
[in]fetched_atMost recent fetch completion time in epoch seconds.
[in]response_statusMost recent HTTP status, or zero if unknown.
Returns
Whether the record was stored.
Return values
trueThe record was appended or the existing URL record replaced.
falseThe pool is full (k_mdl_max_page_recs) or a NULL argument; dedup simply degrades to a refetch next time, never a crash.
Precondition
st and rel_path are non-NULL; rel_path is NUL-terminated.
rel_path is a sanitised path with no ../leading /.
Postcondition
On true, st->page_rec_count grows by one only for a new URL hash.
On false, st is unchanged.
Note
Not thread-safe.
See also
mdl_state_find_page
Since
0.1.0

Definition at line 347 of file mdl_state.c.

References mdl_page_rec_t::content_hash, mdl_page_rec_t::etag, mdl_page_rec_t::fetched_at, internal_mdl_state_page_response_valid(), k_mdl_etag_max, k_mdl_last_mod_max, k_mdl_max_page_recs, k_mdl_relpath_max, mdl_page_rec_t::last_modified, mdl_state_t::page_rec_count, mdl_state_t::pages, priv_mdl_state_field_valid(), mdl_page_rec_t::rel_path, mdl_page_rec_t::response_status, and mdl_page_rec_t::url_hash.

Referenced by internal_mdl_fetch_publish_page(), internal_mdl_fetch_try_reuse(), and internal_mdl_state_apply_page().

◆ mdl_state_chapter_complete()

bool mdl_state_chapter_complete ( const mdl_state_t * st,
const char * id )

Whether a chapter is recorded fully fetched and verified.

Parameters
[in]stState to query (never NULL).
[in]idChapter identifier (never NULL).
Returns
Whether id is present AND its record is complete.
Return values
trueThe chapter exists and every page is fetched and verified.
falseNot recorded, incomplete, or a NULL argument.
Precondition
st and id are non-NULL; id is NUL-terminated.
The caller uses this to decide --update skips.
Postcondition
st is not modified.
Note
Not thread-safe.
Since
0.1.0

Uses fixed-capacity state supplied by the caller without allocation. Any text retained by the state is copied into bounded records.

Postcondition
Documented outputs and the return value describe the same outcome.

Definition at line 308 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_chapter_rec_t::chapter_id, mdl_state_t::chapters, mdl_chapter_rec_t::complete, and strcmp().

◆ mdl_state_chapter_pages()

uint16_t mdl_state_chapter_pages ( const mdl_state_t * st,
const char * id )

Recorded page count for a chapter (0 when unknown).

The combined-download page numbering is derived from these counts, so a run that resumes reproduces the same continuous numbering an uninterrupted run would have produced.

Parameters
[in]stState to query (never NULL).
[in]idChapter identifier (never NULL).
Returns
The chapter's recorded page_count, or 0 if unknown/absent.
Return values
0The chapter is absent, unlearned, or a NULL argument was passed.
Precondition
st and id are non-NULL; id is NUL-terminated.
The caller treats 0 as "unknown", not "zero-page chapter".
Postcondition
st is not modified.
Note
Not thread-safe.
Since
0.1.0
Postcondition
Documented outputs and the return value describe the same outcome.

Definition at line 321 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_chapter_rec_t::chapter_id, mdl_state_t::chapters, mdl_chapter_rec_t::page_count, and strcmp().

◆ mdl_state_coverage()

void mdl_state_coverage ( const mdl_state_t * st,
char * buf,
size_t cap )

Render a one-line coverage summary (chapter span, count, gaps).

Summarises which chapters are complete for the library --list view: the count, the numeric span, and the missing chapter numbers inside that span, so a reader can spot a hole without reading the directory tree.

Parameters
[in]stState to summarise (never NULL).
[out]bufDestination buffer for the NUL-terminated line (never NULL).
[in]capCapacity of buf in bytes (must be > 0).
Returns
Nothing.
Precondition
st and buf are non-NULL; cap > 0.
The caller prints buf as one line.
Postcondition
buf is NUL-terminated.
st is not modified.
Note
Not thread-safe: writes caller storage.
Since
0.1.0

Definition at line 559 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_state_t::chapters, mdl_chapter_rec_t::complete, internal_mdl_state_append_gaps(), and internal_mdl_state_complete_span().

Referenced by internal_list_cb().

◆ mdl_state_find_chapter()

mdl_chapter_rec_t * mdl_state_find_chapter ( mdl_state_t * st,
const char * id )

Find a chapter record by its stable identifier.

Parameters
[in]stState to search (never NULL).
[in]idChapter identifier (never NULL).
Returns
The matching record, or NULL when none is recorded.
Return values
NULLNo chapter with id, or a NULL argument.
Precondition
st and id are non-NULL; id is NUL-terminated.
The caller must not retain the pointer across an add that may move data.
Postcondition
st is not modified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 243 of file mdl_state.c.

References mdl_state_t::chapter_count, mdl_chapter_rec_t::chapter_id, mdl_state_t::chapters, and strcmp().

Referenced by internal_export_fresh_separate(), internal_mdl_state_apply_chapter_values(), and mdl_state_add_chapter_numbered().

◆ mdl_state_find_page()

const mdl_page_rec_t * mdl_state_find_page ( const mdl_state_t * st,
uint64_t url_hash )

Find a page record by its source-URL hash (the dedup lookup).

Parameters
[in]stState to search (never NULL).
[in]url_hashFNV-1a 64 of the candidate source URL.
Returns
The first matching page record, or NULL when none is held.
Return values
NULLNo page with url_hash, or a NULL st.
Precondition
st is non-NULL.
url_hash came from mdl_hash_str on the source URL.
Postcondition
st is not modified.
Note
Not thread-safe.
See also
mdl_state_add_page
Since
0.1.0

Definition at line 334 of file mdl_state.c.

References mdl_state_t::page_rec_count, mdl_state_t::pages, and mdl_page_rec_t::url_hash.

Referenced by internal_mdl_fetch_one_page(), internal_mdl_fetch_prepare_page(), and internal_mdl_fetch_try_reuse().

◆ mdl_state_init()

void mdl_state_init ( mdl_state_t * st)

Reset a state object to an empty, current-version library.

Parameters
[out]stState to clear (never NULL).
Returns
Nothing.
Precondition
st is non-NULL and addresses a full mdl_state_t.
The caller owns st for the duration (not thread-safe).
Postcondition
st->version == k_mdl_state_version and all counts are 0.
Every metadata string is the empty string.
Note
Not thread-safe: initialises caller storage.
Since
0.1.0

Uses fixed-capacity state supplied by the caller without allocation. Any text retained by the state is copied into bounded records.

Definition at line 52 of file mdl_state.c.

References k_mdl_state_version, memset(), and mdl_state_t::version.

Referenced by internal_mdl_state_load_mode(), internal_mdl_state_load_slot(), and priv_mdl_state_parse_file().

◆ mdl_state_note_page_response()

bool mdl_state_note_page_response ( mdl_state_t * st,
uint64_t url_hash,
int64_t fetched_at,
uint16_t response_status )

Refresh the observed HTTP result for one existing URL cache entry.

Locates the record by its stable URL hash and atomically replaces only the completion time and response-status fields.

Parameters
[in,out]stState containing the URL-keyed record.
[in]url_hashFNV-1a 64 hash selecting the record.
[in]fetched_atCompleted request time in epoch seconds.
[in]response_statusHTTP response status in 100..599.
Returns
Whether an existing record and valid observation were updated.
Return values
trueThe matching record now carries the supplied observation.
falseNo record matched or the time/status was invalid.
Precondition
st is non-NULL and exclusively owned.
fetched_at is nonnegative.
Postcondition
Success changes only the two observation fields.
Failure leaves st unchanged.
Note
Used after a bodyless 304 revalidates already-verified local bytes.
Since
0.1.0

Definition at line 393 of file mdl_state.c.

References mdl_page_rec_t::fetched_at, internal_mdl_state_page_response_valid(), mdl_state_t::page_rec_count, mdl_state_t::pages, mdl_page_rec_t::response_status, and mdl_page_rec_t::url_hash.

Referenced by internal_mdl_fetch_resolve_not_modified().

◆ mdl_state_set_chapter_metadata()

bool mdl_state_set_chapter_metadata ( mdl_chapter_rec_t * chapter,
const char * title,
double number,
bool number_known )

Set a chapter's display title and explicit parsed number.

Applies both fields transactionally after validating the title and number. A known number may be zero or fractional; an unknown number must be 0.0.

Parameters
[in,out]chapterChapter record to update (never NULL).
[in]titleDisplay title (may be empty, never NULL).
[in]numberFinite parsed chapter number, or 0.0 if unknown.
[in]number_knownWhether number was explicitly parsed.
Returns
Whether the complete metadata tuple was accepted.
Return values
trueThe title and number were stored.
falseAn argument was invalid; chapter is unchanged.
Precondition
chapter is non-NULL and caller-owned.
title is non-NULL and NUL-terminated.
Postcondition
On true, the chapter metadata exactly matches the arguments.
On false, chapter is unchanged.
Note
Not thread-safe: writes caller storage.
Since
0.1.0

Definition at line 293 of file mdl_state.c.

References internal_mdl_state_chapter_number_valid(), mdl_chapter_rec_t::number, mdl_chapter_rec_t::number_known, priv_mdl_state_field_valid(), and mdl_chapter_rec_t::title.

Referenced by internal_mdl_fetch_chapter_pages_and_checkpoint(), and internal_mdl_state_apply_chapter_values().

◆ mdl_state_set_series()

void mdl_state_set_series ( mdl_state_t * st,
const char * url,
const char * title,
const char * site_name,
const char * site_host,
const char * config_path )

Record the series identity and the descriptor used.

Parameters
[in,out]stState to update (never NULL).
[in]urlSeries page URL, or NULL to leave unchanged.
[in]titleSeries title, or NULL to leave unchanged.
[in]site_nameDescriptor display name, or NULL.
[in]site_hostSite host, or NULL.
[in]config_pathDescriptor file path used (for update-all), or NULL.
Returns
Nothing.
Precondition
st is non-NULL.
Any non-NULL string argument is NUL-terminated.
Postcondition
Each non-NULL argument is copied (truncation-safe) into st.
Fields whose argument was NULL keep their previous value.
Note
Not thread-safe: writes caller storage.
Since
0.1.0

Uses fixed-capacity state supplied by the caller without allocation. Any text retained by the state is copied into bounded records.

Definition at line 226 of file mdl_state.c.

References mdl_state_t::config_path, priv_mdl_state_set_opt(), mdl_state_t::series_title, mdl_state_t::series_url, mdl_state_t::site_host, and mdl_state_t::site_name.

Referenced by internal_reconcile_series_state().

◆ mdl_state_set_series_metadata()

bool mdl_state_set_series_metadata ( mdl_state_t * st,
const char * summary,
const char * writer,
const char * artist,
const char * cover_url,
const char * cover_path,
const char * language,
mdl_state_reading_direction_t direction )

Set the optional rich metadata persisted for a series.

Copies the complete metadata tuple only when every field fits its fixed destination, contains no TAB/newline record delimiters, the cover path is a relative non-traversing path, and direction is a supported value. Empty strings explicitly clear fields; NULL string arguments are invalid.

Parameters
[in,out]stState to update (never NULL).
[in]summarySeries synopsis (may be empty).
[in]writerWriter/author name (may be empty).
[in]artistArtist/illustrator name (may be empty).
[in]cover_urlRemote cover URL (may be empty).
[in]cover_pathLocal cover path relative to the series directory.
[in]languageBCP-47 language tag (may be empty).
[in]directionPage progression direction.
Returns
Whether the complete tuple was accepted.
Return values
trueEvery value was validated and copied.
falseAn argument was NULL, overlong, malformed, or unsupported.
Precondition
st is non-NULL and caller-owned.
All string arguments are non-NULL and NUL-terminated.
Postcondition
On true, all rich series metadata fields equal the supplied values.
On false, st is unchanged.
Note
Not thread-safe: writes caller storage.
Since
0.1.0

Definition at line 186 of file mdl_state.c.

References mdl_state_t::artist, mdl_state_t::cover_path, mdl_state_t::cover_url, k_mdl_language_max, k_mdl_person_max, k_mdl_relpath_max, k_mdl_state_read_ltr, k_mdl_state_read_rtl, k_mdl_summary_max, k_mdl_url_max, mdl_state_t::language, memcpy(), priv_mdl_state_field_valid(), priv_mdl_state_relative_path_valid(), mdl_state_t::reading_direction, mdl_state_t::summary, and mdl_state_t::writer.

Referenced by internal_reconcile_series_state().

◆ priv_mdl_state_field_valid()

bool priv_mdl_state_field_valid ( const char * text,
size_t cap )

True when a record field fits and cannot inject a line or column.

Validate one delimiter-free bounded state field.

Definition at line 70 of file mdl_state.c.

References RA8_PRIV, and strnlen().

Referenced by internal_mdl_state_apply_kv(), mdl_state_add_chapter_numbered(), mdl_state_add_page(), mdl_state_set_chapter_metadata(), mdl_state_set_series_metadata(), priv_mdl_state_relative_path_valid(), and priv_mdl_state_valid().

◆ priv_mdl_state_relative_path_valid()

bool priv_mdl_state_relative_path_valid ( const char * path,
size_t cap )

Validate a bounded relative path.

Validate a bounded relative path stored in state.

Accepts empty paths and rejects absolute, empty-component, and .. component paths without accessing the filesystem.

Parameters
[in]pathCandidate NUL-terminated path.
[in]capMaximum field capacity, including NUL.
Returns
Whether the complete path is safe and bounded.
Return values
trueThe path is empty or safely relative.
falseThe path is malformed, overlong, absolute, or traversing.
Precondition
path is non-NULL.
cap is greater than zero.
Postcondition
path is unchanged.
No filesystem state is accessed or modified.
Note
Thread-safe: reads only caller storage.
Since
0.1.0

Definition at line 95 of file mdl_state.c.

References priv_mdl_state_field_valid(), RA8_PRIV, and strlen().

Referenced by internal_mdl_state_apply_metadata(), mdl_state_set_series_metadata(), and priv_mdl_state_valid().

◆ priv_mdl_state_set_opt()

void priv_mdl_state_set_opt ( char * dst,
size_t cap,
const char * val )

Copy val into a bounded field when val is non-NULL.

Copy one optional value into a bounded state field.

Definition at line 62 of file mdl_state.c.

References RA8_PRIV.

Referenced by internal_mdl_state_apply_kv(), and mdl_state_set_series().

◆ priv_mdl_state_valid()