IMFS

Материал из SynapseOS wiki
Перейти к навигации Перейти к поиску
Файловая системы
Виртуальные файловые системы
Дисковые файловые системы
CD/DVD файловые системы
Сетевые файловые системы

IMFS (in memory filesystem) - файловая система работающая исключительно в ОЗУ.


Пример реализации в Синапс ОС:‎

/**
 * @file imfs.c
 * @author Арен Елчинян (a2.dev@yandex.com)
 * @brief 
 * @version 0.1.0
 * @date 24-03-2023
 * 
 * @license This work is licensed under the Creative Commons  Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)  License. 
 * @copyright Арен Елчинян (c) 2023
 * 
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "imfs.h"


folder_t *root_folder = NULL; 


/**
 * @brief Создание новой папки.
 * @param name Имя папки.
 * @param parent Указатель на папку-родитель.
 * @return Указатель на новую папку.
 */
folder_t *create_folder(const char *name, folder_t *parent) {
    folder_t *folder = malloc(sizeof(folder_t));
    strcpy(folder->name, name);
    folder->parent = parent;
    folder->child = NULL;
    folder->next = NULL;
    folder->files = NULL;

    if (parent == NULL) {
        root_folder = folder;
    } else {
        if (parent->child == NULL) {
            parent->child = folder;
        } else {
            folder_t *current_folder = parent->child;
            while (current_folder->next != NULL) {
                current_folder = current_folder->next;
            }
            current_folder->next = folder;
        }
    }

    return folder;
}


/**
 * @brief Создание новыго файла
 * @param name Имя файла.
 * @param type Тип файла.
 * @param parent Папка файла.
 * @return Указатель на файл.
 */
file_t *create_file(const char *name, const char *type, folder_t *parent) {
    file_t *file = malloc(sizeof(file_t));

    file->data = NULL;
    file->size = 0;
    strcpy(file->name, name);
    strcpy(file->type, type);
    file->next = NULL;

    if (parent->files == NULL) {
        parent->files = file;
    } else {
        file_t *current_file = parent->files;
        while (current_file->next != NULL) {
            current_file = current_file->next;
        }
        current_file->next = file;
    }

    return file;
}


/**
 * @brief Запись в файл.
 * @param file Файл.
 * @param data Буффер с данными.
 * @param size Размер буффера.
 */
void write_file(file_t *file, const char *data, size_t size) {
    if (file->data == NULL) {
        file->data = malloc(size);
    } else {
        file->data = realloc(file->data, file->size + size);
    }
    memcpy(file->data + file->size, data, size);
    file->size += size;
}


/**
 * @brief Чтение из файла.
 * @param file Файл.
 * @param buffer Буффер для вывода.
 * @param size Размер данных для чтения.
 */
void read_file(file_t *file, char *buffer, size_t size) {
    memcpy(buffer, file->data, size);
}


/**
 * @brief Удаление файла.
 * @param file Файл.
 */
void delete_file(file_t *file) {
    if (file->data != NULL) {
        free(file->data);
    }
    free(file);
}


/**
 * @brief Удаление папки рекурсивно.
 * @param folder Папка.
 */
void delete_folder(folder_t *folder) {
    while (folder->files != NULL) {
        file_t *file = folder->files;
        folder->files = file->next;
        delete_file(file);
    }

    while (folder->child != NULL) {
        folder_t *child_folder = folder->child;
        folder->child = child_folder->next;
        delete_folder(child_folder);
    }

    if (folder->parent == NULL) {
        root_folder = NULL;
    } else {
        folder_t *parent_folder = folder->parent;
        if (parent_folder->child == folder) {
            parent_folder->child = folder->next;
        } else {
            folder_t *current_folder = parent_folder->child;
            while (current_folder->next != folder) {
                current_folder = current_folder->next;
            }
            current_folder->next = folder->next;
        }
    }

    free(folder);
}


/**
 * @brief Вывод содержимого папки.
 * @param folder Папка.
 * @param depth Глубина.
 */
void print_folder_contents(folder_t *folder, size_t depth) {
    for (size_t i = 0; i < depth; i++) {
        printf("  ");
    }
    printf("- %s/\n", folder->name);
    
    file_t *file = folder->files;

    while (file != NULL) {
        for (size_t i = 0; i < depth + 1; i++) {
            printf("  ");
        }
        printf("- %s.%s\n", file->name, file->type);
        file = file->next;
    }
    
    folder_t *child_folder = folder->child;

    while (child_folder != NULL) {
        print_folder_contents(child_folder, depth + 1);
        child_folder = child_folder->next;
    }
}



/**
 * @brief Главная функция
 * @param argc Количество аргументов.
 * @param argv Аргументы.
 * @return 0 если все работает.
 */
int main(int argc, char **argv) {
    create_folder("", NULL);

    folder_t *cache_f = create_folder("cache", root_folder);
    folder_t *docs_f = create_folder("docs", root_folder);

    create_file("readme", "text", root_folder);
    create_file("kernel", "elf", root_folder);

    create_file("keyboard", "temp", cache_f);
    create_file("kernel", "temp", cache_f);
    create_file("network", "temp", cache_f);
    
    create_file("SynapseOS user manual", "text", docs_f);

    print_folder_contents(root_folder, 0);

    return 0;
}

#include <stdlib.h>
#include <string.h>


#define MAX_FILE_NAME_LEN 256 
#define MAX_FILE_TYPE_LEN 16 

typedef unsigned char folder_type_t; 


/**
 * @brief Структура файла.
 */
typedef struct file_t {
    char  *data; 
    size_t size; 
    char   name[MAX_FILE_NAME_LEN]; 
    char   type[MAX_FILE_TYPE_LEN]; 
    struct file_t *next; 
} file_t;


/**
 * @brief Структура папки.
 */
typedef struct folder_t {
    char name[MAX_FILE_NAME_LEN]; 
    struct folder_t *parent; 
    struct folder_t *child; 
    struct folder_t *next; 
    file_t *files; 
} folder_t;