def set_in_fat(self, value: int) -> None: """ Sets cluster in FAT to certain value. Firstly, we split the target value into 3 half bytes (max value is 0xfff). Then we could encounter two situations: 1. if the cluster index (indexed from zero) is even, we set the full byte computed by self.cluster_id_to_logical_position_in_bits and the second half of the consequent byte. Order of half bytes is 2, 1, 3. 2. if the cluster index is odd, we set the first half of the computed byte and the full consequent byte. Order of half bytes is 1, 3, 2. """ # value must fit into number of bits of the fat (12, 16 or 32) assert value <= (1 << self.fatfs_state.fatfs_type) - 1 half_bytes = split_by_half_byte_12_bit_little_endian(value) if self.fatfs_state.fatfs_type == FAT12: if self.fat_cluster_address % 8 == 0: self.fatfs_state.binary_image[ self.real_cluster_address] = build_byte( half_bytes[1], half_bytes[0]) self._set_second_half_byte(self.real_cluster_address + 1, half_bytes[2]) elif self.fat_cluster_address % 8 != 0: self._set_first_half_byte(self.real_cluster_address, half_bytes[0]) self.fatfs_state.binary_image[self.real_cluster_address + 1] = build_byte( half_bytes[2], half_bytes[1]) elif self.fatfs_state.fatfs_type == FAT16: self.fatfs_state.binary_image[self.real_cluster_address:self. real_cluster_address + 2] = Int16ul.build(value)
def _build_entry_long(names: List[bytes], checksum: int, order: int, is_last: bool, entity_type: int) -> bytes: """ Long entry starts with 1 bytes of the order, if the entry is the last in the chain it is or-masked with 0x40, otherwise is without change (or masked with 0x00). The following example shows 3 entries: first two (0x2000-0x2040) are long in the reverse order and the last one (0x2040-0x2060) is short. The entries define file name "thisisverylongfilenama.txt". 00002000: 42 67 00 66 00 69 00 6C 00 65 00 0F 00 43 6E 00 Bg.f.i.l.e...Cn. 00002010: 61 00 6D 00 61 00 2E 00 74 00 00 00 78 00 74 00 a.m.a...t...x.t. 00002020: 01 74 00 68 00 69 00 73 00 69 00 0F 00 43 73 00 .t.h.i.s.i...Cs. 00002030: 76 00 65 00 72 00 79 00 6C 00 00 00 6F 00 6E 00 v.e.r.y.l...o.n. 00002040: 54 48 49 53 49 53 7E 31 54 58 54 20 00 00 00 00 THISIS~1TXT..... 00002050: 21 00 00 00 00 00 00 00 21 00 02 00 15 00 00 00 !.......!....... """ order |= (0x40 if is_last else 0x00) long_entry: bytes = ( Int8ul.build(order) + # order of the long name entry (possibly masked with 0x40) names[0] + # first 5 characters (10 bytes) of the name part Int8ul.build(entity_type) + # one byte entity type ATTR_LONG_NAME Int8ul.build(0) + # one byte of zeros Int8ul.build(checksum) + # lfn_checksum defined in utils.py names[1] + # next 6 characters (12 bytes) of the name part Int16ul.build(0) + # 2 bytes of zeros names[2]) # last 2 characters (4 bytes) of the name part return long_entry
def split_by_half_byte_12_bit_little_endian(value: int) -> DATETIME: value_as_bytes: bytes = Int16ul.build(value) return value_as_bytes[0] & 0x0f, value_as_bytes[0] >> 4, value_as_bytes[ 1] & 0x0f
def split_by_half_byte_12_bit_little_endian( value: int) -> Tuple[int, int, int]: value_as_bytes = Int16ul.build(value) return value_as_bytes[0] & 0x0f, value_as_bytes[0] >> 4, value_as_bytes[ 1] & 0x0f