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

Bounded URL naming and portable image-classification helpers. More...

#include <stddef.h>
#include "mdl_storage.h"
#include "ra8_err.h"
Include dependency graph for mdl_urlname.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void mdl_urlname_last_segment (const char *url, char *out, size_t cap)
 Sanitised last non-empty path segment of a URL.
long mdl_urlname_chapter_number (const char *url)
 Parse a chapter URL's integral chapter number.
bool mdl_urlname_chapter_parse (const char *url, double *out)
 Parse an explicitly-marked integral or decimal chapter value.
bool mdl_urlname_chapter_text_parse (const char *text, double *out)
 Parse a selector result as one complete bounded chapter number.
double mdl_urlname_chapter_value (const char *url)
 Parse a chapter URL as a possibly-decimal chapter value.
void mdl_urlname_ext (const char *url, char *out, size_t cap)
 Choose a lower-case image file extension from a URL.
bool mdl_urlname_sniff_image_type (const void *buf, size_t buf_len, const char *content_type, char *out_ext, size_t ext_cap, char *out_mime, size_t mime_cap)
 Sniff true image extension and MIME type from magic bytes and/or HTTP Content-Type.
ra8_err_t mdl_urlname_sniff_file (mdl_storage_t *storage, const char *file_path, const char *content_type, char *out_ext, size_t ext_cap, char *out_mime, size_t mime_cap)
 Sniff true image extension and MIME type from portable storage.

Detailed Description

Bounded URL naming and portable image-classification helpers.

Lexical helpers derive names and numbers from scraped URLs without network or filesystem access. The image-file helper consumes only an injected mdl_storage_t and fw_fs_file_t, so its signature logic is identical for a POSIX sandbox, RAM/FAT/VFS mount, SD card, or future filesystem port.

The last-segment helper runs its result through mdl_sanitize_segment, so a chapter identifier or slug it returns can never be .., absolute, or contain a path separator – the same guarantee the download paths already rely on.

Definition in file mdl_urlname.h.

Function Documentation

◆ mdl_urlname_chapter_number()

long mdl_urlname_chapter_number ( const char * url)

Parse a chapter URL's integral chapter number.

Recognises chapter slugs such as chapter-137, chapter-108-5, and ch-5. Decimal slugs return their integral part here; use mdl_urlname_chapter_value when ordering decimal chapters.

Parameters
[in]urlURL to parse (never NULL).
Returns
The parsed chapter number, or 0 when the URL holds no digits.
Return values
0No decimal digit appears in url.
Precondition
url is non-NULL and NUL-terminated.
The caller treats 0 as "unnumbered", not "chapter zero" specifically.
Postcondition
url is not modified.
The result is the integral truncation of mdl_urlname_chapter_value.
Note
Thread-safe: depends only on its argument.
Since
0.1.0

Definition at line 276 of file mdl_urlname.c.

References mdl_urlname_chapter_value().

◆ mdl_urlname_chapter_parse()

bool mdl_urlname_chapter_parse ( const char * url,
double * out )

Parse an explicitly-marked integral or decimal chapter value.

Recognises chapter-N, /ch-N, and Pepper&Carrot-style /epN markers only within the URL path. Host digits, opaque trailing IDs, query parameters, and fragments are never treated as chapter numbers. A hyphen between the integral and fractional runs is interpreted as a decimal point, so chapter-108-5 is 108.5.

Parameters
[in]urlAbsolute or relative URL to inspect.
[out]outParsed non-negative value on success.
Returns
Whether an explicitly marked chapter value was parsed.
Return values
trueAn explicit, bounded chapter value was found.
falseArguments were invalid, no marker/value was present, or the value exceeded the supported bound.
Precondition
A non-NULL url is NUL-terminated within the documented URL bound.
A non-NULL out addresses writable storage for one double.
Postcondition
On false, out is set to 0.0 when it is non-NULL.
url is never modified.
Note
Thread-safe: uses only caller-owned storage.
Since
0.1.0

Definition at line 210 of file mdl_urlname.c.

References internal_urlname_last_path_marker(), internal_urlname_parse_chapter_digits(), internal_urlname_path_end(), internal_urlname_path_start(), k_urlname_scan_max, strlen(), and strnlen().

Referenced by internal_list_range(), internal_mdl_fetch_process_chapter(), internal_select_window(), internal_sort_by_chapter_num(), and mdl_urlname_chapter_value().

◆ mdl_urlname_chapter_text_parse()

bool mdl_urlname_chapter_text_parse ( const char * text,
double * out )

Parse a selector result as one complete bounded chapter number.

