|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Implementation of the clean-room RAR4/RAR5 archive walker (ra8_rar.h). More...
#include "ra8_rar.h"#include <string.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_rar5.h"Go to the source code of this file.
Enumerations | |
| enum | rar_vint_bits_t : uint8_t { k_rar_vint_data = 0x7FU , k_rar_vint_cont = 0x80U , k_rar_vint_bits = 7U } |
| Bit layout of one RAR5 variable-length integer byte. More... | |
| enum | rar4_layout_t : uint16_t { k_rar4_off_type = 2U , k_rar4_off_flags = 3U , k_rar4_off_size = 5U , k_rar4_off_add = 7U , k_rar4_base_len = 7U , k_rar4_off_unp = 11U , k_rar4_off_method = 25U , k_rar4_off_namesz = 26U , k_rar4_off_attr = 28U , k_rar4_off_name = 32U , k_rar4_off_name_large = 40U } |
| RAR4 block/file-header field byte offsets (from the block start). More... | |
| enum | rar4_bits_t : uint16_t { k_rar4_flag_long = 0x8000U , k_rar4_flag_large = 0x0100U , k_rar4_flag_dirmsk = 0x00E0U , k_rar4_type_file = 0x0074U , k_rar4_method_stor = 0x0030U } |
| RAR4 header flag bits, block type, and method sentinel. More... | |
| enum | rar5_bits_t : uint8_t { k_rar5_type_file = 2U , k_rar5_hflag_extra = 0x01U , k_rar5_hflag_data = 0x02U , k_rar5_fflag_dir = 0x01U , k_rar5_fflag_mtime = 0x02U , k_rar5_fflag_crc = 0x04U , k_rar5_method_shift = 7U , k_rar5_method_mask = 0x07U , k_rar5_fixed_field = 4U } |
| RAR5 header/file flag bits, method field placement, and type. More... | |
| enum | rar_word_t : uint8_t { k_rar_w16 = 2U , k_rar_w32 = 4U , k_rar_hi_sh = 32U } |
| Byte widths and the 32-bit high-dword shift used by the decoders. More... | |
Functions | |
| static void | internal_copy_object (void *dst, const void *src, size_t len) |
| Copy an object representation through compatible byte-pointer types. | |
| static bool | internal_bytes_equal (const void *lhs, const void *rhs, size_t len) |
| Compare byte representations through compatible pointer types. | |
| static uint16_t | internal_le16 (const uint8_t *p) |
| Decode a little-endian uint16 from two unaligned bytes. | |
| static uint32_t | internal_le32 (const uint8_t *p) |
| Decode a little-endian uint32 from four unaligned bytes. | |
| static bool | internal_vint (const uint8_t *buf, size_t len, size_t *pos, uint64_t *val) |
Decode one RAR5 vint, advancing pos past its bytes. | |
| static uint16_t | internal_copy_name (const ra8_rar_t *rar, uint64_t name_abs, const uint8_t *scratch, size_t n, size_t in_pos, uint64_t name_len, char *name_buf, uint16_t name_cap) |
| Copy a member name into the caller buffer, from scratch or a direct read. | |
| static bool | internal_rar4_file (const ra8_rar_t *rar, uint64_t off, const uint8_t *scratch, size_t n, uint16_t flags, uint16_t hsize, char *nbuf, uint16_t ncap, ra8_rar_entry_t *out) |
Decode the RAR4 file-specific fields and fill out. | |
| static ra8_err_t | internal_rar4_block (const ra8_rar_t *rar, uint64_t off, char *nbuf, uint16_t ncap, ra8_rar_entry_t *out) |
Walk one RAR4 block at off. | |
| static bool | internal_rar5_file_vints (const uint8_t *scratch, size_t n, size_t *pos, uint64_t *fflags, uint64_t *unp, uint64_t *cinfo, uint64_t *namesz) |
Decode the RAR5 file-header vint stream, advancing pos past it. | |
| static bool | internal_rar5_file (const ra8_rar_t *rar, uint64_t off, const uint8_t *scratch, size_t n, size_t pos, uint64_t data_off, uint64_t dsize, char *nbuf, uint16_t ncap, ra8_rar_entry_t *out) |
| Decode the RAR5 file-specific fields after the common header vints. | |
| static ra8_err_t | internal_rar5_block (const ra8_rar_t *rar, uint64_t off, char *nbuf, uint16_t ncap, ra8_rar_entry_t *out) |
Walk one RAR5 block at off. | |
| static void | internal_rar_match_signature (const uint8_t *hdr, size_t got, ra8_rar_t *rar) |
| Identify the RAR generation from the leading signature bytes. | |
| 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. | |
| static ra8_err_t | internal_rar_check_stored (const ra8_rar_t *rar, const ra8_rar_entry_t *ent, size_t cap) |
Validate that ent is an extractable STORE member fitting cap. | |
| static bool | internal_rar_read_exact (const ra8_rar_t *rar, uint64_t data_off, uint64_t need, uint8_t *buf) |
Stream exactly need bytes of a STORE member into buf. | |
| 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. | |
| static ra8_err_t | internal_rar_extract_reject_null (const ra8_rar_t *rar, const ra8_rar_entry_t *ent, const uint8_t *buf, const size_t *got) |
| Null-check the required arguments of ra8_rar_extract. | |
| 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. | |
Variables | |
| static const char *const | s_tag_rar = "ra8_rar" |
| Log tag for RAR-walker diagnostics. | |
Implementation of the clean-room RAR4/RAR5 archive walker (ra8_rar.h).
Two block grammars behind one iterator. ra8_rar_open matches the signature and records the first block offset; ra8_rar_next reads one block header into a fixed stack scratch and decodes it under either the RAR4 fixed-field layout or the RAR5 variable-length-integer (vint) layout, always producing the offset of the next block so the caller walks the archive with a bounded loop. ra8_rar_extract_stored streams a STORE member's literal bytes out.
The RAR5 vint is little-endian base-128: seven data bits per byte, high bit set means "continue". A file member's data area begins immediately after its whole header (RAR5: off + <crc+headersize-vint bytes> + headersize; RAR4: off + head_size), which is how a STORE member's bytes are located without a decompressor.
Every parser guards each read against the bytes actually available, so a truncated block is rejected (k_ra8_err_validation_failed) rather than over-read.
Definition in file ra8_rar.c.
| enum rar4_bits_t : uint16_t |
RAR4 header flag bits, block type, and method sentinel.
Flags select optional fields; the directory test is a masked equality.
| enum rar4_layout_t : uint16_t |
RAR4 block/file-header field byte offsets (from the block start).
The classic RAR4 header is fixed-layout; each member names the offset of a field the parser reads with a little-endian decode.
| enum rar5_bits_t : uint8_t |
RAR5 header/file flag bits, method field placement, and type.
Header flags gate the extra/data-size vints; file flags gate the fixed mtime/CRC fields; the method occupies bits 7-9 of comp-info.
| enum rar_vint_bits_t : uint8_t |
Bit layout of one RAR5 variable-length integer byte.
Low 7 bits carry data; the high bit is the continuation flag.
| Enumerator | |
|---|---|
| k_rar_vint_data | Data bits mask within one vint byte. |
| k_rar_vint_cont | Continuation flag within one vint byte. |
| k_rar_vint_bits | Data bits contributed per vint byte. |
| enum rar_word_t : uint8_t |
|
static |
Compare byte representations through compatible pointer types.
Performs an exact bytewise equality check over two bounded spans.
| [in] | lhs | First span of len readable bytes. |
| [in] | rhs | Second span of len readable bytes. |
| [in] | len | Number of bytes to compare. |
| true | The byte spans are identical. |
| false | At least one byte differs. |
lhs is readable for len bytes. rhs is readable for len bytes. Definition at line 76 of file ra8_rar.c.
References memcmp(), and RA8_INTERNAL.
Referenced by internal_rar_match_signature().
|
static |
Copy a member name into the caller buffer, from scratch or a direct read.
Uses the already-read header scratch when the name lies within it, otherwise issues one targeted read of the name bytes. The copy is clamped to name_cap; the returned length is what was copied.
| [in] | rar | Bound archive (for the fallback read). |
| [in] | name_abs | Absolute offset of the name in the archive. |
| [in] | scratch | Header scratch bytes. |
| [in] | n | Valid bytes in scratch. |
| [in] | in_pos | Name offset within scratch. |
| [in] | name_len | Declared name length in bytes. |
| [out] | name_buf | Destination (may be NULL if name_cap is 0). |
| [in] | name_cap | Destination capacity in bytes. |
name_cap). | 0 | name_buf is NULL, name_cap is 0, or a fallback read returned 0. |
scratch holds n readable bytes. name_buf holds name_cap writable bytes (when name_cap > 0). name_cap bytes are written to name_buf. Definition at line 279 of file ra8_rar.c.
References ra8_rar_t::ctx, memcpy(), and ra8_rar_t::read.
Referenced by internal_rar4_file(), and internal_rar5_file().
|
static |
Copy an object representation through compatible byte-pointer types.
Centralizes the parser's permitted bytewise object copy.
| [out] | dst | Destination spanning at least len writable bytes. |
| [in] | src | Source spanning at least len readable bytes. |
| [in] | len | Number of bytes to copy. |
dst is writable for len bytes. src is readable for len bytes and does not overlap dst. len destination bytes equal the source bytes on entry. Definition at line 55 of file ra8_rar.c.
References memcpy(), and RA8_INTERNAL.
Referenced by internal_le16(), internal_le32(), and internal_vint().
|
static |
Decode a little-endian uint16 from two unaligned bytes.
memcpy-based so the source may sit at any alignment; the whole firmware is little-endian, so the bytes map straight to the value.
| [in] | p | Pointer to the two bytes (non-NULL, caller-bounded). |
| 0 | When both bytes are zero. |
p addresses at least two readable bytes. Definition at line 173 of file ra8_rar.c.
References internal_copy_object().
Referenced by internal_rar4_block(), and internal_rar4_file().
|
static |
Decode a little-endian uint32 from four unaligned bytes.
memcpy-based so the source may sit at any alignment; the whole firmware is little-endian, so the bytes map straight to the value.
| [in] | p | Pointer to the four bytes (non-NULL, caller-bounded). |
| 0 | When all four bytes are zero. |
p addresses at least four readable bytes. Definition at line 195 of file ra8_rar.c.
References internal_copy_object().
Referenced by internal_rar4_block(), and internal_rar4_file().
|
static |
Walk one RAR4 block at off.
Reads the fixed 7-byte base header (plus ADD_SIZE when the LONG flag is set), then dispatches file blocks to internal_rar4_file and treats every other block type as a skip (data-less unless LONG). Guarantees a strictly advancing next_off.
| [in] | rar | Bound archive. |
| [in] | off | Block offset (< rar->size). |
| [out] | nbuf | Name buffer. |
| [in] | ncap | Name buffer capacity. |
| [out] | out | Entry to fill. |
| k_ra8_ok | Block decoded. |
| k_ra8_err_validation_failed | Truncated / non-advancing block. |
rar is bound; off < rar->size. out is writable. out is left as the caller zeroed it. Definition at line 390 of file ra8_rar.c.
References ra8_rar_t::ctx, internal_le16(), internal_le32(), internal_rar4_file(), k_ra8_err_validation_failed, k_ra8_ok, k_ra8_rar_hdr_scratch, k_rar4_base_len, k_rar4_flag_long, k_rar4_off_add, k_rar4_off_flags, k_rar4_off_size, k_rar4_off_type, k_rar4_type_file, k_rar_w32, ra8_rar_entry_t::next_off, and ra8_rar_t::read.
Referenced by ra8_rar_next().
|
static |
Decode the RAR4 file-specific fields and fill out.
Reads PACK/UNP sizes (with the optional 64-bit high dwords), the method, and the name; computes the data-area and next-block offsets from head_size. Non-fatal on a short scratch: returns false so the caller reports a malformed block.
| [in] | rar | Bound archive. |
| [in] | off | Block offset. |
| [in] | scratch | Header scratch bytes. |
| [in] | n | Valid bytes in scratch. |
| [in] | flags | HEAD_FLAGS of this block. |
| [in] | hsize | HEAD_SIZE of this block. |
| [out] | nbuf | Name buffer. |
| [in] | ncap | Name buffer capacity. |
| [out] | out | Entry to fill (file fields, data_off, next_off). |
n and were decoded. | true | Fields decoded; out is a valid file entry. |
| false | Truncated fixed fields. |
scratch holds n bytes; hsize is this block's header size. out is writable. out is not relied upon by the caller. Definition at line 329 of file ra8_rar.c.
References ra8_rar_entry_t::data_off, internal_copy_name(), internal_le16(), internal_le32(), ra8_rar_entry_t::is_dir, ra8_rar_entry_t::is_file, k_ra8_rar_method_compressed, k_ra8_rar_method_store, k_rar4_flag_dirmsk, k_rar4_flag_large, k_rar4_method_stor, k_rar4_off_add, k_rar4_off_method, k_rar4_off_name, k_rar4_off_name_large, k_rar4_off_namesz, k_rar4_off_unp, k_rar_hi_sh, k_rar_w32, ra8_rar_entry_t::method, ra8_rar_entry_t::name_len, ra8_rar_entry_t::next_off, ra8_rar_entry_t::pack_size, and ra8_rar_entry_t::unp_size.
Referenced by internal_rar4_block().
|
static |
Walk one RAR5 block at off.
Decodes CRC + header-size vint (which fixes the data-area and next-block offsets), then the header type/flags and the optional extra-area-size / data-size vints; file blocks go to internal_rar5_file, all others are skipped with a valid next_off.
| [in] | rar | Bound archive. |
| [in] | off | Block offset (< rar->size). |
| [out] | nbuf | Name buffer. |
| [in] | ncap | Name buffer capacity. |
| [out] | out | Entry to fill. |
| k_ra8_ok | Block decoded. |
| k_ra8_err_validation_failed | Truncated / non-advancing block. |
rar is bound; off < rar->size. out is writable. out is left as the caller zeroed it. Definition at line 572 of file ra8_rar.c.
References ra8_rar_t::ctx, internal_rar5_file(), internal_vint(), k_ra8_err_validation_failed, k_ra8_ok, k_ra8_rar_hdr_scratch, k_rar5_hflag_data, k_rar5_hflag_extra, k_rar5_type_file, k_rar_w32, ra8_rar_entry_t::next_off, and ra8_rar_t::read.
Referenced by ra8_rar_next().
|
static |
Decode the RAR5 file-specific fields after the common header vints.
From pos (just past header type/flags/extra/data-size), reads the file flags, unpacked size, attributes, optional fixed time/CRC, the compression-info method, host OS, and name; fills the file fields of out. data_off / dsize / next_off were computed by the caller from the header-size vint.
| [in] | rar | Bound archive. |
| [in] | off | Block offset. |
| [in] | scratch | Header scratch bytes. |
| [in] | n | Valid bytes in scratch. |
| [in] | pos | Cursor at the first file field. |
| [in] | data_off | Absolute data-area offset for this block. |
| [in] | dsize | Data-area length (packed size). |
| [out] | nbuf | Name buffer. |
| [in] | ncap | Name buffer capacity. |
| [out] | out | Entry to fill. |
n. | true | Fields decoded; out is a valid file entry. |
| false | Truncated fields. |
scratch holds n bytes; pos <= n. out already has next_off set by the caller. out is not relied upon by the caller. Definition at line 519 of file ra8_rar.c.
References ra8_rar_entry_t::data_off, internal_copy_name(), internal_rar5_file_vints(), ra8_rar_entry_t::is_dir, ra8_rar_entry_t::is_file, k_ra8_rar_method_compressed, k_ra8_rar_method_store, k_rar5_fflag_dir, k_rar5_method_mask, k_rar5_method_shift, ra8_rar_entry_t::method, ra8_rar_entry_t::name_len, ra8_rar_entry_t::pack_size, and ra8_rar_entry_t::unp_size.
Referenced by internal_rar5_block().
|
static |
Decode the RAR5 file-header vint stream, advancing pos past it.
Reads the file flags, unpacked size, and attributes; skips the optional fixed mtime / data-CRC fields the file flags gate; then reads the compression-info, host-OS, and name-size vints. The attributes and host-OS vints are decoded only to advance pos and are then discarded. A truncated stream (any vint running off n) fails without over-read.
| [in] | scratch | Header scratch bytes. |
| [in] | n | Valid bytes in scratch. |
| [in,out] | pos | Cursor into scratch; advanced to the name bytes. |
| [out] | fflags | Receives the file flags. |
| [out] | unp | Receives the unpacked size. |
| [out] | cinfo | Receives the compression-info word (carries the method). |
| [out] | namesz | Receives the declared name length in bytes. |
n. | true | All vints decoded; *pos points at the name bytes. |
| false | A vint ran off n (truncated header). |
scratch holds n readable bytes; *pos <= n on entry. fflags, unp, cinfo, and namesz are writable. Definition at line 452 of file ra8_rar.c.
References internal_vint(), k_rar5_fflag_crc, k_rar5_fflag_mtime, and k_rar5_fixed_field.
Referenced by internal_rar5_file().
|
static |
Validate that ent is an extractable STORE member fitting cap.
Rejects, in order: an unbound archive, a non-file or directory entry, a compressed (non-STORE) member, a member larger than cap, and a member whose data area overruns the archive. Mirrors the guard order ra8_rar_extract_stored needs before it streams the member bytes.
| [in] | rar | Bound archive (its version / size gate the checks). |
| [in] | ent | Candidate entry from ra8_rar_next. |
| [in] | cap | Destination-buffer capacity in bytes. |
| k_ra8_ok | The entry is a STORE member that fits cap. |
| k_ra8_err_invalid_state | The archive was never opened. |
| k_ra8_err_not_supported | A non-file, directory, or compressed member. |
| k_ra8_err_no_mem | The member is larger than cap. |
| k_ra8_err_invalid_size | The member data area overruns the archive. |
rar was bound by ra8_rar_open. ent came from ra8_rar_next on rar. Definition at line 727 of file ra8_rar.c.
References ra8_rar_entry_t::data_off, ra8_rar_entry_t::is_dir, ra8_rar_entry_t::is_file, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_no_mem, k_ra8_err_not_supported, k_ra8_ok, k_ra8_rar_method_store, k_ra8_rar_ver_none, ra8_rar_entry_t::method, ra8_rar_t::size, ra8_rar_entry_t::unp_size, and ra8_rar_t::version.
Referenced by ra8_rar_extract_stored().
|
static |
Null-check the required arguments of ra8_rar_extract.
Runs the mandatory guards on the archive, entry, buffer, and count pointers; the optional decoder scratch is checked later only on the compressed path. Split out so the entry point stays within the function-size budget.
| [in] | rar | Archive pointer. |
| [in] | ent | Entry pointer. |
| [in] | buf | Output buffer pointer. |
| [in] | got | Byte-count output pointer. |
| k_ra8_ok | Every required pointer is non-NULL. |
| k_ra8_err_null_ptr | Some required pointer was NULL. |
Definition at line 828 of file ra8_rar.c.
References k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag_rar.
Referenced by ra8_rar_extract().
|
static |
Identify the RAR generation from the leading signature bytes.
Tests the RAR5 8-byte signature first, then the RAR4 7-byte marker. RAR4 marker "Rar!\x1A\x07\x00" and RAR5 signature "Rar!\x1A\x07\x01\x00" share their first six bytes and diverge at byte 6, so each needs its own constant (a RAR4 match against the RAR5 bytes would fail at that byte). The signatures are written as string literals – the escapes carry the control bytes and the implicit terminating NUL supplies each marker's final 0x00 – so the reader holds no raw-byte magic constant.
| [in] | hdr | Leading header bytes read from the archive. |
| [in] | got | Valid bytes in hdr (>= k_ra8_rar_sig4_len). |
| [in,out] | rar | Archive whose version / first_off are set on a match. |
rar. hdr holds got readable bytes; got >= k_ra8_rar_sig4_len. rar was zeroed (version == k_ra8_rar_ver_none) on entry. rar is unchanged (version == k_ra8_rar_ver_none). Definition at line 640 of file ra8_rar.c.
References ra8_rar_t::first_off, internal_bytes_equal(), k_ra8_rar_sig4_len, k_ra8_rar_sig5_len, k_ra8_rar_ver_4, k_ra8_rar_ver_5, and ra8_rar_t::version.
Referenced by ra8_rar_open().
|
static |
Stream exactly need bytes of a STORE member into buf.
Issues repeated backing reads from data_off until need bytes are copied or a read returns 0 (a short archive). Bounded: need is fixed and every pass copies at least one byte or breaks.
| [in] | rar | Bound archive (its read / ctx perform the I/O). |
| [in] | data_off | Absolute offset of the member data area. |
| [in] | need | Bytes to copy (the member's unpacked size). |
| [out] | buf | Destination (at least need writable bytes). |
need bytes were copied. | true | Exactly need bytes were read into buf. |
| false | A backing read returned 0 before need bytes (short archive). |
rar was bound by ra8_rar_open. buf holds at least need writable bytes. need bytes were written. Definition at line 771 of file ra8_rar.c.
References ra8_rar_t::ctx, and ra8_rar_t::read.
Referenced by ra8_rar_extract_stored().
|
static |
Decode one RAR5 vint, advancing pos past its bytes.
Accumulates 7 data bits per byte, little-endian, stopping at the first byte whose continuation flag is clear. Fails on truncation or a value longer than k_ra8_rar_vint_max bytes. The value is built in two 32-bit halves and assembled by memcpy rather than with a 64-bit variable shift: on Cortex-M a uint64_t << reg lowers to a libgcc __ashldi3 call, so 32-bit shifts keep this leaner (and side-step the emulator's 64-bit shift seam under ra8_emulator).
| [in] | buf | Header scratch bytes. |
| [in] | len | Valid bytes in buf. |
| [in,out] | pos | Cursor into buf; advanced past the vint on success. |
| [out] | val | Receives the decoded value. |
| true | A terminated vint fit within len and the byte budget. |
| false | Truncated (ran off len) or overlong. |
pos <= len on entry. val is writable. Definition at line 226 of file ra8_rar.c.
References internal_copy_object(), k_ra8_rar_vint_max, k_rar_hi_sh, k_rar_vint_bits, k_rar_vint_cont, and k_rar_vint_data.
Referenced by internal_rar5_block(), and internal_rar5_file_vints().
|
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().
|
static |
Log tag for RAR-walker diagnostics.
Definition at line 40 of file ra8_rar.c.
Referenced by internal_rar_extract_reject_null(), ra8_rar_extract(), ra8_rar_extract_stored(), ra8_rar_next(), and ra8_rar_open().