|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Clean-room, read-only RAR archive walker (RAR4 + RAR5 headers, STORE data). More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_rar_t |
| One open RAR archive: the backing plus the detected generation. More... | |
| struct | ra8_rar_entry_t |
| One decoded RAR block: a file member, a directory, or a skipped block. More... | |
Typedefs | |
| typedef struct ra8_rar5_state | ra8_rar5_state_t |
| Forward declaration of the RAR5 decompressor scratch (see ra8_rar5.h). | |
| typedef size_t(* | ra8_rar_read_fn) (void *ctx, uint64_t offset, void *buf, size_t len) |
| Seek+read backing over the RAR container bytes. | |
Enumerations | |
| enum | ra8_rar_version_t : uint8_t { k_ra8_rar_ver_none = 0U , k_ra8_rar_ver_4 = 4U , k_ra8_rar_ver_5 = 5U } |
| Which RAR container generation an archive uses. More... | |
| enum | ra8_rar_method_t : uint8_t { k_ra8_rar_method_store = 0U , k_ra8_rar_method_compressed = 1U } |
| Normalised compression method of a file member. More... | |
| enum | ra8_rar_limits_t : uint16_t { k_ra8_rar_sig4_len = 7U , k_ra8_rar_sig5_len = 8U , k_ra8_rar_hdr_scratch = 128U , k_ra8_rar_vint_max = 10U } |
| Fixed sizes and grammar constants for the RAR block walk. More... | |
Functions | |
| ra8_err_t | ra8_rar_open (ra8_rar_t *rar, ra8_rar_read_fn read, void *ctx, uint64_t size) |
| Detect a RAR archive's generation and locate its first block. | |
| ra8_err_t | ra8_rar_next (const ra8_rar_t *rar, uint64_t off, char *name_buf, uint16_t name_cap, ra8_rar_entry_t *out) |
Decode the block header at off and advance to the next block. | |
| ra8_err_t | ra8_rar_extract_stored (const ra8_rar_t *rar, const ra8_rar_entry_t *ent, uint8_t *buf, size_t cap, size_t *got) |
| Extract a STORE-method member's data into the caller buffer. | |
| ra8_err_t | ra8_rar_extract (const ra8_rar_t *rar, const ra8_rar_entry_t *ent, uint8_t *buf, size_t cap, ra8_rar5_state_t *st, size_t *got) |
| Extract any file member – STORE by copy, RAR5-compressed by decode. | |
Clean-room, read-only RAR archive walker (RAR4 + RAR5 headers, STORE data).
A first-party, hand-written RAR reader for the comic-book-archive (.cbr) use case. It parses the two on-disk RAR container generations – the classic RAR 1.5-4.x block format ("RAR4") and the RAR 5.0 block format ("RAR5") – and exposes each archive member (name, sizes, data offset, compression method) through a bounded, seek+read backing. It extracts only STORE-method (uncompressed) members, which is the common shape for comic archives whose pages are already-compressed JPEG/PNG images (RAR leaves those near-incompressible bytes stored). Members packed with RAR's LZ/PPM compression are enumerated but report k_ra8_rar_method_compressed and are not decoded here – see the module overview note on the follow-up for full RAR5 decompression.
Definition in file ra8_rar.h.
| typedef struct ra8_rar5_state ra8_rar5_state_t |
Forward declaration of the RAR5 decompressor scratch (see ra8_rar5.h).
ra8_rar_extract routes a compressed RAR5 member through the decoder, which needs this caller-owned pool; the full definition lives in ra8_rar5.h so this header stays free of the decoder internals.
| typedef size_t(* ra8_rar_read_fn) (void *ctx, uint64_t offset, void *buf, size_t len) |
Seek+read backing over the RAR container bytes.
Mirrors the streaming EPUB/CBZ read seam (offset + length, bytes-actually-read return), so the same ra8_fs file / ra8_vmem page-cache backing that streams a .epub off storage drives a .cbr with no whole-file residency. A return shorter than len is treated as end-of-file.
| [in] | ctx | Opaque backing context (ra8_rar_t::ctx). |
| [in] | offset | Absolute byte offset within the archive. |
| [out] | buf | Destination buffer (len writable bytes). |
| [in] | len | Bytes requested. |
| enum ra8_rar_limits_t : uint16_t |
Fixed sizes and grammar constants for the RAR block walk.
Signature lengths, the header scratch window, and the maximum bytes in one variable-length integer – the values the parser is coded against.
| enum ra8_rar_method_t : uint8_t |
Normalised compression method of a file member.
The RAR4 METHOD byte and the RAR5 compression-info method field both collapse to this: either the member is stored verbatim or it is packed with one of RAR's compressors (which this reader does not decode).
| Enumerator | |
|---|---|
| k_ra8_rar_method_store | Uncompressed: data area is the file bytes. |
| k_ra8_rar_method_compressed | Packed with a RAR compressor (not decoded). |
| enum ra8_rar_version_t : uint8_t |
Which RAR container generation an archive uses.
Set by ra8_rar_open from the file signature; selects the block-header grammar ra8_rar_next applies.
| Enumerator | |
|---|---|
| k_ra8_rar_ver_none | Not a recognised RAR archive. |
| k_ra8_rar_ver_4 | RAR 1.5-4.x block format ("RAR4"). |
| k_ra8_rar_ver_5 | RAR 5.0 block format ("RAR5"). |
|
nodiscard |
Extract any file member – STORE by copy, RAR5-compressed by decode.
Dispatches on ent's normalised method: a STORE member streams through ra8_rar_extract_stored, while a compressed member of a RAR5 archive is inflated through ra8_rar5_decompress using the caller-owned st pool. A compressed member of a RAR4 archive (the legacy codec) is reported unsupported. This is the single entry the CBR facade uses so both page shapes decode behind one call (SOLID Liskov: STORE and compressed pages are interchangeable to the caller).
| [in] | rar | Archive bound by ra8_rar_open (non-NULL). |
| [in] | ent | A file member from ra8_rar_next (non-NULL, is_file == 1). |
| [out] | buf | Destination for the member's decoded bytes (non-NULL). |
| [in] | cap | Capacity of buf in bytes; must be >= ent->unp_size. |
| [in,out] | st | RAR5 decoder scratch, required only for a compressed member. |
| [out] | got | Receives the number of bytes written (non-NULL). |
| k_ra8_ok | Member decoded; *got == ent->unp_size. |
| k_ra8_err_null_ptr | A required pointer argument was NULL (incl. st for a compressed member). |
| k_ra8_err_invalid_state | rar was never bound by ra8_rar_open. |
| k_ra8_err_not_supported | A directory, a non-file, or a RAR4-compressed member. |
| k_ra8_err_no_mem | cap is smaller than ent->unp_size. |
| k_ra8_err_invalid_size | A STORE member overruns the archive / short read. |
| k_ra8_err_validation_failed | A malformed / truncated compressed stream. |
rar was populated by ra8_rar_open. ent came from ra8_rar_next on the same rar. buf contents are unspecified and *got == 0.Definition at line 840 of file ra8_rar.c.
References ra8_rar_entry_t::data_off, internal_rar_extract_reject_null(), ra8_rar_entry_t::is_dir, ra8_rar_entry_t::is_file, k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_ok, k_ra8_rar_method_store, k_ra8_rar_ver_5, k_ra8_rar_ver_none, ra8_rar_entry_t::method, ra8_rar_entry_t::pack_size, RA8_CHECK_NULL_PTR, ra8_rar5_decompress(), ra8_rar_extract_stored(), s_tag_rar, ra8_rar_entry_t::unp_size, and ra8_rar_t::version.
Referenced by priv_comic_cbr_extract().
|
nodiscard |
Extract a STORE-method member's data into the caller buffer.
Streams ent->unp_size literal bytes from the member's data area ([ent->data_off, ent->data_off + ent->pack_size)) through the archive reader into buf. Only STORE members are supported: a member with ent->method != k_ra8_rar_method_store returns k_ra8_err_not_supported (the RAR compressor is not implemented).
| [in] | rar | Archive bound by ra8_rar_open (non-NULL). |
| [in] | ent | A file member from ra8_rar_next (non-NULL, is_file == 1). |
| [out] | buf | Destination for the member's bytes (non-NULL). |
| [in] | cap | Capacity of buf in bytes; must be >= ent->unp_size. |
| [out] | got | Receives the number of bytes written (non-NULL). |
| k_ra8_ok | Member copied; *got == ent->unp_size. |
| k_ra8_err_null_ptr | A required pointer argument was NULL. |
| k_ra8_err_invalid_state | rar was never bound by ra8_rar_open. |
| k_ra8_err_not_supported | ent is a directory or a compressed member. |
| k_ra8_err_no_mem | cap is smaller than ent->unp_size. |
| k_ra8_err_invalid_size | The member overruns the archive, or the reader returned a short read. |
rar was populated by ra8_rar_open. ent came from ra8_rar_next on the same rar. buf contents are unspecified and *got == 0.Definition at line 785 of file ra8_rar.c.
References ra8_rar_entry_t::data_off, internal_rar_check_stored(), internal_rar_read_exact(), k_ra8_err_invalid_size, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag_rar, and ra8_rar_entry_t::unp_size.
Referenced by ra8_rar_extract().
|
nodiscard |
Decode the block header at off and advance to the next block.
Reads one block header through the archive's reader, decodes it under the archive's generation grammar, and fills out – including out->next_off, the absolute offset of the following block. For a file member the member name is copied into name_buf (up to name_cap bytes; longer names are clamped, out->name_len is the copied length). Non-file blocks (archive header, service, end) set out->is_file == 0 and still yield a valid next_off so the walk continues.
| [in] | rar | Archive bound by ra8_rar_open (non-NULL). |
| [in] | off | Absolute offset of the block header (< rar->size). |
| [out] | name_buf | Buffer for the member name (non-NULL if name_cap > 0). |
| [in] | name_cap | Capacity of name_buf in bytes. |
| [out] | out | Decoded block descriptor (non-NULL). |
| k_ra8_ok | Block decoded; out (and name_buf) filled. |
| k_ra8_err_null_ptr | rar or out was NULL. |
| k_ra8_err_invalid_state | rar was never bound by ra8_rar_open. |
| k_ra8_err_invalid_arg | off is at or past rar->size. |
| k_ra8_err_validation_failed | A truncated / malformed / non-advancing block. |
rar was populated by ra8_rar_open. off is the start of a block header. out is left zeroed.Definition at line 682 of file ra8_rar.c.
References internal_rar4_block(), internal_rar5_block(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_rar_ver_5, k_ra8_rar_ver_none, RA8_CHECK_NULL_PTR, s_tag_rar, ra8_rar_t::size, and ra8_rar_t::version.
Referenced by priv_comic_cbr_open().
|
nodiscard |
Detect a RAR archive's generation and locate its first block.
Reads the leading signature bytes through read, matches the RAR4 marker or the RAR5 signature, and records the offset just past it in rar->first_off. Performs no other I/O; the walk proceeds through ra8_rar_next.
| [out] | rar | Reader to populate (caller-owned). |
| [in] | read | Byte reader over the container file (non-NULL). |
| [in] | ctx | Context passed to read. |
| [in] | size | Container file length in bytes (> 0). |
| k_ra8_ok | Recognised RAR archive; rar bound. |
| k_ra8_err_null_ptr | rar or read was NULL. |
| k_ra8_err_invalid_size | size is 0 or shorter than a signature. |
| k_ra8_err_not_supported | The bytes are not a RAR4 or RAR5 signature. |
read serves offsets [0, size) of the container file. rar is a writable ra8_rar_t. rar is left with version == k_ra8_rar_ver_none.Definition at line 659 of file ra8_rar.c.
References ra8_rar_t::ctx, internal_rar_match_signature(), k_ra8_err_invalid_size, k_ra8_err_not_supported, k_ra8_ok, k_ra8_rar_sig4_len, k_ra8_rar_sig5_len, k_ra8_rar_ver_none, RA8_CHECK_NULL_PTR, ra8_rar_t::read, s_tag_rar, ra8_rar_t::size, and ra8_rar_t::version.
Referenced by internal_open_detect().