Files
Espresso/lib/fs/ramfs/ramfs.c

191 lines
5.2 KiB
C
Raw Normal View History

2025-05-28 14:41:02 -05:00
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fs/ramfs.h>
static ramfs_file_t ramfs_files[RAMFS_MAX_FILES];
static ramfs_directory_t root_directory = { .name = "/", .file_count = 0 };
void ramfs_init()
{
memset(ramfs_files, 0, sizeof(ramfs_files));
root_directory.file_count = 0;
}
ramfs_file_t* ramfs_create_file(const char* name, uint32_t size, uint8_t permissions)
{
for (uint32_t i = 0; i < RAMFS_MAX_FILES; i++) {
if (ramfs_files[i].name[0] == '\0') {
// Create the file
ramfs_file_t* file = &ramfs_files[i];
strncpy(file->name, name, RAMFS_MAX_PATH_LEN);
file->size = size;
file->data = (size > 0) ? malloc(size) : NULL;
file->permissions = permissions;
if (root_directory.file_count < RAMFS_MAX_FILES) {
root_directory.files[root_directory.file_count++] = file;
}
return file;
}
}
return NULL;
}
bool ramfs_delete_file(const char* name)
{
for (uint32_t i = 0; i < root_directory.file_count; i++) {
if (strcmp(root_directory.files[i]->name, name) == 0) {
free(root_directory.files[i]->data);
root_directory.files[i] = root_directory.files[root_directory.file_count - 1];
root_directory.file_count--;
return true;
}
}
return false;
}
ramfs_file_t* ramfs_find_file(const char* name)
{
for (uint32_t i = 0; i < root_directory.file_count; i++) {
if (strcmp(root_directory.files[i]->name, name) == 0) {
return root_directory.files[i];
}
}
return NULL;
}
bool ramfs_resize_file(const char* name, uint32_t new_size)
{
ramfs_file_t* file = ramfs_find_file(name);
if (file)
{
file->data = realloc(file->data, new_size);
file->size = new_size;
return true;
}
return false;
}
bool ramfs_append_to_file(const char* name, const uint8_t* data, uint32_t data_size)
{
ramfs_file_t* file = ramfs_find_file(name);
if (file && (file->permissions & RAMFS_PERM_WRITE))
{
file->data = realloc(file->data, file->size + data_size + 1);
if (!file->data) return false;
memcpy(file->data + file->size, data, data_size);
file->size += data_size;
file->data[file->size] = '\0';
return true;
}
return false;
}
bool ramfs_create_directory(const char* name)
{
if (root_directory.file_count < RAMFS_MAX_FILES) {
ramfs_directory_t* dir = (ramfs_directory_t*)malloc(sizeof(ramfs_directory_t));
strncpy(dir->name, name, RAMFS_MAX_PATH_LEN);
dir->file_count = 0;
root_directory.files[root_directory.file_count++] = (ramfs_file_t*)dir;
return true;
}
return false;
}
bool ramfs_delete_directory(const char* name)
{
for (uint32_t i = 0; i < root_directory.file_count; i++) {
if (strcmp(root_directory.files[i]->name, name) == 0) {
// Delete the directory (along with its files)
ramfs_directory_t* dir = (ramfs_directory_t*)root_directory.files[i];
for (uint32_t j = 0; j < dir->file_count; j++) {
free(dir->files[j]->data);
}
free(dir);
root_directory.files[i] = root_directory.files[root_directory.file_count - 1];
root_directory.file_count--;
return true;
}
}
return false;
}
bool ramfs_check_permissions(const char* name, uint8_t required_permissions)
{
ramfs_file_t* file = ramfs_find_file(name);
if (file) {
return (file->permissions & required_permissions) == required_permissions;
}
return false;
}
void ramfs_list_files()
{
printf("Files in RAMFS:\n");
for (uint32_t i = 0; i < root_directory.file_count; i++) {
printf("%s (Size: %u bytes)\n", root_directory.files[i]->name, root_directory.files[i]->size);
}
}
void ramfs_list_directories()
{
printf("Directories in RAMFS:\n");
for (uint32_t i = 0; i < root_directory.file_count; i++) {
if (root_directory.files[i]->data != NULL) {
printf("%s\n", root_directory.files[i]->name);
}
}
}
bool ramfs_read_file(const char* name, uint8_t* buffer, uint32_t buffer_size)
{
ramfs_file_t* file = ramfs_find_file(name);
if (file && (file->permissions & RAMFS_PERM_READ))
{
uint32_t bytes_to_read = (file->size < buffer_size) ? file->size : buffer_size;
memcpy(buffer, file->data, bytes_to_read);
return true;
}
return false;
}
bool ramfs_write_file(const char* name, const uint8_t* data, uint32_t size)
{
return ramfs_append_to_file(name, data, size);
}
bool ramfs_overwrite_file(const char* name, const uint8_t* data, uint32_t size)
{
ramfs_file_t* file = ramfs_find_file(name);
if (!file || !(file->permissions & RAMFS_PERM_WRITE)) {
return false;
}
// Allocate space for data + null terminator
uint8_t* new_data = realloc(file->data, size + 1);
if (!new_data && size > 0) {
return false; // realloc failed
}
file->data = new_data;
if (size > 0 && data) {
memcpy(file->data, data, size);
}
file->data[size] = '\0'; // Ensure null-terminated
file->size = size;
return true;
}