Trims ASCII whitespace, then accepts only a non-negative decimal value. Both 108.5 and the URL-style fractional spelling 108-5 represent chapter 108.5. Signs, exponent notation, labels, NaN/infinity, trailing bytes, excessive precision, and values above the documented chapter bound are rejected.

Parameters
[in]textNUL-terminated selector text to parse.
[out]outParsed non-negative value on success.
Returns
Whether all non-whitespace input formed one bounded chapter value.
Return values
trueThe complete trimmed input was accepted.
falseArguments were invalid or the text was not a strict value.
Precondition
A non-NULL text is NUL-terminated within the URL-name scan bound.
A non-NULL out addresses writable storage for one double.
Postcondition
On false, a non-NULL out is set to 0.0.
text is never modified.
Note
Thread-safe and allocation-free.
Since
0.1.0

Definition at line 238 of file mdl_urlname.c.

References internal_urlname_parse_chapter_digits(), k_urlname_scan_max, and strnlen().

Referenced by internal_mdl_fetch_select_chapter_number().

◆ mdl_urlname_chapter_value()

double mdl_urlname_chapter_value ( const char * url)

Parse a chapter URL as a possibly-decimal chapter value.

A site slug such as chapter-108-5 represents chapter 108.5, not chapter 5. This helper recognises that convention and ordinary dotted decimals while ignoring unrelated digits in the host or earlier path.

Parameters
[in]urlURL to parse; may be NULL.
Returns
Parsed chapter value, or 0.0 for an unnumbered URL. New callers that must distinguish an absent number from chapter zero use mdl_urlname_chapter_parse.
Return values
0.0No explicit bounded chapter marker was found.
otherThe non-negative integral or decimal chapter value.
Precondition
A non-NULL url is NUL-terminated within the documented URL bound.
A NULL url is accepted and treated as unnumbered.
Postcondition
The return value is non-negative.
url is never modified.
Note
Thread-safe: uses only caller-owned storage.
Since
0.1.0

Definition at line 269 of file mdl_urlname.c.

References mdl_urlname_chapter_parse().

Referenced by internal_sort_by_chapter_num(), and mdl_urlname_chapter_number().

◆ mdl_urlname_ext()

void mdl_urlname_ext ( const char * url,
char * out,
size_t cap )

Choose a lower-case image file extension from a URL.

Reads the extension of the URL's last path segment, lower-cases it, and accepts it only if it is a known raster type (jpg, jpeg, png, gif, webp, bmp); anything else – including no extension – yields jpg. Used to name a downloaded page file and to name the copy made when a byte-identical page is reused from another chapter.

Parameters
[in]urlURL whose last segment carries the extension (never NULL).
[out]outDestination buffer for the NUL-terminated extension.
[in]capCapacity of out in bytes (must be >= 5 for "jpeg").
Returns
Nothing.
Precondition
url and out are non-NULL; url is NUL-terminated.
cap is at least 5 so the longest accepted extension fits.
Postcondition
out is a NUL-terminated, lower-case, known extension (default jpg).
out contains no ?/# bytes from a query or fragment.
Note
Thread-safe: writes only caller-provided storage.
Since
0.1.0

Definition at line 349 of file mdl_urlname.c.

References internal_urlname_copy(), internal_urlname_is_known_ext(), internal_urlname_path_end(), and internal_urlname_to_lower_ascii().

Referenced by internal_mdl_fetch_page_leaf().

◆ mdl_urlname_last_segment()

void mdl_urlname_last_segment ( const char * url,
char * out,
size_t cap )

Sanitised last non-empty path segment of a URL.

Strips any ?query/#fragment and trailing slashes, takes the final path segment, and passes it through mdl_sanitize_segment so the result is a single filesystem-safe name. Used for the series slug, per-chapter folder names, and the stable chapter identifier recorded in library state – an identifier derived from the URL path rather than the chapter's position in a freshly scraped list, so it stays fixed as the site adds or reorders chapters.

Parameters
[in]urlAbsolute URL to take the last segment of (never NULL).
[out]outDestination buffer for the sanitised segment (never NULL).
[in]capCapacity of out in bytes (must be >= 2).
Returns
Nothing.
Precondition
url and out are non-NULL; url is NUL-terminated.
cap is at least 2 so a one-character name plus a NUL fits.
Postcondition
out is NUL-terminated and holds no /, .-only, or .. result.
out is non-empty (a generated fallback when the segment was empty).
Note
Thread-safe: writes only caller-provided storage.
See also
mdl_sanitize_segment
Since
0.1.0

Definition at line 75 of file mdl_urlname.c.

