|
Data Structures | |
| struct | fat_dir_entry_struct |
Defines | |
| #define | FAT_ATTRIB_READONLY (1 << 0) |
| #define | FAT_ATTRIB_HIDDEN (1 << 1) |
| #define | FAT_ATTRIB_SYSTEM (1 << 2) |
| #define | FAT_ATTRIB_VOLUME (1 << 3) |
| #define | FAT_ATTRIB_DIR (1 << 4) |
| #define | FAT_ATTRIB_ARCHIVE (1 << 5) |
| #define | FAT_SEEK_SET 0 |
| #define | FAT_SEEK_CUR 1 |
| #define | FAT_SEEK_END 2 |
Functions | |
| uint8_t | fat_get_dir_entry_of_path (struct fat_fs_struct *fs, const char *path, struct fat_dir_entry_struct *dir_entry) |
| struct fat_file_struct * | fat_open_file (struct fat_fs_struct *fs, const struct fat_dir_entry_struct *dir_entry) |
| void | fat_close_file (struct fat_file_struct *fd) |
| intptr_t | fat_read_file (struct fat_file_struct *fd, uint8_t *buffer, uintptr_t buffer_len) |
| intptr_t | fat_write_file (struct fat_file_struct *fd, const uint8_t *buffer, uintptr_t buffer_len) |
| uint8_t | fat_seek_file (struct fat_file_struct *fd, int32_t *offset, uint8_t whence) |
| uint8_t | fat_resize_file (struct fat_file_struct *fd, uint32_t size) |
| uint8_t | fat_create_file (struct fat_dir_struct *parent, const char *file, struct fat_dir_entry_struct *dir_entry) |
| uint8_t | fat_delete_file (struct fat_fs_struct *fs, struct fat_dir_entry_struct *dir_entry) |
| #define FAT_ATTRIB_ARCHIVE (1 << 5) |
| #define FAT_ATTRIB_DIR (1 << 4) |
The file is a directory.
Definition at line 48 of file fat.h.
Referenced by fat_create_dir(), fat_get_dir_entry_of_path(), fat_open_dir(), fat_open_file(), WaspSD::getAttributes(), WaspSD::isDir(), WaspSD::isFile(), and WaspSD::ls().
| #define FAT_ATTRIB_READONLY (1 << 0) |
The file is read-only.
Definition at line 40 of file fat.h.
Referenced by WaspSD::getAttributes(), and WaspSD::ls().
| #define FAT_ATTRIB_VOLUME (1 << 3) |
| #define FAT_SEEK_CUR 1 |
The given offset is relative to the current read/write position.
Definition at line 55 of file fat.h.
Referenced by fat_seek_file().
| #define FAT_SEEK_END 2 |
The given offset is relative to the end of the file.
Definition at line 57 of file fat.h.
Referenced by fat_seek_file().
| #define FAT_SEEK_SET 0 |
The given offset is relative to the beginning of the file.
Definition at line 53 of file fat.h.
Referenced by WaspSD::cat(), WaspSD::catBin(), fat_seek_file(), and WaspSD::writeSD().
| void fat_close_file | ( | struct fat_file_struct * | fd | ) |
Closes a file.
| [in] | fd | The file handle of the file to close. |
Definition at line 964 of file fat.c.
References fat_file_struct::dir_entry, fat_write_dir_entry(), and fat_file_struct::fs.
Referenced by WaspSD::cat(), WaspSD::catBin(), WaspSD::catln(), WaspSD::closeFile(), WaspSD::indexOf(), WaspSD::numln(), and WaspSD::writeSD().
00965 { 00966 if(fd) 00967 { 00968 #if FAT_DELAY_DIRENTRY_UPDATE 00969 /* write directory entry */ 00970 fat_write_dir_entry(fd->fs, &fd->dir_entry); 00971 #endif 00972 00973 #if USE_DYNAMIC_MEMORY 00974 free(fd); 00975 #else 00976 fd->fs = 0; 00977 #endif 00978 } 00979 }


| uint8_t fat_create_file | ( | struct fat_dir_struct * | parent, | |
| const char * | file, | |||
| struct fat_dir_entry_struct * | dir_entry | |||
| ) |
Creates a file.
Creates a file and obtains the directory entry of the new file. If the file to create already exists, the directory entry of the existing file will be returned within the dir_entry parameter.
The generation of the short 8.3 file name is quite simple. The first eight characters are used for the filename. The extension, if any, is made up of the first three characters following the last dot within the long filename. If the filename (without the extension) is longer than eight characters, the lower byte of the cluster number replaces the last two characters to avoid name clashes. In any other case, it is your responsibility to avoid name clashes.
| [in] | parent | The handle of the directory in which to create the file. |
| [in] | file | The name of the file to create. |
| [out] | dir_entry | The directory entry to fill for the new file. |
Definition at line 2055 of file fat.c.
References fat_dir_entry_struct::entry_offset, fat_find_offset_for_dir_entry(), fat_read_dir(), fat_reset_dir(), fat_write_dir_entry(), fat_dir_struct::fs, and fat_dir_entry_struct::long_name.
Referenced by WaspSD::create().
02056 { 02057 if(!parent || !file || !file[0] || !dir_entry) 02058 return 0; 02059 02060 /* check if the file already exists */ 02061 while(1) 02062 { 02063 if(!fat_read_dir(parent, dir_entry)) 02064 break; 02065 02066 if(strcmp(file, dir_entry->long_name) == 0) 02067 { 02068 fat_reset_dir(parent); 02069 return 0; 02070 } 02071 } 02072 02073 struct fat_fs_struct* fs = parent->fs; 02074 02075 /* prepare directory entry with values already known */ 02076 memset(dir_entry, 0, sizeof(*dir_entry)); 02077 strncpy(dir_entry->long_name, file, sizeof(dir_entry->long_name) - 1); 02078 02079 /* find place where to store directory entry */ 02080 if(!(dir_entry->entry_offset = fat_find_offset_for_dir_entry(fs, parent, dir_entry))) 02081 return 0; 02082 02083 /* write directory entry to disk */ 02084 if(!fat_write_dir_entry(fs, dir_entry)) 02085 return 0; 02086 02087 return 1; 02088 }


| uint8_t fat_delete_file | ( | struct fat_fs_struct * | fs, | |
| struct fat_dir_entry_struct * | dir_entry | |||
| ) |
Deletes a file or directory.
If a directory is deleted without first deleting its subdirectories and files, disk space occupied by these files will get wasted as there is no chance to release it and mark it as free.
| [in] | fs | The filesystem on which to operate. |
| [in] | dir_entry | The directory entry of the file to delete. |
Definition at line 2106 of file fat.c.
References fat_dir_entry_struct::cluster, partition_struct::device_read, partition_struct::device_write, fat_dir_entry_struct::entry_offset, FAT_DIRENTRY_DELETED, fat_free_clusters(), and fat_fs_struct::partition.
Referenced by WaspSD::delDir(), and WaspSD::delFile().
02107 { 02108 if(!fs || !dir_entry) 02109 return 0; 02110 02111 /* get offset of the file's directory entry */ 02112 offset_t dir_entry_offset = dir_entry->entry_offset; 02113 if(!dir_entry_offset) 02114 return 0; 02115 02116 #if FAT_LFN_SUPPORT 02117 uint8_t buffer[12]; 02118 while(1) 02119 { 02120 /* read directory entry */ 02121 if(!fs->partition->device_read(dir_entry_offset, buffer, sizeof(buffer))) 02122 return 0; 02123 02124 /* mark the directory entry as deleted */ 02125 buffer[0] = FAT_DIRENTRY_DELETED; 02126 02127 /* write back entry */ 02128 if(!fs->partition->device_write(dir_entry_offset, buffer, sizeof(buffer))) 02129 return 0; 02130 02131 /* check if we deleted the whole entry */ 02132 if(buffer[11] != 0x0f) 02133 break; 02134 02135 dir_entry_offset += 32; 02136 } 02137 #else 02138 /* mark the directory entry as deleted */ 02139 uint8_t first_char = FAT_DIRENTRY_DELETED; 02140 if(!fs->partition->device_write(dir_entry_offset, &first_char, 1)) 02141 return 0; 02142 #endif 02143 02144 /* We deleted the directory entry. The next thing to do is 02145 * marking all occupied clusters as free. 02146 */ 02147 return (dir_entry->cluster == 0 || fat_free_clusters(fs, dir_entry->cluster)); 02148 }


| uint8_t fat_get_dir_entry_of_path | ( | struct fat_fs_struct * | fs, | |
| const char * | path, | |||
| struct fat_dir_entry_struct * | dir_entry | |||
| ) |
Retrieves the directory entry of a path.
The given path may both describe a file or a directory.
| [in] | fs | The FAT filesystem on which to search. |
| [in] | path | The path of which to read the directory entry. |
| [out] | dir_entry | The directory entry to fill. |
Definition at line 850 of file fat.c.
References fat_dir_entry_struct::attributes, FAT_ATTRIB_DIR, fat_close_dir(), fat_open_dir(), fat_read_dir(), and fat_dir_entry_struct::long_name.
Referenced by WaspSD::init().
00851 { 00852 if(!fs || !path || path[0] == '\0' || !dir_entry) 00853 return 0; 00854 00855 if(path[0] == '/') 00856 ++path; 00857 00858 /* begin with the root directory */ 00859 memset(dir_entry, 0, sizeof(*dir_entry)); 00860 dir_entry->attributes = FAT_ATTRIB_DIR; 00861 00862 while(1) 00863 { 00864 if(path[0] == '\0') 00865 return 1; 00866 00867 struct fat_dir_struct* dd = fat_open_dir(fs, dir_entry); 00868 if(!dd) 00869 break; 00870 00871 /* extract the next hierarchy we will search for */ 00872 const char* sub_path = strchr(path, '/'); 00873 uint8_t length_to_sep; 00874 if(sub_path) 00875 { 00876 length_to_sep = sub_path - path; 00877 ++sub_path; 00878 } 00879 else 00880 { 00881 length_to_sep = strlen(path); 00882 sub_path = path + length_to_sep; 00883 } 00884 00885 /* read directory entries */ 00886 while(fat_read_dir(dd, dir_entry)) 00887 { 00888 /* check if we have found the next hierarchy */ 00889 if((strlen(dir_entry->long_name) != length_to_sep || 00890 strncmp(path, dir_entry->long_name, length_to_sep) != 0)) 00891 continue; 00892 00893 fat_close_dir(dd); 00894 dd = 0; 00895 00896 if(path[length_to_sep] == '\0') 00897 /* we iterated through the whole path and have found the file */ 00898 return 1; 00899 00900 if(dir_entry->attributes & FAT_ATTRIB_DIR) 00901 { 00902 /* we found a parent directory of the file we are searching for */ 00903 path = sub_path; 00904 break; 00905 } 00906 00907 /* a parent of the file exists, but not the file itself */ 00908 return 0; 00909 } 00910 00911 fat_close_dir(dd); 00912 } 00913 00914 return 0; 00915 }


| struct fat_file_struct* fat_open_file | ( | struct fat_fs_struct * | fs, | |
| const struct fat_dir_entry_struct * | dir_entry | |||
| ) | [read] |
Opens a file on a FAT filesystem.
| [in] | fs | The filesystem on which the file to open lies. |
| [in] | dir_entry | The directory entry of the file to open. |
Definition at line 926 of file fat.c.
References fat_dir_entry_struct::attributes, fat_dir_entry_struct::cluster, fat_file_struct::dir_entry, FAT_ATTRIB_DIR, FAT_FILE_COUNT, fat_file_handles, fat_file_struct::fs, fat_file_struct::pos, and fat_file_struct::pos_cluster.
Referenced by WaspSD::openFile().
00927 { 00928 if(!fs || !dir_entry || (dir_entry->attributes & FAT_ATTRIB_DIR)) 00929 return 0; 00930 00931 #if USE_DYNAMIC_MEMORY 00932 struct fat_file_struct* fd = malloc(sizeof(*fd)); 00933 if(!fd) 00934 return 0; 00935 #else 00936 struct fat_file_struct* fd = fat_file_handles; 00937 uint8_t i; 00938 for(i = 0; i < FAT_FILE_COUNT; ++i) 00939 { 00940 if(!fd->fs) 00941 break; 00942 00943 ++fd; 00944 } 00945 if(i >= FAT_FILE_COUNT) 00946 return 0; 00947 #endif 00948 00949 memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry)); 00950 fd->fs = fs; 00951 fd->pos = 0; 00952 fd->pos_cluster = dir_entry->cluster; 00953 00954 return fd; 00955 }

| intptr_t fat_read_file | ( | struct fat_file_struct * | fd, | |
| uint8_t * | buffer, | |||
| uintptr_t | buffer_len | |||
| ) |
Reads data from a file.
The data requested is read from the current file location.
| [in] | fd | The file handle of the file from which to read. |
| [out] | buffer | The buffer into which to write. |
| [in] | buffer_len | The amount of data to read. |
Definition at line 993 of file fat.c.
References fat_dir_entry_struct::cluster, fat_header_struct::cluster_size, partition_struct::device_read, fat_file_struct::dir_entry, fat_cluster_offset(), fat_get_next_cluster(), fat_dir_entry_struct::file_size, fat_file_struct::fs, fat_fs_struct::header, fat_fs_struct::partition, fat_file_struct::pos, and fat_file_struct::pos_cluster.
Referenced by WaspSD::cat(), WaspSD::catBin(), WaspSD::catln(), WaspSD::indexOf(), and WaspSD::numln().
00994 { 00995 /* check arguments */ 00996 if(!fd || !buffer || buffer_len < 1) 00997 return -1; 00998 00999 /* determine number of bytes to read */ 01000 if(fd->pos + buffer_len > fd->dir_entry.file_size) 01001 buffer_len = fd->dir_entry.file_size - fd->pos; 01002 if(buffer_len == 0) 01003 return 0; 01004 01005 uint16_t cluster_size = fd->fs->header.cluster_size; 01006 cluster_t cluster_num = fd->pos_cluster; 01007 uintptr_t buffer_left = buffer_len; 01008 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1)); 01009 01010 /* find cluster in which to start reading */ 01011 if(!cluster_num) 01012 { 01013 cluster_num = fd->dir_entry.cluster; 01014 01015 if(!cluster_num) 01016 { 01017 if(!fd->pos) 01018 return 0; 01019 else 01020 return -1; 01021 } 01022 01023 if(fd->pos) 01024 { 01025 uint32_t pos = fd->pos; 01026 while(pos >= cluster_size) 01027 { 01028 pos -= cluster_size; 01029 cluster_num = fat_get_next_cluster(fd->fs, cluster_num); 01030 if(!cluster_num) 01031 return -1; 01032 } 01033 } 01034 } 01035 01036 /* read data */ 01037 do 01038 { 01039 /* calculate data size to copy from cluster */ 01040 offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset; 01041 uint16_t copy_length = cluster_size - first_cluster_offset; 01042 if(copy_length > buffer_left) 01043 copy_length = buffer_left; 01044 01045 /* read data */ 01046 if(!fd->fs->partition->device_read(cluster_offset, buffer, copy_length)) 01047 return buffer_len - buffer_left; 01048 01049 /* calculate new file position */ 01050 buffer += copy_length; 01051 buffer_left -= copy_length; 01052 fd->pos += copy_length; 01053 01054 if(first_cluster_offset + copy_length >= cluster_size) 01055 { 01056 /* we are on a cluster boundary, so get the next cluster */ 01057 if((cluster_num = fat_get_next_cluster(fd->fs, cluster_num))) 01058 { 01059 first_cluster_offset = 0; 01060 } 01061 else 01062 { 01063 fd->pos_cluster = 0; 01064 return buffer_len - buffer_left; 01065 } 01066 } 01067 01068 fd->pos_cluster = cluster_num; 01069 01070 } while(buffer_left > 0); /* check if we are done */ 01071 01072 return buffer_len; 01073 }


| uint8_t fat_resize_file | ( | struct fat_file_struct * | fd, | |
| uint32_t | size | |||
| ) |
Resizes a file to have a specific size.
Enlarges or shrinks the file pointed to by the file descriptor to have exactly the specified size.
If the file is truncated, all bytes having an equal or larger offset than the given size are lost. If the file is expanded, the additional bytes are allocated.
| [in] | fd | The file decriptor of the file which to resize. |
| [in] | size | The new size of the file. |
Definition at line 1288 of file fat.c.
References fat_dir_entry_struct::cluster, fat_header_struct::cluster_size, fat_file_struct::dir_entry, fat_append_clusters(), fat_free_clusters(), fat_get_next_cluster(), fat_terminate_clusters(), fat_write_dir_entry(), fat_dir_entry_struct::file_size, fat_file_struct::fs, fat_fs_struct::header, fat_file_struct::pos, and fat_file_struct::pos_cluster.
Referenced by fat_seek_file().
01289 { 01290 if(!fd) 01291 return 0; 01292 01293 cluster_t cluster_num = fd->dir_entry.cluster; 01294 uint16_t cluster_size = fd->fs->header.cluster_size; 01295 uint32_t size_new = size; 01296 01297 do 01298 { 01299 if(cluster_num == 0 && size_new == 0) 01300 /* the file stays empty */ 01301 break; 01302 01303 /* seek to the next cluster as long as we need the space */ 01304 while(size_new > cluster_size) 01305 { 01306 /* get next cluster of file */ 01307 cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); 01308 if(cluster_num_next) 01309 { 01310 cluster_num = cluster_num_next; 01311 size_new -= cluster_size; 01312 } 01313 else 01314 { 01315 break; 01316 } 01317 } 01318 01319 if(size_new > cluster_size || cluster_num == 0) 01320 { 01321 /* Allocate new cluster chain and append 01322 * it to the existing one, if available. 01323 */ 01324 cluster_t cluster_count = (size_new + cluster_size - 1) / cluster_size; 01325 cluster_t cluster_new_chain = fat_append_clusters(fd->fs, cluster_num, cluster_count); 01326 if(!cluster_new_chain) 01327 return 0; 01328 01329 if(!cluster_num) 01330 { 01331 cluster_num = cluster_new_chain; 01332 fd->dir_entry.cluster = cluster_num; 01333 } 01334 } 01335 01336 /* write new directory entry */ 01337 fd->dir_entry.file_size = size; 01338 if(size == 0) 01339 fd->dir_entry.cluster = 0; 01340 if(!fat_write_dir_entry(fd->fs, &fd->dir_entry)) 01341 return 0; 01342 01343 if(size == 0) 01344 { 01345 /* free all clusters of file */ 01346 fat_free_clusters(fd->fs, cluster_num); 01347 } 01348 else if(size_new <= cluster_size) 01349 { 01350 /* free all clusters no longer needed */ 01351 fat_terminate_clusters(fd->fs, cluster_num); 01352 } 01353 01354 } while(0); 01355 01356 /* correct file position */ 01357 if(size < fd->pos) 01358 { 01359 fd->pos = size; 01360 fd->pos_cluster = 0; 01361 } 01362 01363 return 1; 01364 }


| uint8_t fat_seek_file | ( | struct fat_file_struct * | fd, | |
| int32_t * | offset, | |||
| uint8_t | whence | |||
| ) |
Repositions the read/write file offset.
Changes the file offset where the next call to fat_read_file() or fat_write_file() starts reading/writing.
If the new offset is beyond the end of the file, fat_resize_file() is implicitly called, i.e. the file is expanded.
The new offset can be given in different ways determined by the whence parameter:
*offset is relative to the beginning of the file.*offset is relative to the current file position.*offset is relative to the end of the file.
The resulting absolute offset is written to the location the offset parameter points to.
| [in] | fd | The file decriptor of the file on which to seek. |
| [in,out] | offset | A pointer to the new offset, as affected by the whence parameter. The function writes the new absolute offset to this location before it returns. |
| [in] | whence | Affects the way offset is interpreted, see above. |
Definition at line 1233 of file fat.c.
References fat_file_struct::dir_entry, fat_resize_file(), FAT_SEEK_CUR, FAT_SEEK_END, FAT_SEEK_SET, FAT_WRITE_SUPPORT, fat_dir_entry_struct::file_size, fat_file_struct::pos, and fat_file_struct::pos_cluster.
Referenced by WaspSD::cat(), WaspSD::catBin(), and WaspSD::writeSD().
01234 { 01235 if(!fd || !offset) 01236 return 0; 01237 01238 uint32_t new_pos = fd->pos; 01239 switch(whence) 01240 { 01241 case FAT_SEEK_SET: 01242 new_pos = *offset; 01243 break; 01244 case FAT_SEEK_CUR: 01245 new_pos += *offset; 01246 break; 01247 case FAT_SEEK_END: 01248 new_pos = fd->dir_entry.file_size + *offset; 01249 break; 01250 default: 01251 return 0; 01252 } 01253 01254 if(new_pos > fd->dir_entry.file_size 01255 #if FAT_WRITE_SUPPORT 01256 && !fat_resize_file(fd, new_pos) 01257 #endif 01258 ) 01259 return 0; 01260 01261 fd->pos = new_pos; 01262 fd->pos_cluster = 0; 01263 01264 *offset = (int32_t) new_pos; 01265 return 1; 01266 }


| intptr_t fat_write_file | ( | struct fat_file_struct * | fd, | |
| const uint8_t * | buffer, | |||
| uintptr_t | buffer_len | |||
| ) |
Writes data to a file.
The data is written to the current file location.
| [in] | fd | The file handle of the file to which to write. |
| [in] | buffer | The buffer from which to read the data to be written. |
| [in] | buffer_len | The amount of data to write. |
Definition at line 1088 of file fat.c.
References fat_dir_entry_struct::cluster, fat_header_struct::cluster_size, partition_struct::device_write, fat_file_struct::dir_entry, fat_append_clusters(), fat_cluster_offset(), fat_get_next_cluster(), fat_write_dir_entry(), fat_dir_entry_struct::file_size, fat_file_struct::fs, fat_fs_struct::header, fat_fs_struct::partition, fat_file_struct::pos, and fat_file_struct::pos_cluster.
Referenced by WaspSD::writeSD().
01089 { 01090 /* check arguments */ 01091 if(!fd || !buffer || buffer_len < 1) 01092 return -1; 01093 if(fd->pos > fd->dir_entry.file_size) 01094 return -1; 01095 01096 uint16_t cluster_size = fd->fs->header.cluster_size; 01097 cluster_t cluster_num = fd->pos_cluster; 01098 uintptr_t buffer_left = buffer_len; 01099 uint16_t first_cluster_offset = (uint16_t) (fd->pos & (cluster_size - 1)); 01100 01101 /* find cluster in which to start writing */ 01102 if(!cluster_num) 01103 { 01104 cluster_num = fd->dir_entry.cluster; 01105 01106 if(!cluster_num) 01107 { 01108 if(!fd->pos) 01109 { 01110 /* empty file */ 01111 fd->dir_entry.cluster = cluster_num = fat_append_clusters(fd->fs, 0, 1); 01112 if(!cluster_num) 01113 return -1; 01114 } 01115 else 01116 { 01117 return -1; 01118 } 01119 } 01120 01121 if(fd->pos) 01122 { 01123 uint32_t pos = fd->pos; 01124 cluster_t cluster_num_next; 01125 while(pos >= cluster_size) 01126 { 01127 pos -= cluster_size; 01128 cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); 01129 if(!cluster_num_next && pos == 0) 01130 /* the file exactly ends on a cluster boundary, and we append to it */ 01131 cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1); 01132 if(!cluster_num_next) 01133 return -1; 01134 01135 cluster_num = cluster_num_next; 01136 } 01137 } 01138 } 01139 01140 /* write data */ 01141 do 01142 { 01143 /* calculate data size to write to cluster */ 01144 offset_t cluster_offset = fat_cluster_offset(fd->fs, cluster_num) + first_cluster_offset; 01145 uint16_t write_length = cluster_size - first_cluster_offset; 01146 if(write_length > buffer_left) 01147 write_length = buffer_left; 01148 01149 /* write data which fits into the current cluster */ 01150 if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length)) 01151 break; 01152 01153 /* calculate new file position */ 01154 buffer += write_length; 01155 buffer_left -= write_length; 01156 fd->pos += write_length; 01157 01158 if(first_cluster_offset + write_length >= cluster_size) 01159 { 01160 /* we are on a cluster boundary, so get the next cluster */ 01161 cluster_t cluster_num_next = fat_get_next_cluster(fd->fs, cluster_num); 01162 if(!cluster_num_next && buffer_left > 0) 01163 /* we reached the last cluster, append a new one */ 01164 cluster_num_next = fat_append_clusters(fd->fs, cluster_num, 1); 01165 if(!cluster_num_next) 01166 { 01167 fd->pos_cluster = 0; 01168 break; 01169 } 01170 01171 cluster_num = cluster_num_next; 01172 first_cluster_offset = 0; 01173 } 01174 01175 fd->pos_cluster = cluster_num; 01176 01177 } while(buffer_left > 0); /* check if we are done */ 01178 01179 /* update directory entry */ 01180 if(fd->pos > fd->dir_entry.file_size) 01181 { 01182 #if !FAT_DELAY_DIRENTRY_UPDATE 01183 uint32_t size_old = fd->dir_entry.file_size; 01184 #endif 01185 01186 /* update file size */ 01187 fd->dir_entry.file_size = fd->pos; 01188 01189 #if !FAT_DELAY_DIRENTRY_UPDATE 01190 /* write directory entry */ 01191 if(!fat_write_dir_entry(fd->fs, &fd->dir_entry)) 01192 { 01193 /* We do not return an error here since we actually wrote 01194 * some data to disk. So we calculate the amount of data 01195 * we wrote to disk and which lies within the old file size. 01196 */ 01197 buffer_left = fd->pos - size_old; 01198 fd->pos = size_old; 01199 } 01200 #endif 01201 } 01202 01203 return buffer_len - buffer_left; 01204 }


1.5.6