30 uint64_t loaded = UINT64_MAX;
32 for (uint32_t k = 0U; k < count; k++) {
41 sec[byte] = (uint8_t)(sec[
byte] & (uint8_t)~(uint8_t)(1U << bit));
88 for (uint32_t k = 0U; k < sc; k++) {
126 *out_match = matched;
166 const uint16_t* need,
175 const uint32_t total = 1U + sc;
176 if (total > max_pos) {
181 uint8_t matched = 0U;
204 while (*path ==
'/') {
291 uint64_t bmp_lba = 0U;
297 const uint8_t nofat =
300 const uint32_t count = (uint32_t)((size + cluster_bytes - 1U) / cluster_bytes);
303 uint32_t clus = first;
325 for (uint32_t k = 0U; k < count; k++) {
329 .entry_in_cluster = pos[k].
index,
386 const char* leaf =
nullptr;
429 const uint8_t* file_e,
430 const uint8_t* strm_e,
431 const uint16_t* new_name,
434 const uint32_t name_entries =
436 const uint32_t sec_count = 1U + name_entries;
438 for (uint32_t i = 0U; i < total; i++) {
447 for (uint32_t n = 0U; n < name_entries; n++) {
495 const char* old_path,
496 const char* new_path,
498 const char** out_old,
499 const char** out_new)
502 const char* ol =
nullptr;
508 const char* nl =
nullptr;
569 if (new_count == old_count) {
570 for (uint32_t k = 0U; k < new_count; k++) {
596 const char* old_name =
nullptr;
597 const char* new_name =
nullptr;
609 uint32_t new_len = 0U;
695 for (uint32_t k = 1U; k < sc; k++) {
776 if (name[0] ==
'\0') {
828 bool present =
false;
830 if ((err !=
k_ra8_ok) || !present) {
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ 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_exists
Item already exists – cannot create again.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_access_denied
Operation refused because the target is protected against it.
@ k_ra8_err_protocol_error
Protocol-level error (e.g.
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
@ 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.
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.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
uint32_t priv_rd32(const uint8_t *p)
Decode a little-endian uint32_t from a byte buffer.
ra8_err_t priv_fat_get(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t *out_value)
Fetch the FAT entry for cluster, returning the next-cluster value.
uint16_t priv_rd16(const uint8_t *p)
Decode a little-endian uint16_t from a byte buffer.
uint8_t priv_is_eoc(const ra8_fs_mount_t *m, uint32_t value)
Test whether value is an end-of-chain marker for this FAT type.
uint32_t priv_bps(const ra8_fs_mount_t *m)
One mounted volume's sector size in bytes.
void priv_byte_copy(uint8_t *dst, const uint8_t *src, uint32_t n)
Length-checked byte copy used in place of memcpy().
uint64_t priv_rd64(const uint8_t *p)
Decode a little-endian uint64_t from a byte buffer.
uint32_t priv_cluster_bytes(const ra8_fs_mount_t *m)
One mounted volume's cluster size in bytes.
ra8_err_t priv_write_sector(const ra8_fs_mount_t *m, uint64_t lba, const uint8_t *buf)
Write a single sector from a caller-provided buffer.
void priv_wr16(uint8_t *p, uint16_t v)
Encode a little-endian uint16_t into a byte buffer.
void priv_alloc_hint_lower(const ra8_fs_mount_t *m, uint32_t cluster)
Pull the next-free hint back to cluster if it is further on.
ra8_err_t priv_exfat_bitmap_lba(const ra8_fs_mount_t *m, uint64_t *out_lba)
Resolve the exFAT allocation bitmap's first LBA, once per mount.
uint8_t * priv_sec_io(void)
The IO-role sector buffer (leaf data / bitmap sector transfers).
ra8_err_t priv_exfat_resolve_parent(const ra8_fs_mount_t *m, const char *path, exfat_dir_t *out_parent, const char **out_leaf)
Resolve every component of path but the last.
ra8_err_t priv_exfat_find_dir_space(const ra8_fs_mount_t *m, const exfat_dir_t *dir, uint32_t need, uint32_t *out_clus, uint32_t *out_idx)
Find need consecutive free entry slots inside one directory cluster.
void priv_exfat_cursor_init(const exfat_dir_t *dir, exfat_cursor_t *out)
Aim a fresh cursor at the start of dir.
ra8_err_t priv_exfat_listdir(const ra8_fs_mount_t *m, const exfat_dir_t *dir, ra8_fs_listdir_cb_t cb, void *ctx)
Enumerate ONE directory of an exFAT volume.
ra8_err_t priv_exfat_unlink(const ra8_fs_mount_t *m, const char *path)
Delete a file on an exFAT volume, at any depth.
static uint32_t internal_exfat_build_rename_set(uint8_t *set, const uint8_t *file_e, const uint8_t *strm_e, const uint16_t *new_name, uint32_t new_len)
Assemble a file's directory set under a new name, keeping its data.
static ra8_err_t internal_exfat_put_entry(const ra8_fs_mount_t *m, const exfat_setpos_t *where, const uint8_t *entry)
Rewrite one 32-byte directory entry at a recorded position.
static ra8_err_t internal_exfat_rename_prepare(const ra8_fs_mount_t *m, const char *old_path, const char *new_path, exfat_dir_t *out_parent, const char **out_old, const char **out_new)
Resolve a rename's two paths to one shared parent plus two leaves.
static ra8_err_t internal_exfat_try_set(const ra8_fs_mount_t *m, exfat_cursor_t *cur, exfat_setpos_t at, const uint8_t *e, const uint16_t *need, uint32_t nlen, exfat_setpos_t *pos, uint32_t max_pos, uint32_t *out_count, uint8_t *file_copy, uint8_t *strm_copy)
Test one File entry set against a needle, recording its positions.
ra8_err_t priv_exfat_free_clusters(const ra8_fs_mount_t *m, const uint8_t *strm)
Implementation of priv_exfat_free_clusters() – run or chain, bitmap only.
ra8_err_t priv_exfat_dir_next(const ra8_fs_mount_t *m, exfat_cursor_t *cur, ra8_fs_dirent_t *out, bool *out_entry)
Copy the next visible exFAT directory entry from an existing cursor.
static ra8_err_t internal_exfat_list_emit(const ra8_fs_mount_t *m, exfat_cursor_t *cur, const uint8_t *e, ra8_fs_dirent_t *out, bool *out_entry)
Copy one File entry set into a stable directory value.
ra8_err_t priv_exfat_drop_set(const ra8_fs_mount_t *m, const exfat_setpos_t *pos, uint32_t count)
Retire an entry set by clearing the in-use bit on every entry.
static ra8_err_t internal_exfat_gather_name(const ra8_fs_mount_t *m, exfat_cursor_t *cur, uint32_t sc, uint32_t nlen, char *name, uint32_t cap)
Consume a set's Name entries and assemble the name as UTF-8.
ra8_err_t priv_exfat_find_set(const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *path, exfat_setpos_t *pos, uint32_t max_pos, uint32_t *out_count, uint8_t *file_copy, uint8_t *strm_copy)
Implementation of priv_exfat_find_set() – one aligned walk of a directory.
ra8_err_t priv_exfat_unlink_at(const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *name)
Delete a FILE named name from dir.
static ra8_err_t internal_exfat_place_rename(const ra8_fs_mount_t *m, const exfat_dir_t *parent, const exfat_setpos_t *pos, uint32_t old_count, const uint8_t *set, uint32_t bytes)
Write a rebuilt rename set, in place when it fits, else by relocation.
ra8_err_t priv_exfat_rename(const ra8_fs_mount_t *m, const char *old_path, const char *new_path)
Rename a root-level file on an exFAT volume, at any storable length.
static ra8_err_t internal_exfat_take_set(const ra8_fs_mount_t *m, exfat_cursor_t *cur, const uint16_t *name, uint32_t nlen, uint32_t sc, exfat_setpos_t *pos, uint8_t *strm_copy, uint8_t *out_match)
Consume a set's secondary entries, recording positions + matching.
ra8_err_t priv_exfat_bitmap_clear(const ra8_fs_mount_t *m, uint64_t bmp_lba, uint32_t clus, uint32_t count)
Clear a contiguous cluster run in the allocation bitmap.
ra8_err_t priv_exfat_next_entry(const ra8_fs_mount_t *m, exfat_cursor_t *cur, uint8_t *out)
Fetch the next 32-byte directory entry, following the cluster chain.
uint32_t priv_strlen(const char *s)
Length of a NUL-terminated string.
uint8_t priv_exfat_name_chunk_eq(const uint8_t *entry, const uint16_t *name, uint32_t pos, uint32_t nlen)
Compare one file-name entry's 15 UTF-16 units against a needle.
ra8_err_t priv_exfat_needle_units(const ra8_fs_mount_t *m, const char *name, uint16_t *out, uint32_t *out_units, ra8_err_t too_long)
Convert a leaf name to code units, mapping over-long to too_long.
ra8_err_t priv_exfat_find(const ra8_fs_mount_t *m, const exfat_dir_t *dir, const char *path, uint8_t *out_strm, uint8_t *out_attr)
Find a name in ONE exFAT directory.
uint16_t priv_exfat_set_checksum(const uint8_t *set, uint32_t bytes)
Compute the SetChecksum over a built directory entry set.
uint16_t priv_exfat_name_hash(const uint16_t *name, uint32_t nlen)
Compute the exFAT NameHash for a name in UTF-16 code units.
ra8_err_t priv_exfat_write_dir_set(const ra8_fs_mount_t *m, uint32_t cluster, uint32_t idx, const uint8_t *set, uint32_t bytes)
Write a pre-built entry set into consecutive directory entries.
ra8_err_t priv_exfat_bmp_switch(const ra8_fs_mount_t *m, uint64_t lba, uint64_t *loaded, uint8_t *sec)
Flush the cached bitmap sector and load lba if it changed.
Cross-TU shared declarations for the FAT/exFAT ra8_fs adapter.
void priv_exfat_file_stamp_access(uint8_t *file_entry)
Advance only an exFAT File entry's last-accessed stamp.
@ k_exfat_name_off
File-name entry character offset.
@ k_exfat_strm_off_dlen
Stream-ext DataLength (low 32 used).
@ k_exfat_strm_off_nlen
Stream-ext NameLength (UTF-16 units).
@ k_exfat_strm_off_clus
Stream-ext FirstCluster.
@ k_exfat_strm_off_flags
Stream-ext GeneralSecondaryFlags.
@ k_exfat_off_file_csum
File entry: SetChecksum (2 bytes).
@ k_exfat_secflag_no_fat
GeneralSecondaryFlags: NoFatChain.
@ k_exfat_name_per_entry
UTF-16 units per file-name entry.
@ k_exfat_entry_bytes
Directory entry size.
@ k_exfat_off_strm_hash
Stream entry: NameHash (2 bytes).
@ k_exfat_entry_eod
End-of-directory marker.
@ k_exfat_bit_shift
log2(8): cluster index -> byte.
@ k_exfat_entry_stream
Stream-extension entry.
@ k_exfat_off_file_attr
File entry: FileAttributes (2 bytes).
@ k_exfat_off_file_secnt
File entry: SecondaryCount.
@ k_exfat_name_u8_cap
That name in UTF-8: 3 * 64, plus a NUL.
@ k_exfat_max_set_bytes
(2 + ceil(64/15)) * 32 = 7 entries.
@ k_exfat_scan_limit
Max dir entries scanned (P10 bound).
@ k_exfat_attr_read_only
FileAttributes: read-only.
@ k_exfat_attr_directory
FileAttributes: directory.
@ k_exfat_bit_mask
Bit index within a bitmap byte.
@ k_exfat_entry_name
File-name entry.
@ k_exfat_name_cap
Longest name we store, in UTF-16 units.
@ k_exfat_inuse_bit
Directory entry type bit 7 = in use.
@ k_exfat_entry_file
File directory entry.
@ k_exfat_set_max_entries
1 File + 1 Stream + 17 Name entries.
@ k_cluster_first_data
Cluster numbers start at 2.
void(* ra8_fs_listdir_cb_t)(const char *name, uint8_t attr, uint64_t size, void *ctx)
Callback invoked once per directory entry by ra8_fs_listdir().
ra8_err_t priv_utf16_to_utf8(const uint16_t *in, uint32_t units, char *out, uint32_t cap)
Convert UTF-16LE code units into a NUL-terminated UTF-8 name.
Linear cursor over a directory's 32-byte entries.
uint32_t scanned
Total entries read (P10 bound).
uint32_t cluster
Current directory cluster.
uint32_t entry_in_cluster
Next entry index within the cluster.
Identifies the exFAT directory a lookup, scan or link operates in.
uint32_t cluster
First cluster of the directory.
Directory position (cluster + entry index) of one 32-byte entry.
uint32_t index
Entry index within that cluster (0-based).
uint32_t cluster
Directory cluster holding the entry.
Stable directory-entry value copied by ra8_fs_dir_next.
char name[k_ra8_fs_dir_name_cap]
NUL-terminated visible leaf.
uint8_t attr
On-disk FAT attributes.
uint64_t size_bytes
File bytes; zero for dirs.
Cached parse of one mounted FAT volume.
uint32_t count_of_clusters
Per MS spec: data_sectors / SPC.