References internal_urlname_path_end(), k_urlname_raw_bytes, and mdl_sanitize_segment().

Referenced by internal_export_fresh_separate(), internal_extract_series_metadata(), internal_mdl_fetch_process_chapter(), internal_resolve_removal_target(), mdl_app_run_artifact(), and priv_mdl_app_prepare_series_dir().

◆ mdl_urlname_sniff_file()

ra8_err_t mdl_urlname_sniff_file ( mdl_storage_t * storage,
const char * file_path,
const char * content_type,
char * out_ext,
size_t ext_cap,
char * out_mime,
size_t mime_cap )
nodiscard

Sniff true image extension and MIME type from portable storage.

Reads only the bounded signature prefix needed by mdl_urlname_sniff_image_type, then applies the same magic-first type selection. The file is closed before this function returns.

Parameters
[in,out]storageInitialized filesystem binding and exclusive file workspace.
[in]file_pathCanonical path beneath the bound filesystem root.
[in]content_typeHTTP Content-Type header string (may be NULL or empty).
[out]out_extDestination buffer for lower-case extension (e.g. "jpg"). May be NULL.
[in]ext_capCapacity of out_ext in bytes.
[out]out_mimeDestination buffer for exact MIME type (e.g. "image/jpeg"). May be NULL.
[in]mime_capCapacity of out_mime in bytes.
Returns
Canonical storage or classification status.
Return values
k_ra8_okFile magic or the HTTP content type identifies a supported image.
k_ra8_err_validation_failedClean EOF yielded no supported classification.
k_ra8_err_invalid_argThe storage binding or path is invalid.
k_ra8_err_invalid_sizeThe backend did not reach the bounded prefix in time.
otherAn open, read, or close error propagated unchanged.
Precondition
storage was initialized by mdl_storage_init and is exclusively owned.
file_path is a NUL-terminated canonical portable path.
Each non-NULL output points to writable storage of its corresponding capacity.
Postcondition
On success, each non-empty requested output receives a NUL-terminated canonical value, truncated when its capacity is too small.
On failure requested outputs are unchanged; any opened file is consumed.
Note
A recognised content type may supply the result when file magic is inconclusive.
Since
0.1.0

Definition at line 540 of file mdl_urlname.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(), k_fw_fs_open_read, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_validation_failed, k_ra8_ok, k_urlname_magic_bytes, k_urlname_read_calls, mdl_urlname_sniff_image_type(), and fw_fs_t::streams.

Referenced by internal_cover_current(), internal_epub_media_type_from_sniff(), and priv_mdl_export_prepare_cover().

◆ mdl_urlname_sniff_image_type()

bool mdl_urlname_sniff_image_type ( const void * buf,
size_t buf_len,
const char * content_type,
char * out_ext,
size_t ext_cap,
char * out_mime,
size_t mime_cap )

Sniff true image extension and MIME type from magic bytes and/or HTTP Content-Type.

Inspects HTTP Content-Type header and magic bytes of buffer data:

  • JPEG: FF D8 FF -> .jpg / image/jpeg
  • PNG: 89 50 4E 47 -> .png / image/png
  • WebP: RIFF....WEBP -> .webp / image/webp
  • GIF: GIF87a / GIF89a -> .gif / image/gif
  • BMP: BM -> .bmp / image/bmp
Parameters
[in]bufData buffer holding raw magic bytes (may be NULL if buf_len == 0).
[in]buf_lenLength of buf in bytes.
[in]content_typeHTTP Content-Type header string (may be NULL or empty).
[out]out_extDestination buffer for lower-case extension (e.g. "jpg"). May be NULL.
[in]ext_capCapacity of out_ext in bytes.
[out]out_mimeDestination buffer for exact MIME type (e.g. "image/jpeg"). May be NULL.
[in]mime_capCapacity of out_mime in bytes.
Returns
Whether a supported image type was recognised.
Return values
trueMagic bytes or the HTTP content type identify a supported image.
falseNeither input identifies a supported image.
Precondition
buf is readable for buf_len bytes when buf_len is non-zero.
Each non-NULL output points to writable storage of its corresponding capacity.
Postcondition
On true, each non-empty requested output receives a NUL-terminated canonical value, truncated when its capacity is too small.
On false, requested output buffers are left unchanged.
Note
Magic bytes take precedence over a conflicting HTTP content type.
Since
0.1.0

Definition at line 523 of file mdl_urlname.c.

References internal_copy_image_type(), internal_sniff_content_type(), and internal_sniff_magic_image().

Referenced by internal_body_begin(), and mdl_urlname_sniff_file().