57 (void)
memcpy(dst, src, len);
78 return memcmp(lhs, rhs, len) == 0;
87typedef enum : uint8_t {
100typedef enum : uint16_t {
120typedef enum : uint16_t {
135typedef enum : uint8_t {
152typedef enum : uint8_t {
226static bool internal_vint(
const uint8_t* buf,
size_t len,
size_t* pos, uint64_t* val)
228 uint32_t words[2] = {0U, 0U};
236 const uint8_t b = buf[*pos];
239 if (shift < hi_bit) {
240 words[0] |= (uint32_t)(d << shift);
241 if (shift > straddle) {
242 words[1] |= (uint32_t)(d >> (hi_bit - shift));
245 words[1] |= (uint32_t)(d << (shift - hi_bit));
281 const uint8_t* scratch,
288 if (name_buf ==
nullptr) {
291 if (name_cap == 0U) {
294 const uint16_t want = (name_len > (uint64_t)name_cap) ? name_cap : (uint16_t)name_len;
295 if ((in_pos + (
size_t)want) <= n) {
296 (void)
memcpy(name_buf, &scratch[in_pos], (
size_t)want);
299 const size_t got = rar->
read(rar->
ctx, name_abs, name_buf, (
size_t)want);
300 return (uint16_t)got;
331 const uint8_t* scratch,
361 out->
data_off = off + (uint64_t)hsize;
362 out->
next_off = off + (uint64_t)hsize + pack;
364 internal_copy_name(rar, off + (uint64_t)pos, scratch, n, pos, (uint64_t)namesz, nbuf, ncap);
397 const size_t n = rar->
read(rar->
ctx, off, scratch,
sizeof(scratch));
419 out->
next_off = off + (uint64_t)hsize + add;
461 uint64_t hostos = 0U;
521 const uint8_t* scratch,
530 uint64_t fflags = 0U;
533 uint64_t namesz = 0U;
537 const uint8_t method =
579 const size_t n = rar->
read(rar->
ctx, off, scratch,
sizeof(scratch));
585 const uint64_t data_off = off + (uint64_t)pos + hsize;
587 uint64_t hflags = 0U;
609 if (!
internal_rar5_file(rar, off, scratch, n, pos, data_off, dsize, nbuf, ncap, out)) {
642 static const char k_sig5[] =
"Rar!\x1A\x07\x01";
643 static const char k_sig4[] =
"Rar!\x1A\x07";
668 const size_t got = read(ctx, 0U, hdr,
sizeof(hdr));
694 if (off >= rar->
size) {
741 if (ent->
unp_size > (uint64_t)cap) {
774 while ((uint64_t)total < need) {
775 const size_t chunk = (size_t)(need - (uint64_t)total);
776 const size_t r = rar->
read(rar->
ctx, data_off + (uint64_t)total, &buf[total], chunk);
782 return (uint64_t)total == need;
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ 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 memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Clean-room RAR 5.0 ("method 50") decompressor – LZ + Huffman + filters.
ra8_err_t ra8_rar5_decompress(const ra8_rar_t *rar, uint64_t data_off, uint64_t pack_size, uint8_t *out, size_t out_cap, uint64_t unp_size, ra8_rar5_state_t *st, size_t *got)
Decompress one RAR5-packed member into the caller's output buffer.
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_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 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.
rar_word_t
Byte widths and the 32-bit high-dword shift used by the decoders.
@ k_rar_hi_sh
High-dword shift for 64-bit sizes.
static bool internal_bytes_equal(const void *lhs, const void *rhs, size_t len)
Compare byte representations through compatible pointer types.
static const char *const s_tag_rar
Log tag for RAR-walker diagnostics.
rar4_bits_t
RAR4 header flag bits, block type, and method sentinel.
@ k_rar4_type_file
File-header block type ('t').
@ k_rar4_method_stor
METHOD value for STORE ('0').
@ k_rar4_flag_dirmsk
(flags & this) == this -> directory.
@ k_rar4_flag_large
64-bit HIGH_PACK/HIGH_UNP sizes present.
@ k_rar4_flag_long
ADD_SIZE present after the base header.
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.
rar4_layout_t
RAR4 block/file-header field byte offsets (from the block start).
@ k_rar4_off_method
METHOD byte (0x30 = store).
@ k_rar4_off_size
HEAD_SIZE uint16.
@ k_rar4_off_name
FILE_NAME start (no LARGE flag).
@ k_rar4_off_flags
HEAD_FLAGS uint16.
@ k_rar4_off_namesz
NAME_SIZE uint16.
@ k_rar4_off_add
ADD_SIZE / PACK_SIZE uint32.
@ k_rar4_off_attr
ATTR uint32 (fixed fields end +4).
@ k_rar4_base_len
Base header length before ADD_SIZE.
@ k_rar4_off_type
HEAD_TYPE byte.
@ k_rar4_off_unp
UNP_SIZE uint32.
@ k_rar4_off_name_large
FILE_NAME start (LARGE 64-bit).
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.
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 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 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.
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.
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 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_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.
rar5_bits_t
RAR5 header/file flag bits, method field placement, and type.
@ k_rar5_fflag_mtime
4-byte mtime field present.
@ k_rar5_hflag_extra
Extra-area-size vint present.
@ k_rar5_type_file
File-header block type.
@ k_rar5_fflag_dir
Member is a directory.
@ k_rar5_fflag_crc
4-byte data-CRC field present.
@ k_rar5_fixed_field
Fixed mtime / CRC field width, bytes.
@ k_rar5_method_mask
3-bit method mask after the shift.
@ k_rar5_hflag_data
Data-size vint present.
@ k_rar5_method_shift
Method occupies comp-info bits 7..9.
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.
rar_vint_bits_t
Bit layout of one RAR5 variable-length integer byte.
@ k_rar_vint_cont
Continuation flag within one vint byte.
@ k_rar_vint_data
Data bits mask within one vint byte.
@ k_rar_vint_bits
Data bits contributed per vint byte.
static void internal_copy_object(void *dst, const void *src, size_t len)
Copy an object representation through compatible byte-pointer types.
static uint16_t internal_le16(const uint8_t *p)
Decode a little-endian uint16 from two unaligned bytes.
Clean-room, read-only RAR archive walker (RAR4 + RAR5 headers, STORE data).
@ k_ra8_rar_vint_max
Max bytes in one RAR5 vint (64-bit value).
@ k_ra8_rar_sig5_len
"Rar!\x1A\x07\x01\x00" signature length (RAR5).
@ k_ra8_rar_sig4_len
"Rar!\x1A\x07\x00" marker length (RAR4).
@ k_ra8_rar_hdr_scratch
Per-block header read window (fixed fields).
size_t(* ra8_rar_read_fn)(void *ctx, uint64_t offset, void *buf, size_t len)
Seek+read backing over the RAR container bytes.
@ 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").
@ k_ra8_rar_method_compressed
Packed with a RAR compressor (not decoded).
@ k_ra8_rar_method_store
Uncompressed: data area is the file bytes.
Caller-owned zero-heap scratch for one ra8_rar5_decompress call.
One decoded RAR block: a file member, a directory, or a skipped block.
uint8_t method
ra8_rar_method_t (normalised; 0 = store).
uint8_t is_file
1 if this block is a file member header.
uint64_t unp_size
Unpacked length, bytes.
uint64_t data_off
Absolute offset of the member's data area.
uint64_t next_off
Absolute offset of the next block header.
uint16_t name_len
Name bytes copied into the caller buffer (clamped).
uint8_t is_dir
1 if the file member is a directory entry.
uint64_t pack_size
Packed (stored/compressed) data length, bytes.
One open RAR archive: the backing plus the detected generation.
uint64_t size
Container length in bytes.
uint64_t first_off
Offset of the first block past the signature.
void * ctx
Context for read.
ra8_rar_version_t version
Detected container generation.
ra8_rar_read_fn read
Byte reader over the container file.