static int32 _initialize_file( IN tffs_t * ptffs, IN tdir_t * pdir, IN tdir_entry_t * pdir_entry, OUT tfile_t * pfile) { int32 ret; pfile->ptffs = ptffs; pfile->pdir = pdir; pfile->pdir_entry = pdir_entry; ret = FILE_OK; pfile->start_clus = dirent_get_clus(pdir_entry); pfile->file_size = dirent_get_file_size(pdir_entry); pfile->cur_clus = pfile->start_clus; pfile->cur_sec = 0; pfile->cur_sec_offset = 0; pfile->cur_fp_offset = 0; if (pfile->open_mode == OPENMODE_APPEND) { pfile->cur_fp_offset = dirent_get_file_size(pdir_entry); _file_seek(pfile, pfile->cur_fp_offset); if (pfile->cur_clus != 0) { if (cache_readsector(ptffs->pcache, clus2sec(ptffs, pfile->cur_clus) + pfile->cur_sec, pfile->secbuf) != CACHE_OK) { ret = ERR_TFFS_DEVICE_FAIL; } } } else if (pfile->open_mode == OPENMODE_WRITE) { if (pfile->start_clus != 0) { if (fat_free_clus(ptffs->pfat, pfile->start_clus) != FAT_OK) { ERR("%s(): %d fat_free_clus failed.\n", __FUNCTION__, __LINE__); ret = ERR_TFFS_FAT; } } dirent_set_file_size(pdir_entry , 0); dirent_set_clus(pdir_entry, 0); pfile->file_size = 0; pfile->cur_clus = 0; pfile->cur_sec = 0; pfile->cur_sec_offset = 0; pfile->cur_fp_offset = 0; } else { if (pfile->cur_clus != 0) { if (cache_readsector(ptffs->pcache, clus2sec(ptffs, pfile->cur_clus) + pfile->cur_sec, pfile->secbuf) != CACHE_OK) { ret = ERR_TFFS_DEVICE_FAIL; } } } return ret; }
int32 FS_readdir( IN tdir_handle_t hdir, OUT dirent_t * pdirent) { tdir_t * pdir = (tdir_t *)hdir; uint32 ret; tdir_entry_t * pdir_entry; if (!hdir || !pdirent) return ERR_FS_INVALID_PARAM; ret = FS_OK; pdir_entry = dirent_malloc(); while (1) { uint32 de_ret; de_ret = dirent_get_next(pdir, pdir_entry); if (de_ret == DIRENTRY_OK) { Strcpy(pdirent->d_name, pdir_entry->long_name); Strcpy(pdirent->d_name_short, pdir_entry->short_name); pdirent->dir_attr = dirent_get_dir_attr(pdir_entry); pdirent->dir_file_size = dirent_get_file_size(pdir_entry); pdirent->crttime.year = ((dirent_get_crt_date(pdir_entry) & 0xFE00) >> 9) + 1980; pdirent->crttime.month = ((dirent_get_crt_date(pdir_entry) & 0x1E0) >> 5); pdirent->crttime.day = (dirent_get_crt_date(pdir_entry) & 0x1F); pdirent->crttime.hour = (dirent_get_crt_time(pdir_entry) & 0xF800) >> 11; pdirent->crttime.min = (dirent_get_crt_time(pdir_entry) & 0x7E0) >> 5; pdirent->crttime.sec = ((dirent_get_crt_time(pdir_entry) & 0x1F) << 2) + (dirent_get_crt_time_tenth(pdir_entry) & 1); break; } else if (de_ret == ERR_DIRENTRY_NOMORE_ENTRY) {
int32 TFFS_fread( IN tfile_handle_t hfile, IN uint32 buflen, OUT ubyte * ptr) { tfile_t * pfile = (tfile_t *)hfile; tdir_entry_t * pdir_entry; tdir_t * pdir; uint32 read_size; uint32 readin_size; uint32 file_size; int32 ret; if (!hfile || !ptr) return ERR_TFFS_INVALID_PARAM; pdir = pfile->pdir; pdir_entry = pfile->pdir_entry; file_size = dirent_get_file_size(pdir_entry); read_size = min(buflen, file_size - pfile->cur_fp_offset); readin_size = 0; while (readin_size < read_size) { if (pfile->cur_sec_offset + (read_size - readin_size) >= pfile->ptffs->pbs->byts_per_sec) { Memcpy(ptr + readin_size, pfile->secbuf + pfile->cur_sec_offset, pfile->ptffs->pbs->byts_per_sec - pfile->cur_sec_offset); readin_size += pfile->ptffs->pbs->byts_per_sec - pfile->cur_sec_offset; ret = file_read_sector(pfile); if (ret == FILE_OK) { pfile->cur_sec_offset = 0; continue; } else if (ret == ERR_FILE_EOF) { //WARN("%s(): unexpect file end at %d\n", __FUNCTION__, __LINE__); break; } else { ERR("%s(): read file data sector failed at %d\n", __FUNCTION__, __LINE__); ret = ERR_TFFS_DEVICE_FAIL; goto _end; } } else { Memcpy(ptr + readin_size, pfile->secbuf + pfile->cur_sec_offset, read_size - readin_size); pfile->cur_sec_offset += (read_size - readin_size); readin_size += (read_size - readin_size); } } if (readin_size > 0) { dirent_update_lst_acc_date(pdir_entry); pfile->cur_fp_offset += readin_size; ret = readin_size; } else { ret = ERR_TFFS_FILE_EOF; } _end: return ret; }
int32 TFFS_fwrite( IN tfile_handle_t hfile, IN uint32 buflen, IN ubyte * ptr) { tfile_t * pfile = (tfile_t *)hfile; tdir_entry_t * pdir_entry; tdir_t * pdir; uint32 write_size; uint32 written_size; uint32 file_size; int32 ret; if (!hfile || !ptr) return ERR_TFFS_INVALID_PARAM; if (pfile->open_mode == OPENMODE_READONLY) return ERR_TFFS_READONLY; pdir = pfile->pdir; pdir_entry = pfile->pdir_entry; file_size = dirent_get_file_size(pdir_entry); write_size = buflen; written_size = 0; while (written_size < buflen) { uint32 write_once_size; write_once_size = min(pfile->ptffs->pbs->byts_per_sec - pfile->cur_sec_offset, buflen - written_size); Memcpy(pfile->secbuf + pfile->cur_sec_offset, ptr + written_size, write_once_size); written_size += write_once_size; pfile->cur_sec_offset += write_once_size; if (pfile->cur_sec_offset == pfile->ptffs->pbs->byts_per_sec) { ret = file_write_sector(pfile); if (ret == FILE_OK) { if (buflen - written_size > 0) { if ((ret = _get_next_sec(pfile)) != FILE_OK) { ERR("%s(): get next sector failed at %d with ret = %d\n", __FUNCTION__, __LINE__, ret); break; } } pfile->cur_sec_offset = 0; } else if (ret == ERR_FILE_NO_FREE_CLUSTER) { ret = ERR_TFFS_NO_FREE_SPACE; break; } else { ret = ERR_TFFS_DEVICE_FAIL; break; } } } if (written_size > 0) { dirent_update_wrt_time(pdir_entry); dirent_update_wrt_date(pdir_entry); pfile->file_size += written_size; } return written_size; }