1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openLuat-LuatOS

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
luat_vfs_romfs.c 8.3 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Dozingfiretruck Отправлено год назад 906d75e
#include "luat_base.h"
#include "luat_fs.h"
#include "luat_mem.h"
#define LUAT_LOG_TAG "romfs"
#include "luat_log.h"
#include "luat_romfs.h"
#define ROMFS_DEBUG 0
#if ROMFS_DEBUG == 0
#undef LLOGD
#define LLOGD(...)
#endif
static uint32_t toInt32(uint8_t buff[4]) {
uint32_t ret = 0;
ret += (buff[0] << 24);
ret += (buff[1] << 16);
ret += (buff[2] << 8);
ret += (buff[3] << 0);
return ret;
}
// typedef struct luat_fs_romfs
// {
// size_t count;
// romfs_file_t *files[256 - 1];
// }luat_fs_romfs_t;
typedef struct romfs_head
{
char magic[8];
size_t count;
size_t checksum;
char volume[16];
} romfs_head_t;
#define FDATA(fd) ((char *)(fd) + sizeof(romfs_file_t))
#define FSIZE(fd) (fd->file->size)
#ifdef LUAT_USE_FS_VFS
static int romfs_find(luat_romfs_ctx* fs, const char* filename, romfs_file_t *file) {
int ret = 0;
int offset = sizeof(romfs_head_t);
// LLOGD("romfs_find %s", filename);
ret = fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
while (1)
{
// LLOGD("name %s", file->name);
if (!memcmp(".", file->name, 2) || !memcmp("..", file->name, 3))
{
// pass
}
else
{
if (strcmp(file->name, filename) == 0)
{
// LLOGD("found %s %08X %08X", file->name, toInt32(file->size), toInt32(file->next_offset));
return offset;
}
}
if ((toInt32(file->next_offset) & 0xFFFFFFF0) == 0)
break;
// LLOGD("file->next_offset %08X", toInt32(file->next_offset));
offset = sizeof(romfs_head_t) + (toInt32(file->next_offset) & 0xFFFFFFF0);
// LLOGD("Next offset %08X", offset);
ret = fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
if (ret < 0) {
LLOGW("romfs ERROR find %d", ret);
return -1;
}
}
LLOGD("NOT found %s", filename);
return 0;
}
FILE *luat_vfs_romfs_fopen(void *userdata, const char *filename, const char *mode)
{
// LLOGD("open romfs >> ============== %s", filename);
// int ret = 0;
size_t offset = 0;
luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
romfs_file_t tfile = {0};
if (memcmp("r", mode, 1))
{
return NULL; // romfs 是只读文件系统
}
offset = romfs_find(fs, filename, &tfile);
if (offset > 0) {
romfs_fd_t *fd = luat_heap_malloc(sizeof(romfs_fd_t));
if (fd == NULL)
{
LLOGE("out of memory when malloc luat_fs_romfs_t");
return NULL;
}
fd->offset = 0;
fd->addr = offset;
// LLOGD("fopen addr %08X", fd->addr);
memcpy(&fd->file, &tfile, sizeof(romfs_file_t));
return (FILE *)fd;
}
return NULL;
}
int luat_vfs_romfs_getc(void *userdata, FILE *stream)
{
// LLOGD("getc %p %p", userdata, stream);
romfs_fd_t *fd = (romfs_fd_t *)stream;
luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
// LLOGD("getc %p %p %d %d", userdata, stream, fd->offset, fd->size);
char c = 0;
if (fd->offset < toInt32(fd->file.size))
{
fs->read(fs->userdata, &c, fd->offset + fd->addr + sizeof(romfs_file_t), 1);
fd->offset++;
// LLOGD("getc %02X", c);
return c;
}
return -1;
}
int luat_vfs_romfs_fseek(void *userdata, FILE *stream, long int offset, int origin)
{
// LLOGD("fseek %p %p %d %d", userdata, stream, offset, origin);
romfs_fd_t *fd = (romfs_fd_t *)stream;
if (origin == SEEK_CUR)
{
fd->offset += offset;
return 0;
}
else if (origin == SEEK_SET)
{
fd->offset = offset;
return 0;
}
else
{
fd->offset = toInt32(fd->file.size) - offset;
return 0;
}
}
int luat_vfs_romfs_ftell(void *userdata, FILE *stream)
{
romfs_fd_t *fd = (romfs_fd_t *)stream;
// LLOGD("tell %p %p %d %d", userdata, stream, fd->size, fd->offset);
return fd->offset;
}
int luat_vfs_romfs_fclose(void *userdata, FILE *stream)
{
romfs_fd_t *fd = (romfs_fd_t *)stream;
// LLOGD("fclose %p %p %d %d", userdata, stream, fd->size, fd->offset);
luat_heap_free(fd);
return 0;
}
int luat_vfs_romfs_feof(void *userdata, FILE *stream)
{
romfs_fd_t *fd = (romfs_fd_t *)stream;
// LLOGD("feof %p %p %d %d", userdata, stream, fd->size, fd->offset);
return fd->offset >= toInt32(fd->file.size) ? 1 : 0;
}
int luat_vfs_romfs_ferror(void *userdata, FILE *stream)
{
return 0;
}
size_t luat_vfs_romfs_fread(void *userdata, void *ptr, size_t size, size_t nmemb, FILE *stream)
{
romfs_fd_t *fd = (romfs_fd_t *)stream;
luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
// LLOGD("fread %p %p %d %d", userdata, stream, fd->size, fd->offset);
// LLOGD("fread2 %p %p %d %d", userdata, stream, size * nmemb, fd->offset);
size_t read_size = size * nmemb;
if (fd->offset + read_size > toInt32(fd->file.size))
{
read_size = toInt32(fd->file.size) - fd->offset;
}
// memcpy(ptr, FDATA(fd) + fd->offset, read_size);
fs->read(fs->userdata, ptr, fd->offset + fd->addr + sizeof(romfs_file_t), read_size);
fd->offset += read_size;
return read_size;
}
int luat_vfs_romfs_fexist(void *userdata, const char *filename)
{
// LLOGD("open romfs %s", filename);
luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
romfs_file_t file = {0};
int ret = romfs_find(fs, filename, &file);
// LLOGD("found? %s %d", filename, ret);
return ret > 0 ? 1 : 0;
}
size_t luat_vfs_romfs_fsize(void *userdata, const char *filename)
{
// LLOGD("open romfs %s", filename);
luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
romfs_file_t file = {0};
int ret = romfs_find(fs, filename, &file);
if (ret > 0) {
return toInt32(file.size);
}
return 0;
}
int luat_vfs_romfs_mount(void **userdata, luat_fs_conf_t *conf)
{
// LLOGD("luat_vfs_romfs_mount ==================");
luat_romfs_ctx* fs = (luat_romfs_ctx*)conf->busname;
// LLOGD("luat_romfs_ctx %p", fs);
// LLOGD("luat_romfs_ctx %p", fs->read);
// LLOGD("luat_romfs_ctx %p", fs->userdata);
romfs_head_t head = {0};
fs->read(fs->userdata, (char*)&head, 0, sizeof(romfs_head_t));
if (memcmp(head.magic, "-rom1fs-", 8))
{
LLOGI("Not ROMFS at %p", &head);
return -1;
}
// LLOGD("romfs mounted");
*userdata = conf->busname;
return 0;
}
int luat_vfs_romfs_umount(void *userdata, luat_fs_conf_t *conf)
{
return 0;
}
int luat_vfs_romfs_info(void *userdata, const char *path, luat_fs_info_t *conf)
{
memcpy(conf->filesystem, "romfs", strlen("romfs") + 1);
conf->type = 0;
conf->total_block = 0;
conf->block_used = 0;
conf->block_size = 512;
return 0;
}
int luat_vfs_romfs_lsdir(void *userdata, char const *_DirName, luat_fs_dirent_t *ents, size_t ent_offset, size_t len)
{
luat_romfs_ctx* fs = (luat_romfs_ctx*)userdata;
int offset = sizeof(romfs_head_t);
// romfs_head_t head = {0};
romfs_file_t tfile = {0};
// fs->read(fs->addr, &head, sizeof(romfs_head_t));
int counter = 0;
int count_down = ent_offset;
romfs_file_t *file = &tfile;
fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
while (1)
{
if (counter >= len)
break;
if (!memcmp(".", file->name, 2) || !memcmp("..", file->name, 3))
{
// pass
}
else if (count_down > 0)
{
count_down--;
}
else
{
ents[counter].d_type = 0;
strcpy(ents[counter].d_name, file->name);
counter++;
}
if ((toInt32(file->next_offset) & 0xFFFFFFF0) == 0)
break;
offset = sizeof(romfs_head_t) + (toInt32(file->next_offset) & 0xFFFFFFF0);
fs->read(fs->userdata, (char*)file, offset, sizeof(romfs_file_t));
}
return 0;
}
#define T(name) .name = luat_vfs_romfs_##name
const struct luat_vfs_filesystem vfs_fs_romfs = {
.name = "romfs",
.opts = {
.mkfs = NULL,
T(mount),
.umount = NULL,
.mkdir = NULL,
.rmdir = NULL,
.remove = NULL,
.rename = NULL,
T(fsize),
T(fexist),
T(info),
T(lsdir)},
.fopts = {T(fopen), T(getc), T(fseek), T(ftell), T(fclose), T(feof), T(ferror), T(fread), .fwrite = NULL}};
#endif
1
https://gitlife.ru/oschina-mirror/openLuat-LuatOS.git
git@gitlife.ru:oschina-mirror/openLuat-LuatOS.git
oschina-mirror
openLuat-LuatOS
openLuat-LuatOS
master