|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
FAT 8.3 short-name pack/unpack and directory walking. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_fs.h"#include "ra8_fs_fat_internal.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_fs_name_local_t : uint16_t { k_lfn_space = 0x20U , k_lfn_del = 0x7FU , k_case_seen_upper = 0x01U , k_case_seen_lower = 0x02U , k_case_seen_mixed = 0x03U , k_alias_radix = 10U , k_alias_digits_max = 6U } |
| Small constants used only by this translation unit's name analysis. More... | |
Functions | |
| char | priv_to_upper (char c) |
| Convert "FILE.TXT" (caller-supplied path) to packed 11-byte 8.3. | |
| static uint8_t | internal_pack_base (const char **path_io, uint8_t *out11) |
| Pack the base portion of a path into out11[0..7]. | |
| static uint8_t | internal_pack_ext (const char *path, uint8_t *out11) |
| Pack the extension portion of a path into out11[8..10]. | |
| uint8_t | priv_path_to_83 (const char *path, uint8_t *out11) |
| Convert a "/FILE.TXT"-style path to packed 11-byte 8.3 form. | |
| static char | internal_case_apply (char c, uint8_t lower) |
| Lower-case one ASCII character when a DIR_NTRes flag asks for it. | |
| void | priv_83_to_str (const uint8_t *in11, uint8_t ntres, char *out13) |
| Unpack on-disk 11-byte 8.3 name into NUL-terminated "NAME.EXT". | |
| static uint8_t | internal_unit_in_set (uint16_t u, const char *set) |
Does u appear in the NUL-terminated ASCII set set? | |
| static uint8_t | internal_unit_is_lfn_legal (uint16_t u) |
Is u a code unit a VFAT long name is allowed to hold? | |
| static uint8_t | internal_unit_is_83_legal (uint16_t u) |
Is c usable verbatim inside a packed 8.3 short name? | |
| static uint32_t | internal_name_dot_index (const uint16_t *leaf, uint32_t n) |
Index of the field-separating dot, or n when there is none. | |
| static uint8_t | internal_name_is_83 (const uint16_t *leaf, uint32_t n) |
Can leaf be stored as a packed 8.3 name without losing anything? | |
| static void | internal_case_observe (const uint16_t *leaf, uint32_t from, uint32_t to, uint8_t *seen) |
| Fold one half of a name into "has upper" / "has lower" observations. | |
| static ra8_fs_name_kind_t | internal_name_case_kind (const uint16_t *leaf, uint32_t n, uint8_t *out_ntres) |
| Decide the case shape of an 8.3-representable leaf. | |
| ra8_fs_name_kind_t | priv_name_classify (const char *leaf, uint16_t *out_units, uint32_t *out_nunits, uint8_t *out83, uint8_t *out_ntres) |
| Decide whether a leaf needs one entry, one entry plus case flags, or a chain. | |
| static uint8_t | internal_alias_map_unit (uint16_t u) |
| Map one long-name character into the short-name character set. | |
| static uint32_t | internal_alias_collect (const uint16_t *leaf, uint32_t from, uint32_t to, uint32_t cap, uint8_t *out) |
Collect up to cap alias characters from from up to to. | |
| static uint32_t | internal_alias_ext_dot (const uint16_t *leaf, uint32_t n) |
Index of the dot that separates the alias extension, or n if none. | |
| static uint32_t | internal_alias_digits (uint32_t tail) |
Decimal digit count of tail (1..k_lfn_alias_tail_max). | |
| void | priv_lfn_alias_basis (const uint16_t *leaf, uint32_t n, uint32_t tail, uint8_t *out11) |
| Derive the LONGNA~N.TXT 8.3 alias a long name is filed under. | |
| static void | internal_dir_walk_init_root (const ra8_fs_mount_t *m, dir_walk_t *w) |
| Initialise a walker that iterates the volume root directory. | |
| void | priv_dir_walk_init_loc (const ra8_fs_mount_t *m, const dir_loc_t *loc, dir_walk_t *w) |
| Initialise a directory walker for an arbitrary directory location. | |
| ra8_err_t | priv_dir_walk_next_sector (const ra8_fs_mount_t *m, dir_walk_t *w, uint8_t *out_eod) |
| Advance the walker to the next sector. | |
| ra8_err_t | priv_dir_find (const ra8_fs_mount_t *m, const dir_loc_t *loc, const uint8_t *name83, uint64_t *out_lba, uint32_t *out_entry_off, uint8_t out_entry[k_ra8_fs_dir_entry_bytes]) |
| Find a directory entry by 8.3 name within a given directory. | |
FAT 8.3 short-name pack/unpack and directory walking.
8.3 short-name encode/decode, the directory-walk cursor, and the short-name directory lookup primitives for the ra8_fs FAT adapter.
Definition in file ra8_fs_fat_name.c.
| enum ra8_fs_name_local_t : uint16_t |
Small constants used only by this translation unit's name analysis.
The case observations are a two-bit set rather than two booleans so that "mixed" is a value the code can name, instead of a conjunction the reader has to work out at each test.
| Enumerator | |
|---|---|
| k_lfn_space | Lowest character code a long name may hold. |
| k_lfn_del | DEL: a control code, not a name character. |
| k_case_seen_upper | An upper-case letter was seen. |
| k_case_seen_lower | A lower-case letter was seen. |
| k_case_seen_mixed | Both were: no NTRes flag can express it. |
| k_alias_radix | The alias tail is written in decimal. |
| k_alias_digits_max | Digits in k_lfn_alias_tail_max. |
Definition at line 33 of file ra8_fs_fat_name.c.
|
static |
Collect up to cap alias characters from from up to to.
Spaces and dots are dropped rather than mapped – the FAT specification removes them before translating – so My Report.v2 contributes MYREPORT and not MY_REPORT.
| [in] | leaf | Leaf component's code units. |
| [in] | from | First index to read. |
| [in] | to | One past the last index to read. |
| [in] | cap | Maximum characters to emit. |
| [out] | out | Receives up to cap mapped characters. |
| 0..cap | How many of out were filled. |
leaf and out are non-NULL; out holds cap bytes. from is at most to. out bytes were written. leaf is not modified.out.Definition at line 685 of file ra8_fs_fat_name.c.
References internal_alias_map_unit().
Referenced by priv_lfn_alias_basis().
|
static |
Decimal digit count of tail (1..k_lfn_alias_tail_max).
Drives how much of the basis name survives: the numeric tail and its ~ must fit inside the eight-character base field, so ~1 leaves six characters and ~999999 leaves one.
| [in] | tail | Alias sequence number. |
| 1..6 | Digit count for the supported range. |
tail is at least 1. tail is at most k_lfn_alias_tail_max. Definition at line 756 of file ra8_fs_fat_name.c.
References k_alias_digits_max, and k_alias_radix.
Referenced by priv_lfn_alias_basis().
|
static |
Index of the dot that separates the alias extension, or n if none.
The LAST dot, and only when it has at least one character on each side: a leading dot (.profile) names no extension, and a trailing one (notes.) supplies no characters for it.
| [in] | leaf | Leaf component's code units. |
| [in] | n | Length of leaf in code units. |
n when the alias has no extension. | 1..n-2 | The separating dot. |
| n | No usable extension. |
leaf is non-NULL and holds at least n units. n is non-zero. leaf is not modified. n or a valid interior index.Definition at line 723 of file ra8_fs_fat_name.c.
Referenced by priv_lfn_alias_basis().
|
static |
Map one long-name character into the short-name character set.
Upper-cases, then substitutes _ for anything an 8.3 name cannot hold. This is the FAT specification's "Basis-Name Generation Algorithm" step that makes the alias representable at all: without it a name like Design (final).txt would generate an alias with a space and parentheses in it, which no 8.3 reader accepts.
| [in] | u | Code unit from the caller's long name. |
| '_' | u is not legal in an 8.3 name – which now includes every unit above ASCII, exactly as VFAT does for a character its OEM code page cannot represent. |
| other | The upper-cased u. |
u passed ::priv_unit_is_lfn_legal(). Definition at line 646 of file ra8_fs_fat_name.c.
References internal_unit_is_83_legal(), k_lfn_del, and priv_to_upper().
Referenced by internal_alias_collect().
|
static |
Lower-case one ASCII character when a DIR_NTRes flag asks for it.
The FAT directory entry always stores the upper-case 8.3 form; the case a user typed survives in two bits of DIR_NTRes, one for the base and one for the extension. This applies the bit that governs the half of the name the character came from.
| [in] | c | Character straight out of the packed 11-byte name field. |
| [in] | lower | Non-zero when this half of the name is flagged lower case. |
| 'a'..'z' | c was 'A'..'Z' and lower was set. |
| c | Otherwise, unchanged. |
c is one byte of a packed 8.3 name field. lower is 0 or non-zero; no other interpretation is placed on it. lower is.Definition at line 200 of file ra8_fs_fat_name.c.
Referenced by priv_83_to_str().
|
static |
Fold one half of a name into "has upper" / "has lower" observations.
Walks leaf from from up to (not including) to and ORs a bit into seen for each case class present. Digits and punctuation set neither, so "IMG_01" is upper-only and "01" is neither, which is what makes a case-flagged short name possible for both.
| [in] | leaf | Leaf component's code units. |
| [in] | from | First index to inspect. |
| [in] | to | One past the last index to inspect. |
| [in,out] | seen | Bit 0 set when an upper-case letter is seen, bit 1 when a lower-case one is. |
leaf is non-NULL and holds at least to units. from is at most to and seen is non-NULL. seen has only bits it already had, plus the ones observed here. leaf is not modified.seen.Definition at line 504 of file ra8_fs_fat_name.c.
References k_case_seen_lower, and k_case_seen_upper.
Referenced by internal_name_case_kind().
|
static |
Initialise a walker that iterates the volume root directory.
FAT12/16 use a fixed root region; FAT32 uses a cluster chain rooted at m->root_cluster.
| [in] | m | Mount providing geometry and FAT type. |
| [out] | w | Walker cursor to initialise. |
Definition at line 831 of file ra8_fs_fat_name.c.
References dir_walk_t::cluster, dir_walk_t::cluster_hops, dir_walk_t::cur_lba, dir_walk_t::entry_idx, ra8_fs_mount_t::first_root_lba, dir_walk_t::fixed_remaining, dir_walk_t::is_root_fixed, k_ra8_fs_dir_entry_bytes, k_ra8_fs_type_fat32, priv_bps(), priv_cluster_to_lba(), ra8_fs_mount_t::root_cluster, ra8_fs_mount_t::root_entries, dir_walk_t::sector_in_cluster, and ra8_fs_mount_t::type.
Referenced by priv_dir_walk_init_loc().
|
static |
Decide the case shape of an 8.3-representable leaf.
A half of the name that is all one case round-trips through a DIR_NTRes bit; a half that mixes cases does not, and the whole name then needs a long-name chain to survive. The two halves are judged independently, exactly as the two flag bits are.
| [in] | leaf | Leaf component's units, already known to pack to 8.3. |
| [in] | n | Length of leaf in code units. |
| [out] | out_ntres | Receives the DIR_NTRes byte to store. |
| k_name_kind_short | One entry plus out_ntres suffices. |
| k_name_kind_long | A half mixes cases; a chain is required. |
leaf and out_ntres are non-NULL; n is leaf's length. leaf. out_ntres is written on both outcomes (0 on the long one). leaf is not modified.Definition at line 545 of file ra8_fs_fat_name.c.
References internal_case_observe(), internal_name_dot_index(), k_case_seen_lower, k_case_seen_mixed, k_name_kind_long, k_name_kind_short, k_ntres_base_lower, and k_ntres_ext_lower.
Referenced by priv_name_classify().
|
static |
Index of the field-separating dot, or n when there is none.
The LAST dot, because that is the one an extension would follow. A name holding more than one is not 8.3 anyway: the earlier dots then sit inside the base, where ::priv_unit_is_83_legal() refuses them, so the rejection needs no special case here.
| [in] | leaf | Leaf component's code units (no slashes). |
| [in] | n | Length of leaf in code units. |
n when there is none. | 0..n-1 | The last dot's index. |
| n | There is no dot. |
leaf is non-NULL and holds at least n units. n is at most k_lfn_write_max. leaf is not modified. n units.Definition at line 415 of file ra8_fs_fat_name.c.
Referenced by internal_name_case_kind(), and internal_name_is_83().
|
static |
Can leaf be stored as a packed 8.3 name without losing anything?
Requires a 1..8 character base, a 0 or 1..3 character extension, and every character legal in a short name. A second dot is caught by that last rule rather than by a count of its own: everything before the LAST dot is the base, so an earlier one is simply a character the base may not hold. A trailing dot ("REPORT.") fails the extension test and is therefore stored as a long name, which is the only way to read it back as it was written.
| [in] | leaf | Leaf component's code units (no slashes). |
| [in] | n | Length of leaf in code units. |
| 1U | leaf packs to 8.3 losslessly, up to case. |
| 0U | leaf needs a long-name chain. |
leaf is non-NULL and holds at least n units. n is non-zero and at most k_lfn_write_max. leaf is not modified. Definition at line 454 of file ra8_fs_fat_name.c.
References internal_name_dot_index(), internal_unit_is_83_legal(), k_filename_base_len, and k_filename_ext_len.
Referenced by priv_name_classify().
|
static |
Pack the base portion of a path into out11[0..7].
Returns 0 on error.
Reads characters from *path_io up to a . or NUL, upper-cases them, and writes them into out11[0..7].
| [in,out] | path_io | Cursor into the input path; advanced on success. |
| [out] | out11 | 11-byte buffer; first 8 bytes are written. |
| 1 | Base name packed. |
| 0 | Base too long or zero-length. |
Definition at line 87 of file ra8_fs_fat_name.c.
References k_filename_base_len, k_lfn_del, and priv_to_upper().
Referenced by priv_path_to_83().
|
static |
Pack the extension portion of a path into out11[8..10].
Returns 0 on error.
If *path is not ., returns success with no writes.
| [in] | path | Cursor at the . or terminator following the base. |
| [out] | out11 | 11-byte buffer; bytes 8..10 are written. |
| 1 | Extension packed (or absent). |
| 0 | Extension too long. |
Definition at line 129 of file ra8_fs_fat_name.c.
References k_filename_base_len, k_filename_ext_len, k_lfn_del, and priv_to_upper().
Referenced by priv_path_to_83().
|
static |
Does u appear in the NUL-terminated ASCII set set?
Linear scan, bounded by k_lfn_write_max so the loop has a static upper limit even though both call sites pass a string literal (NASA Power of 10 Rule 2). Every set here is ASCII, so a unit above that range simply never matches – no widening is needed.
| [in] | u | Code unit to look for. |
| [in] | set | NUL-terminated set of characters. |
| 1U | u is in set. |
| 0U | u is not in set. |
set is non-NULL and NUL-terminated. set is shorter than k_lfn_write_max characters. u nor set is modified. Definition at line 281 of file ra8_fs_fat_name.c.
References k_lfn_write_max.
Referenced by internal_unit_is_83_legal(), and internal_unit_is_lfn_legal().
|
static |
Is c usable verbatim inside a packed 8.3 short name?
Stricter than ::priv_unit_is_lfn_legal() by the extra short-name exclusions, by the dot – which in an 8.3 name is a field separator rather than a character – and by the ASCII cut, which belongs here rather than there: a packed 8.3 field is an OEM-code-page byte and this adapter only writes ASCII into one, while a long name has the whole of UTF-16 available to it.
| [in] | u | Candidate code unit. |
| 1U | u may appear in the base or extension field. |
| 0U | u may not; a name containing it needs a long-name chain. |
u already passed ::priv_unit_is_lfn_legal(). u is one code unit of a caller-supplied leaf component. u.Definition at line 370 of file ra8_fs_fat_name.c.
References internal_unit_in_set(), and k_lfn_del.
Referenced by internal_alias_map_unit(), and internal_name_is_83().
|
static |
Is u a code unit a VFAT long name is allowed to hold?
Rejects the control range, DEL, and the explicit illegal set from the FAT specification. Everything above ASCII is ALLOWED: the slots store UTF-16 and this adapter now reads them back as such, so the old "at or above DEL" cut – which existed only because the reader substituted ? for those units – would refuse names the format and the reader both handle (#606).
| [in] | u | Candidate code unit. |
| 1U | u may appear in a long name. |
| 0U | u may not; the whole leaf is rejected. |
u is one code unit of a caller-supplied leaf component. u.Definition at line 322 of file ra8_fs_fat_name.c.
References internal_unit_in_set(), k_lfn_del, and k_lfn_space.
Referenced by priv_name_classify().
| void priv_83_to_str | ( | const uint8_t * | in11, |
| uint8_t | ntres, | ||
| char * | out13 ) |
Unpack on-disk 11-byte 8.3 name into NUL-terminated "NAME.EXT".
Trims trailing space pad in the base portion, restores the 0x05 -> 0xE5 kanji escape, and emits the dot + extension only when the extension is non-empty. The two DIR_NTRes case flags are applied as they are unpacked, so an entry written for data.log – stored upper-case with both flags set – reads back as data.log rather than DATA.LOG. Pass 0 for ntres to get the raw upper-case form.
| [in] | in11 | Packed 11-byte name. |
| [in] | ntres | The entry's DIR_NTRes byte (0 when it has none). |
| [out] | out13 | Buffer of at least 13 bytes (8 + . + 3 + NUL). |
Definition at line 216 of file ra8_fs_fat_name.c.
References internal_case_apply(), k_dir_marker_free_used, k_dir_marker_kanji_e5, k_filename_base_len, k_filename_ext_len, k_ntres_base_lower, and k_ntres_ext_lower.
Referenced by internal_fat_dir_scan_sector(), and internal_listdir_visit_sector().
| ra8_err_t priv_dir_find | ( | const ra8_fs_mount_t * | m, |
| const dir_loc_t * | loc, | ||
| const uint8_t * | name83, | ||
| uint64_t * | out_lba, | ||
| uint32_t * | out_entry_off, | ||
| uint8_t | out_entry[k_ra8_fs_dir_entry_bytes] ) |
Find a directory entry by 8.3 name within a given directory.
Walks the directory loc (root or a subdirectory) and matches on the packed 11-byte name field. Skips LFN entries (attr 0x0F) and deleted slots.
| [in] | m | Mount providing geometry and backend. |
| [in] | loc | Directory to search (root or a subdirectory). |
| [in] | name83 | Packed 11-byte name. |
| [out] | out_lba | Sector containing the entry. |
| [out] | out_entry_off | Byte offset within the sector. |
| [out] | out_entry | 32 bytes of the entry payload. |
| k_ra8_ok | Entry found; out parameters populated. |
| k_ra8_err_not_found | End-of-directory reached without a match. |
| k_ra8_err_* | Backend error. |
Definition at line 911 of file ra8_fs_fat_name.c.
References dir_walk_t::cur_lba, k_dir_marker_free_perm, k_dir_marker_free_used, k_dir_name_field_len, k_dir_off_attr, k_dir_off_name, k_ra8_err_not_found, k_ra8_fs_attr_lfn, k_ra8_fs_dir_entry_bytes, k_ra8_ok, priv_byte_copy(), priv_byte_equal(), priv_dir_eps(), priv_dir_walk_init_loc(), priv_dir_walk_next_sector(), priv_read_sector(), and priv_sec_walk().
Referenced by internal_alias_unique(), internal_setattr_fat(), internal_stat_fat(), internal_utime_fat(), and priv_dir_lookup_any().
| void priv_dir_walk_init_loc | ( | const ra8_fs_mount_t * | m, |
| const dir_loc_t * | loc, | ||
| dir_walk_t * | w ) |
Initialise a directory walker for an arbitrary directory location.
Dispatches to priv_dir_walk_init_root for the root, or sets up a plain cluster-chain walk starting at loc->cluster for a subdirectory (the same machinery the FAT32 root uses, so priv_dir_walk_next_sector follows the chain unchanged).
| [in] | m | Mount providing geometry and FAT type. |
| [in] | loc | Directory to walk (root or a subdirectory cluster). |
| [out] | w | Walker cursor to initialise. |
Definition at line 853 of file ra8_fs_fat_name.c.
References dir_loc_t::cluster, dir_walk_t::cluster, dir_walk_t::cluster_hops, dir_walk_t::cur_lba, dir_walk_t::entry_idx, dir_walk_t::fixed_remaining, internal_dir_walk_init_root(), dir_loc_t::is_root, dir_walk_t::is_root_fixed, priv_cluster_to_lba(), and dir_walk_t::sector_in_cluster.
Referenced by internal_dir_collect_chain(), internal_dir_grow(), internal_dir_is_empty(), internal_fat_find_free_root(), internal_fat_find_vol_id(), priv_dir_find(), priv_dir_find_free_run(), and priv_dir_find_long().
| ra8_err_t priv_dir_walk_next_sector | ( | const ra8_fs_mount_t * | m, |
| dir_walk_t * | w, | ||
| uint8_t * | out_eod ) |
Advance the walker to the next sector.
For fixed-region roots simply increments the LBA. For cluster-chain roots advances within the cluster, then follows the FAT chain when the cluster is exhausted.
| [in] | m | Mount providing geometry and backend. |
| [in,out] | w | Walker cursor to advance. |
| [out] | out_eod | Set to 1 if end-of-directory reached, else 0. |
| k_ra8_ok | Walker advanced (or EOD signalled in *out_eod). |
| k_ra8_err_protocol_error | Cluster-chain cycle detected (corrupt FAT). |
| k_ra8_err_* | Backend error from a FAT read. |
Definition at line 869 of file ra8_fs_fat_name.c.
References dir_walk_t::cluster, dir_walk_t::cluster_hops, ra8_fs_mount_t::count_of_clusters, dir_walk_t::cur_lba, dir_walk_t::entry_idx, dir_walk_t::fixed_remaining, dir_walk_t::is_root_fixed, k_ra8_err_protocol_error, k_ra8_ok, priv_cluster_to_lba(), priv_fat_get(), priv_is_eoc(), dir_walk_t::sector_in_cluster, and ra8_fs_mount_t::sectors_per_cluster.
Referenced by internal_dir_collect_chain(), internal_dir_grow(), internal_dir_is_empty(), internal_fat_dir_advance_sector(), internal_fat_find_free_root(), internal_fat_find_vol_id(), internal_slot_advance(), priv_dir_find(), priv_dir_find_free_run(), and priv_dir_find_long().
| void priv_lfn_alias_basis | ( | const uint16_t * | leaf, |
| uint32_t | n, | ||
| uint32_t | tail, | ||
| uint8_t * | out11 ) |
Derive the LONGNA~N.TXT 8.3 alias a long name is filed under.
The Microsoft FAT specification's basis-name generation: spaces and all but the last interior dot are dropped, the remainder is upper-cased with anything an 8.3 field cannot hold replaced by _, and the base is truncated to leave room for ~ plus the decimal tail. A leaf that contributes no base characters at all ("...") yields _, because an 8.3 name may not have an empty base.
Every unit above ASCII maps to _, which is what VFAT does with a character its OEM code page cannot express. Working from CODE UNITS rather than UTF-8 bytes is what makes that one underscore per character instead of one per byte.
| [in] | leaf | Long name being filed, as UTF-16 code units. |
| [in] | n | Number of units in leaf. |
| [in] | tail | Sequence number, 1..k_lfn_alias_tail_max. |
| [out] | out11 | Receives the packed, space-padded 11-byte alias. |
leaf and out11 are non-NULL; out11 holds k_max_8_3_name bytes. tail is at least 1 and at most k_lfn_alias_tail_max. out11 is a legal 8.3 character or a space pad. out11 always contains a ~ followed by tail in decimal.Definition at line 769 of file ra8_fs_fat_name.c.
References internal_alias_collect(), internal_alias_digits(), internal_alias_ext_dot(), k_alias_radix, k_filename_base_len, k_filename_ext_len, and k_max_8_3_name.
Referenced by internal_alias_unique().
| ra8_fs_name_kind_t priv_name_classify | ( | const char * | leaf, |
| uint16_t * | out_units, | ||
| uint32_t * | out_nunits, | ||
| uint8_t * | out83, | ||
| uint8_t * | out_ntres ) |
Decide whether a leaf needs one entry, one entry plus case flags, or a chain.
Decodes leaf from UTF-8 into the code units the on-disk chain carries, which is where a malformed encoding is refused – an over-long form, a raw surrogate, a truncated sequence – and then rejects anything a long name may not hold at all (an empty leaf, one longer than k_lfn_write_max CODE UNITS, a control character, or one of the FAT specification's illegal characters). Characters above ASCII are legal: the slots are UTF-16 and the reader returns them as such. What is left is an 8.3 name if it has a 1..8 character base, a 0 or 1..3 character extension, at most one dot, and no character an 8.3 field cannot hold – a space and a second dot are both enough to disqualify it however short it is. An 8.3 name whose base or extension is all one case round-trips through DIR_NTRes; one that MIXES cases in either half does not, and is reported as needing a chain.
| [in] | leaf | Leaf component (no slashes), NUL-terminated UTF-8. |
| [out] | out_units | Receives leaf as UTF-16LE code units. |
| [out] | out_nunits | Receives how many units that is. |
| [out] | out83 | Receives the packed 11-byte name on a short verdict. |
| [out] | out_ntres | Receives the DIR_NTRes case flags (0 unless short). |
| k_name_kind_short | out83 and out_ntres are ready to write. |
| k_name_kind_long | A chain plus a generated alias is required. |
| k_name_kind_invalid | Empty, over-long, illegal, or not valid UTF-8. |
out_units addresses k_lfn_write_max writable units and out83 addresses k_max_8_3_name writable bytes. out_ntres and out_nunits are written on every outcome. leaf is not modified.Definition at line 571 of file ra8_fs_fat_name.c.
References internal_name_case_kind(), internal_name_is_83(), internal_unit_is_lfn_legal(), k_lfn_write_max, k_name_kind_invalid, k_name_kind_long, k_ra8_ok, priv_path_to_83(), and priv_utf8_to_utf16().
Referenced by priv_dir_reserve().
| uint8_t priv_path_to_83 | ( | const char * | path, |
| uint8_t * | out11 ) |
Convert a "/FILE.TXT"-style path to packed 11-byte 8.3 form.
Strips leading /, pre-pads out11 with spaces, calls the base/extension packers, and rewrites a leading 0xE5 byte to the kanji escape 0x05.
| [in] | path | NUL-terminated input path. Must be non-NULL. |
| [out] | out11 | 11-byte output buffer. Must be non-NULL. |
| 1 | Name packed into out11. |
| 0 | NULL input or name violates 8.3 rules. |
Definition at line 150 of file ra8_fs_fat_name.c.
References internal_pack_base(), internal_pack_ext(), and k_max_8_3_name.
Referenced by internal_setattr_fat(), internal_stat_fat(), internal_utime_fat(), priv_dir_lookup_any(), and priv_name_classify().
| char priv_to_upper | ( | char | c | ) |
Convert "FILE.TXT" (caller-supplied path) to packed 11-byte 8.3.
Upper-case ASCII conversion (returns input unchanged if not lowercase).
Result is space-padded as on-disk. Lower-case input is upper-cased. Returns 0 on bad name (>8 base, >3 ext, missing chars), 1 on success.
Definition at line 56 of file ra8_fs_fat_name.c.
Referenced by internal_alias_map_unit(), internal_pack_base(), and internal_pack_ext().