17typedef enum : uint16_t {
22typedef enum : uint32_t {
39typedef enum : uint8_t {
46typedef enum : uint16_t {
54typedef enum : uint16_t {
64 while ((*s ==
' ') || (*s ==
'\t') || (*s ==
'\r') || (*s ==
'\n')) {
68 while ((n > 0U) && ((s[n - 1U] ==
' ') || (s[n - 1U] ==
'\t') || (s[n - 1U] ==
'\r') ||
69 (s[n - 1U] ==
'\n'))) {
94 const size_t len =
strlen(val);
98 memcpy(dst, val, len + 1U);
149 for (
size_t i = 0U; i < (
sizeof(fields) /
sizeof(fields[0])); ++i) {
150 if (
strcmp(key, fields[i].key) == 0) {
175 if ((val[0] ==
'\0') || (val[0] ==
'+') || (val[0] ==
'-')) {
178 uint32_t parsed = 0U;
179 for (
size_t index = 0U; val[index] !=
'\0'; ++index) {
180 if ((val[index] <
'0') || (val[index] >
'9')) {
183 const uint32_t digit = (uint32_t)(val[index] -
'0');
223 {
"burst", &s->
burst},
228 for (
size_t i = 0U; i < (
sizeof(fields) /
sizeof(fields[0])); ++i) {
229 if (
strcmp(key, fields[i].key) == 0) {
253 if (
strcmp(val,
"reverse") == 0) {
257 if (
strcmp(val,
"asc") == 0) {
261 if (
strcmp(val,
"doc") == 0) {
295 if (
strcmp(key,
"chapter_order") == 0) {
380 reader->
eof = count == 0U;
411 uint32_t length = 0U;
412 *out_present =
false;
422 *out_present = length > 0U;
426 if (
byte == (uint8_t)
'\n') {
430 if ((length + 1U) >= capacity) {
433 line[length] = (char)
byte;
457 if ((text[0] ==
'\0') || (text[0] ==
'#') || (text[0] ==
'[')) {
460 char* equals =
strchr(text,
'=');
461 if (equals ==
nullptr) {
493 bool present =
false;
495 if ((err !=
k_ra8_ok) || !present) {
529 for (
size_t i = 0U; i < (
sizeof(selectors) /
sizeof(selectors[0])); ++i) {
530 const char* selector = selectors[i];
531 if (selector[0] ==
'\0') {
534 const char* prefixes[] = {
"meta:",
"class:",
"label:",
"literal:"};
536 for (
size_t prefix_index = 0U; prefix_index < (
sizeof(prefixes) /
sizeof(prefixes[0]));
538 const size_t prefix_len =
strlen(prefixes[prefix_index]);
539 if ((
strncmp(selector, prefixes[prefix_index], prefix_len) == 0) &&
540 (selector[prefix_len] !=
'\0')) {
549 return (site->
host[0] !=
'\0') && (site->
language[0] !=
'\0') &&
559 if ((storage ==
nullptr) || (storage->
fs ==
nullptr) || (storage->
file_workspace ==
nullptr) ||
576 uint64_t file_bytes = 0U;
622 return (a > b) ? a : b;
ra8_err_t fw_fs_open(const fw_fs_stream_port_t *streams, const char *path, fw_fs_open_mode_t mode, fw_fs_file_t *file, void *workspace, uint32_t workspace_size)
Open a file into a caller-owned handle and backend workspace.
ra8_err_t fw_fs_read(fw_fs_file_t *file, uint8_t *dst, uint32_t cap, uint32_t *out_read)
Read up to cap bytes; zero bytes is EOF.
ra8_err_t fw_fs_close(fw_fs_file_t *file)
Close and consume an open handle.
ra8_err_t fw_fs_file_size(fw_fs_file_t *file, uint64_t *out_size)
Report the open file's current length.
@ k_fw_fs_open_read
Existing file, read-only.
@ k_polite_img_min_ms
Polite per-image floor.
@ k_polite_img_max_ms
Polite per-image ceiling.
static uint32_t internal_config_max_u32(uint32_t a, uint32_t b)
Return the larger of two unsigned values.
mdl_config_defaults_t
Default politeness bounds (ms) applied before the file is read.
@ k_def_img_delay_max
Per-image spacing ceiling.
@ k_def_chapter_delay_min
Inter-chapter spacing floor.
@ k_def_img_delay_min
Per-image spacing floor.
@ k_def_chapter_delay_max
Inter-chapter spacing ceiling.
static void internal_config_set_defaults(mdl_site_t *out)
Apply the polite default descriptor before the file overrides it.
mdl_config_polite_floor_t
--polite per-request delay floors (milliseconds).
@ k_polite_chap_min_ms
Polite inter-chapter floor.
@ k_polite_chap_max_ms
Polite inter-chapter ceiling.
ra8_err_t mdl_config_load(mdl_storage_t *storage, const char *path, mdl_site_t *out)
Load a site descriptor from a flat key=value file.
mdl_gov_cfg_t mdl_config_gov_cfg(const mdl_site_t *site)
Build the politeness-governor tunables for a loaded site descriptor.
static mdl_kv_result_t internal_config_apply_u32(mdl_site_t *s, const char *key, const char *val)
Apply an unsigned-integer key (jitter delay or governor bound).
mdl_parse_limits_t
Local parser limits.
@ k_line_max
Max config line bytes including NUL.
static bool internal_config_valid(const mdl_site_t *site)
Validate descriptor cross-field and selector invariants.
static ra8_err_t internal_config_next(internal_config_reader_t *reader, uint8_t *out_byte, bool *out_eof)
Read one byte through a bounded buffered portable stream.
static mdl_kv_result_t internal_config_apply_string(mdl_site_t *s, const char *key, const char *val)
Apply a string-valued key and distinguish unknown from invalid.
static ra8_err_t internal_config_apply_line(mdl_site_t *site, char *line)
Apply one already bounded descriptor record.
static bool internal_config_apply_pair(mdl_site_t *s, const char *key, const char *val)
Apply one descriptor key/value pair.
static bool internal_config_set_str(char *dst, size_t cap, const char *val)
Copy one descriptor value without truncation.
void mdl_config_apply_polite(mdl_site_t *site)
Raise a descriptor's per-request delay floors for --polite.
static ra8_err_t internal_config_parse(internal_config_reader_t *reader, mdl_site_t *out)
Parse every descriptor record from an open portable stream.
static bool internal_config_parse_u32(const char *val, uint32_t *out)
Parse one complete unsigned 32-bit decimal field.
static char * internal_config_trim(char *s)
Trim leading/trailing ASCII whitespace in place; return start.
static ra8_err_t internal_config_read_line(internal_config_reader_t *reader, char *line, uint32_t capacity, bool *out_present)
Read one complete bounded descriptor line.
static bool internal_config_parse_order(const char *val, mdl_chapter_order_t *out)
Parse the configured chapter-order spelling.
mdl_config_io_limit_t
Complete descriptor and backend-progress ceilings.
@ k_config_dec_base
Base-10 integer fields.
@ k_config_file_max
Largest accepted descriptor file.
@ k_config_read_calls
One-byte reads plus EOF.
mdl_kv_result_t
Result of applying one descriptor key.
@ k_kv_unknown
Key is not owned by this helper.
@ k_kv_applied
Key and value were accepted.
@ k_kv_invalid
Key is known but value is invalid.
Per-site descriptor loaded from a flat key=value config file.
mdl_chapter_order_t
How to order chapters extracted from a series page.
@ k_mdl_order_asc
Sort by the number parsed from the URL.
@ k_mdl_order_reverse
Reverse document order (newest-first -> old).
@ k_mdl_order_doc
Keep document order.
Jittered inter-request delay plus the per-host politeness governor.
mdl_gov_cfg_t mdl_gov_cfg_default(void)
Conservative default tunables for a site that configures none.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
int strncmp(const char *s1, const char *s2, size_t n)
Compare two strings up to a specified length.
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
char * strchr(const char *s, int c)
Locate first occurrence of character in string.
Caller-owned open file; fields are private to the facade.
fw_fs_stream_port_t streams
Byte-stream operations.
Buffered reader borrowing one initialized storage binding.
uint32_t read_calls
Bounded backend read calls.
fw_fs_file_t file
Caller-owned portable handle.
uint32_t available
Readable scratch byte count.
mdl_storage_t * storage
Injected filesystem and scratch.
bool eof
Clean zero-byte read observed.
uint32_t position
Next unread scratch offset.
Per-site politeness tunables the governor is initialised with.
uint32_t burst
Token-bucket capacity, in requests (>= 1).
uint32_t rate_per_min
Sustained per-host request ceiling (0 = off).
uint16_t max_inflight
Per-host in-flight request cap (>= 1).
uint32_t backoff_max_ms
Backoff-window ceiling.
uint32_t backoff_base_ms
First backoff window on a 429/503.
One site's scraping rules (all data, no logic).
char chapter_number_selector[k_mdl_match_max]
Per-chapter number selector.
uint32_t chapter_delay_min
Inter-chapter spacing floor.
char browse_url[k_mdl_search_url_max]
Latest-updates page (no {q}).
char series_author_selector[k_mdl_match_max]
Series writer selector.
char kind[k_mdl_kind_max]
Content kind hint (reader mode).
uint32_t burst
Token-bucket capacity, in requests.
uint32_t rate_per_min
Sustained per-host request ceiling (0 = off).
char search_url[k_mdl_search_url_max]
Query template with a {q} slot.
uint32_t img_delay_max
Per-image spacing ceiling.
char reading_direction[k_mdl_kind_max]
ltr or rtl.
char name[k_mdl_name_max]
Human-readable site name.
uint32_t chapter_delay_max
Inter-chapter spacing ceiling.
char host[k_mdl_host_max]
Site host, e.g.
char contact[k_mdl_contact_max]
Operator contact for the UA.
char chapter_title_selector[k_mdl_match_max]
Per-chapter title selector.
char page_img_url_contains[k_mdl_match_max]
Keep only URLs with this.
char series_cover_selector[k_mdl_match_max]
Series cover-URL selector.
uint32_t backoff_base_ms
First backoff window on a 429/503.
char chapter_url_contains[k_mdl_match_max]
href must contain this.
uint32_t backoff_max_ms
Backoff-window ceiling.
char language[k_mdl_kind_max]
BCP-47 language tag.
char series_summary_selector[k_mdl_match_max]
Series synopsis selector.
char page_img_attr[k_mdl_attr_max]
Preferred attr (fallback other).
mdl_chapter_order_t chapter_order
Ordering to apply.
uint32_t img_delay_min
Per-image spacing floor.
char search_result_contains[k_mdl_match_max]
Series-link substring on results.
char series_artist_selector[k_mdl_match_max]
Series artist selector.
uint32_t max_inflight
Per-host in-flight request cap.
char chapter_url_prefix[k_mdl_search_url_max]
Absolute series-chapter prefix.
char series_title_selector[k_mdl_match_max]
Series display-title selector.
One non-reentrant downloader filesystem dependency bundle.
uint32_t file_workspace_bytes
File workspace extent.
uint8_t * io_buffer
Caller-owned stream scratch.
const fw_fs_t * fs
Injected portable filesystem.
void * file_workspace
Open-file backend state.
uint32_t io_buffer_bytes
Stream scratch extent.