From 7fb62d41d56897e959af9e8294cda50a2ca58336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ga=C5=88o?= Date: Thu, 29 Sep 2022 14:54:23 +0200 Subject: [PATCH] fatfsgen.py: omit cluster allocation when the file is empty --- components/fatfs/fatfs_utils/fs_object.py | 47 ++++++++++++++--------- components/fatfs/fatfsgen.py | 10 +++-- components/fatfs/fatfsparse.py | 6 ++- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/components/fatfs/fatfs_utils/fs_object.py b/components/fatfs/fatfs_utils/fs_object.py index 836d988ee37..307087cfb3d 100644 --- a/components/fatfs/fatfs_utils/fs_object.py +++ b/components/fatfs/fatfs_utils/fs_object.py @@ -201,11 +201,11 @@ def allocate_long_name_object(free_entry, name, extension, target_dir, - free_cluster, + free_cluster_id, entity_type, date, time): - # type: (Entry, str, str, Directory, Cluster, int, DATETIME, DATETIME) -> Tuple[Cluster, Entry, Directory] + # type: (Entry, str, str, Directory, int, int, DATETIME, DATETIME) -> Entry lfn_full_name: str = build_lfn_full_name(name, extension) lfn_unique_entry_order: int = build_lfn_unique_entry_name_order(target_dir.entities, name) lfn_short_entry_name: str = build_lfn_short_entry_name(name, extension, lfn_unique_entry_order) @@ -218,7 +218,7 @@ def allocate_long_name_object(free_entry, order: int = i + 1 blocks_: List[bytes] = split_name_to_lfn_entry_blocks(name_split_to_entry) lfn_names: List[bytes] = list(map(lambda x: x.lower(), blocks_)) - free_entry.allocate_entry(first_cluster_id=free_cluster.id, + free_entry.allocate_entry(first_cluster_id=free_cluster_id, entity_name=name, entity_extension=extension, entity_type=entity_type, @@ -227,14 +227,14 @@ def allocate_long_name_object(free_entry, lfn_checksum_=checksum, lfn_is_last=order == entries_count) free_entry = target_dir.find_free_entry() or target_dir.chain_directory() - free_entry.allocate_entry(first_cluster_id=free_cluster.id, + free_entry.allocate_entry(first_cluster_id=free_cluster_id, entity_name=lfn_short_entry_name[:MAX_NAME_SIZE], entity_extension=lfn_short_entry_name[MAX_NAME_SIZE:], entity_type=entity_type, lfn_order=Entry.SHORT_ENTRY_LN, date=date, time=time) - return free_cluster, free_entry, target_dir + return free_entry @staticmethod def _is_valid_sfn(name: str, extension: str) -> bool: @@ -248,14 +248,21 @@ def allocate_object(self, entity_type, object_timestamp_, path_from_root=None, - extension=''): - # type: (str, int, datetime, Optional[List[str]], str) -> Tuple[Cluster, Entry, Directory] + extension='', + is_empty=False): + # type: (str, int, datetime, Optional[List[str]], str, bool) -> Tuple[Cluster, Entry, Directory] """ Method finds the target directory in the path and allocates cluster (both the record in FAT and cluster in the data region) and entry in the specified directory """ - free_cluster: Cluster = self.fat.find_free_cluster() + + free_cluster: Optional[Cluster] = None + free_cluster_id = 0x00 + if not is_empty: + free_cluster = self.fat.find_free_cluster() + free_cluster_id = free_cluster.id + target_dir: Directory = self if not path_from_root else self.recursive_search(path_from_root, self) free_entry: Entry = target_dir.find_free_entry() or target_dir.chain_directory() @@ -263,7 +270,7 @@ def allocate_object(self, fatfs_time_ = (object_timestamp_.hour, object_timestamp_.minute, object_timestamp_.second) if not self.fatfs_state.long_names_enabled or self._is_valid_sfn(name, extension): - free_entry.allocate_entry(first_cluster_id=free_cluster.id, + free_entry.allocate_entry(first_cluster_id=free_cluster_id, entity_name=name, entity_extension=extension, date=fatfs_date_, @@ -271,25 +278,27 @@ def allocate_object(self, fits_short=True, entity_type=entity_type) return free_cluster, free_entry, target_dir - return self.allocate_long_name_object(free_entry=free_entry, - name=name, - extension=extension, - target_dir=target_dir, - free_cluster=free_cluster, - entity_type=entity_type, - date=fatfs_date_, - time=fatfs_time_) + return free_cluster, self.allocate_long_name_object(free_entry=free_entry, + name=name, + extension=extension, + target_dir=target_dir, + free_cluster_id=free_cluster_id, + entity_type=entity_type, + date=fatfs_date_, + time=fatfs_time_), target_dir def new_file(self, name: str, extension: str, path_from_root: Optional[List[str]], - object_timestamp_: datetime) -> None: + object_timestamp_: datetime, + is_empty: bool) -> None: free_cluster, free_entry, target_dir = self.allocate_object(name=name, extension=extension, entity_type=Directory.ATTR_ARCHIVE, path_from_root=path_from_root, - object_timestamp_=object_timestamp_) + object_timestamp_=object_timestamp_, + is_empty=is_empty) file: File = File(name=name, fat=self.fat, diff --git a/components/fatfs/fatfsgen.py b/components/fatfs/fatfsgen.py index 11f8dd4545a..9ba5b5e8078 100755 --- a/components/fatfs/fatfsgen.py +++ b/components/fatfs/fatfsgen.py @@ -78,7 +78,8 @@ def __init__(self, def create_file(self, name: str, extension: str = '', path_from_root: Optional[List[str]] = None, - object_timestamp_: datetime = FATFS_INCEPTION) -> None: + object_timestamp_: datetime = FATFS_INCEPTION, + is_empty: bool = False) -> None: """ Root directory recursively finds the parent directory of the new file, allocates cluster, entry and appends a new file into the parent directory. @@ -89,11 +90,13 @@ def create_file(self, name: str, :param extension: The extension of the file. :param path_from_root: List of strings containing names of the ancestor directories in the given order. :param object_timestamp_: is not None, this will be propagated to the file's entry + :param is_empty: True if there is no need to allocate any cluster, otherwise False """ self.root_directory.new_file(name=name, extension=extension, path_from_root=path_from_root, - object_timestamp_=object_timestamp_) + object_timestamp_=object_timestamp_, + is_empty=is_empty) def create_directory(self, name: str, path_from_root: Optional[List[str]] = None, @@ -159,7 +162,8 @@ def _generate_partition_from_folder(self, self.create_file(name=file_name, extension=extension, path_from_root=split_path[1:-1] or None, - object_timestamp_=object_timestamp) + object_timestamp_=object_timestamp, + is_empty=len(content) == 0) self.write_content(split_path[1:], content) elif os.path.isdir(real_path): if not is_dir: diff --git a/components/fatfs/fatfsparse.py b/components/fatfs/fatfsparse.py index f9bc82bd392..c5d3716c562 100755 --- a/components/fatfs/fatfsparse.py +++ b/components/fatfs/fatfsparse.py @@ -69,8 +69,10 @@ def traverse_folder_tree(directory_bytes_: bytes, entry_position_=i, lfn_checksum_=lfn_checksum(obj_['DIR_Name'] + obj_['DIR_Name_ext'])) if obj_['DIR_Attr'] == Entry.ATTR_ARCHIVE: - content_ = fat_.get_chained_content(cluster_id_=Entry.get_cluster_id(obj_), - size=obj_['DIR_FileSize']) + content_ = b'' + if obj_['DIR_FileSize'] > 0: + content_ = fat_.get_chained_content(cluster_id_=Entry.get_cluster_id(obj_), + size=obj_['DIR_FileSize']) with open(os.path.join(name, obj_name_), 'wb') as new_file: new_file.write(content_) elif obj_['DIR_Attr'] == Entry.ATTR_DIRECTORY: