fygue: support cluster chunk list generator for file (needed for the future read() primitive)

This commit is contained in:
Yann MAGNIN 2025-04-05 15:22:09 +02:00
parent eaa0602225
commit b1b4e8a287
No known key found for this signature in database
GPG key ID: D82629D933EADC59
4 changed files with 96 additions and 28 deletions

View file

@ -79,3 +79,16 @@ int fygue_fat_cluster_get_sector(
}
return 0;
}
/* fygue_fat_get_cluster_addr() - get logical sector addr */
int fygue_fat_cluster_get_addr(
struct fygue_fat *fat,
uintptr_t *addr,
int cluster_id
) {
int sector_id;
if (fygue_fat_cluster_get_sector(fat, cluster_id, &sector_id) != 0)
return -1;
return fygue_fat_sector_get_addr(fat, addr, sector_id);
}

View file

@ -83,6 +83,12 @@ struct fygue_fat_file
int cluster_entry;
int attribute;
size_t size;
struct {
uintptr_t addr;
size_t size;
int cluster_count;
} *chunk;
int chunk_count;
};
/* fygue_fat_resolve: internal resolve information */
@ -163,6 +169,13 @@ extern int fygue_fat_cluster_get_sector(
int *sector_id
);
/* fygue_fat_get_cluster_addr() - get logical sector addr */
extern int fygue_fat_cluster_get_addr(
struct fygue_fat *fat,
uintptr_t *addr,
int cluster_id
);
/* fygue_fat_get_sector_addr() - get logical sector addr */
extern int fygue_fat_sector_get_addr(
struct fygue_fat *fat,

View file

@ -149,25 +149,7 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
/* _fygue_fat_prepare() - prepare logic information */
static int _fygue_fat_prepare(struct fygue_fat *fat)
{
int rc;
#if 0
rc = fygue_fat_sector_get_addr(
fat,
&fat->FAT0Addr,
fat->FAT0SectorID
);
if (rc != 0)
return -1;
rc = fygue_fat_sector_get_addr(
fat,
(void*)&fat->FAT1Addr,
fat->FAT1SectorID
);
if (rc != 0)
return -1;
#endif
rc = fygue_flash_cmap_lsector_get_addr(
int rc = fygue_flash_cmap_lsector_get_addr(
&fat->_flash.cmap,
&fat->RootAddr,
fat->RootSectorID

View file

@ -1,4 +1,5 @@
#include <string.h>
#include <stdlib.h>
#include "fat.h"
//---
@ -30,8 +31,70 @@ static int _fygue_path_get_name(
return 0;
}
/* _fugue_dirent_resolve(): convert found dirent to dir */
static int _fygue_dirent_resolve(
/* _fygue_dirent_resolve_file(): generate file information
*
* notes
* - assume FAT integrity */
static int _fygue_dirent_resolve_file(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
) {
uintptr_t cluster_addr_prev;
uintptr_t cluster_addr;
size_t cluster_size;
int cluster;
void *tmp;
memset(file, 0x00, sizeof(struct fygue_fat_file));
file->attribute = dirent->attribute;
file->cluster_entry = dirent->cluster_id;
file->size = dirent->size;
file->chunk = NULL;
file->chunk_count = 0;
cluster = file->cluster_entry;
cluster_size = fat->SectorSize * fat->SectorPerClus;
while (true)
{
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster) != 0)
goto error;
if (file->chunk_count > 0) {
cluster_addr_prev = file->chunk[file->chunk_count - 1].addr;
cluster_addr_prev += file->chunk[file->chunk_count - 1].size;
if (cluster_addr == cluster_addr_prev) {
file->chunk[file->chunk_count - 1].size += cluster_size;
file->chunk[file->chunk_count - 1].cluster_count += 1;
if (fygue_fat_cluster_get_next(fat, &cluster) != 0)
break;
continue;
}
}
tmp = reallocarray(
file->chunk,
file->chunk_count + 1,
sizeof(*file->chunk)
);
if (tmp == NULL)
goto error;
file->chunk = tmp;
file->chunk[file->chunk_count].size = cluster_size;
file->chunk[file->chunk_count].addr = cluster_addr;
file->chunk[file->chunk_count].cluster_count = 1;
file->chunk_count += 1;
if (fygue_fat_cluster_get_next(fat, &cluster) != 0)
break;
}
return 0;
error:
if (file->chunk == NULL)
free(file->chunk);
memset(file, 0x00, sizeof(struct fygue_fat_file));
return -1;
}
/* _fugue_dirent_resolve_dir(): convert found dirent to dir */
static int _fygue_dirent_resolve_dir(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
@ -96,13 +159,10 @@ static int _fygue_resolve_set(
) {
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
resolve->type = FYGUE_FAT_FILE_TYPE_DIR;
return _fygue_dirent_resolve(fat, &(resolve->dir), dirent);
return _fygue_dirent_resolve_dir(fat, &(resolve->dir), dirent);
}
resolve->type = FYGUE_FAT_FILE_TYPE_FILE;
resolve->file.attribute = dirent->attribute;
resolve->file.cluster_entry = dirent->cluster_id;
resolve->file.size = dirent->size;
return 0;
return _fygue_dirent_resolve_file(fat, &(resolve->file), dirent);
}
//---
@ -134,7 +194,7 @@ int fygue_fat_resolve(
while (true)
{
if (is_root) {
if (_fygue_dirent_resolve(fat, &dir, NULL) != 0)
if (_fygue_dirent_resolve_dir(fat, &dir, NULL) != 0)
return -3;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break;
@ -145,7 +205,7 @@ int fygue_fat_resolve(
return -4;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break;
if (_fygue_dirent_resolve(fat, &dir, &dirent) != 0)
if (_fygue_dirent_resolve_dir(fat, &dir, &dirent) != 0)
return -5;
}
if (is_root)