Major update, both design and implementation
This commit is contained in:
1 parent
ac7c44e70d
commit
e5d9d51870
5 files changed
+316
-406
No files matched your search
+141
-275
@@ -10,6 +10,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "lsfs_string.h"
|
||||||
|
|
||||||
typedef struct Directory_Table Directory_Table;
|
typedef struct Directory_Table Directory_Table;
|
||||||
typedef struct struct_table_entry struct_table_entry;
|
typedef struct struct_table_entry struct_table_entry;
|
||||||
typedef struct struct_partition_control partition_control;
|
typedef struct struct_partition_control partition_control;
|
||||||
@@ -18,6 +20,7 @@ typedef struct File_System_Control_Information FSCI;
|
|||||||
typedef struct meta_information_format mif;
|
typedef struct meta_information_format mif;
|
||||||
typedef struct tag_record tag_record;
|
typedef struct tag_record tag_record;
|
||||||
typedef struct lsfs_file lsfs_file;
|
typedef struct lsfs_file lsfs_file;
|
||||||
|
typedef enum Table_Entry_Kind Table_Entry_Kind;
|
||||||
|
|
||||||
typedef uint64_t lsfs_sector_offset;
|
typedef uint64_t lsfs_sector_offset;
|
||||||
typedef lsfs_sector_offset lsfs_file_id;
|
typedef lsfs_sector_offset lsfs_file_id;
|
||||||
@@ -27,17 +30,13 @@ static FILE* disk;
|
|||||||
static partition_control p_control;
|
static partition_control p_control;
|
||||||
|
|
||||||
int create_file_system();
|
int create_file_system();
|
||||||
//lsfs_sector_offset lsfs_disk_create_tag(char* tag_name, bool is_filename);
|
int lsfs_disk_create_entry(const char* path, Table_Entry_Kind entry_kind);
|
||||||
lsfs_sector_offset lsfs_disk_create_file(char* filename, lsfs_file_id* tags, void* file_data);
|
|
||||||
int lsfs_disk_getattr(lsfs_file* find_file, const char *path);
|
int lsfs_disk_getattr(lsfs_file* find_file, const char *path);
|
||||||
//int lsfs_disk_untag_file(lsfs_file_id file_id, lsfs_file_id file_id);
|
|
||||||
//int lsfs_disk_tag_file(lsfs_file_id file_id, lsfs_file_id file_id);
|
|
||||||
//int lsfs_disk_delete_tag(lsfs_file_id file_id);
|
|
||||||
int lsfs_disk_delete_file(lsfs_file_id file_id);
|
int lsfs_disk_delete_file(lsfs_file_id file_id);
|
||||||
|
int get_free_sectors_table();
|
||||||
int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array);
|
int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array);
|
||||||
int lsfs_disk_read_data_from_file(lsfs_file* file, int buffer_size, void* buffer_for_data);
|
int lsfs_disk_read_data_from_file(lsfs_file* file, int buffer_size, void* buffer_for_data);
|
||||||
int lsfs_disk_write_data_to_file(lsfs_file* file, int data_length, char *data);
|
int lsfs_disk_write_data_to_file(lsfs_file* file, int data_length, char *data);
|
||||||
//int lsfs_disk_rename_tag(lsfs_file_id file_id, char* new_filename);
|
|
||||||
int lsfs_disk_rename_file(lsfs_file* file, const char* new_filename);
|
int lsfs_disk_rename_file(lsfs_file* file, const char* new_filename);
|
||||||
int lsfs_disk_load_disk();
|
int lsfs_disk_load_disk();
|
||||||
int write_data_to_disk(lsfs_sector_offset at_sector, uint32_t file_block_size, void* data_to_write);
|
int write_data_to_disk(lsfs_sector_offset at_sector, uint32_t file_block_size, void* data_to_write);
|
||||||
@@ -45,20 +44,19 @@ int read_data_from_disk(lsfs_sector_offset index, uint32_t file_block_size, void
|
|||||||
int write_data_to_disk_off(lsfs_sector_offset index, void* data_to_write, int offset);
|
int write_data_to_disk_off(lsfs_sector_offset index, void* data_to_write, int offset);
|
||||||
int save_modified_file_information(lsfs_file* file);
|
int save_modified_file_information(lsfs_file* file);
|
||||||
|
|
||||||
|
|
||||||
#define SECTOR_SIZE 512
|
#define SECTOR_SIZE 512
|
||||||
#define NUMBER_OF_MBR_PARTITIONS 4
|
#define NUMBER_OF_MBR_PARTITIONS 4
|
||||||
#define DEFAULT_FILE_SIZE 4 // This is in sectors
|
#define DEFAULT_FILE_SIZE 4 // This is in sectors
|
||||||
#define DEFAULT_MASTER_TABLE_SIZE 64
|
#define DEFAULT_TABLE_SIZE 10
|
||||||
#define DEFAULT_TAG_TABLE_SIZE 64 // correspond to 262144 bytes in sectors - 16384 files pr. default. (minus one, the last is a pointer to a table more )
|
|
||||||
#define MAX_MASTER_TAGS 57825
|
|
||||||
#define MAX_TAGS_IN_TAG_TABLE 16384
|
|
||||||
#define MAX_TAGS_FOR_A_FILE 32
|
|
||||||
#define NUM_DATA_POINTERS 28
|
#define NUM_DATA_POINTERS 28
|
||||||
|
|
||||||
//#define MAX_NUM_TWO_LEVEL_DATA 94 // First Mib of a file.
|
typedef enum Table_Entry_Kind
|
||||||
//#define MAX_NUM_THREE_LEVEL_DATA 94 // First Mib of a file.
|
{
|
||||||
|
// These are specific values since, is has to corrospond to the implementation in assembly
|
||||||
|
ENTRY_EMPTY = 0,
|
||||||
|
ENTRY_FILE = 1,
|
||||||
|
ENTRY_DIRECTORY = 2,
|
||||||
|
} Table_Entry_Kind;
|
||||||
|
|
||||||
typedef struct Partition_Entry
|
typedef struct Partition_Entry
|
||||||
{
|
{
|
||||||
@@ -101,13 +99,15 @@ typedef struct Directory_Table
|
|||||||
typedef struct File_System_Control_Information
|
typedef struct File_System_Control_Information
|
||||||
{
|
{
|
||||||
char filesyste_information[256];
|
char filesyste_information[256];
|
||||||
uint64_t offset_on_disk;
|
uint64_t master_table_index;
|
||||||
|
uint64_t this_partition_offset_on_disk;
|
||||||
uint64_t next_free_sector;
|
uint64_t next_free_sector;
|
||||||
|
uint64_t next_uniqe_id; // both files and directories gets this.
|
||||||
uint64_t next_sector_reuse_pointer;
|
uint64_t next_sector_reuse_pointer;
|
||||||
uint64_t last_sector_index_on_partition;
|
uint64_t last_sector_index_on_partition;
|
||||||
uint64_t maximum_sectors_on_disk;
|
uint64_t maximum_sectors_on_disk;
|
||||||
uint64_t sectors_size_on_disk;
|
uint64_t sectors_size_on_disk;
|
||||||
uint64_t not_used[26];
|
uint64_t not_used[24];
|
||||||
|
|
||||||
} __attribute__((packed)) FSCI;
|
} __attribute__((packed)) FSCI;
|
||||||
|
|
||||||
@@ -120,15 +120,15 @@ typedef struct struct_partition_control
|
|||||||
|
|
||||||
|
|
||||||
typedef struct meta_information_format {
|
typedef struct meta_information_format {
|
||||||
char filename[246]; // remeber that the 246 bytes has to be a /0 terminator..
|
char filename[246]; // remeber that the 246 bytes has to be a /0 terminator..
|
||||||
uint32_t owner_id;
|
uint32_t owner_id;
|
||||||
lsfs_file_id tags[32];
|
lsfs_file_id tags[32];
|
||||||
uint64_t file_size;
|
uint64_t file_size;
|
||||||
uint32_t control_bits;
|
uint32_t control_bits;
|
||||||
/* not pressent - Permission key table 64 bytes sha-265 pr. key*/
|
/* not pressent - Permission key table 64 bytes sha-265 pr. key*/
|
||||||
uint64_t creation_date;
|
uint64_t creation_date;
|
||||||
uint64_t last_modification_data;
|
uint64_t last_modification_data;
|
||||||
uint64_t last_access_date;
|
uint64_t last_access_date;
|
||||||
/*
|
/*
|
||||||
* 256 first pointers in direct mapping to data
|
* 256 first pointers in direct mapping to data
|
||||||
* 94 next pointers is a pointer
|
* 94 next pointers is a pointer
|
||||||
@@ -153,6 +153,7 @@ typedef struct tag_record {
|
|||||||
typedef struct lsfs_file {
|
typedef struct lsfs_file {
|
||||||
lsfs_file_id file_id;
|
lsfs_file_id file_id;
|
||||||
lsfs_sector_offset table_entry_pointer;
|
lsfs_sector_offset table_entry_pointer;
|
||||||
|
Table_Entry_Kind entry_kind;
|
||||||
char* filename;
|
char* filename;
|
||||||
uint32_t owner_id;
|
uint32_t owner_id;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
@@ -173,6 +174,7 @@ int lsfs_disk_getattr(lsfs_file* find_file, const char* path) {
|
|||||||
time ( ¤t_time );
|
time ( ¤t_time );
|
||||||
|
|
||||||
find_file->file_id = p_control.master_table.entries[i].file_id;
|
find_file->file_id = p_control.master_table.entries[i].file_id;
|
||||||
|
find_file->entry_kind = p_control.master_table.entries[i].entry_kind;
|
||||||
find_file->table_entry_pointer = i;
|
find_file->table_entry_pointer = i;
|
||||||
find_file->filename = p_control.master_table.entries[i].filename;
|
find_file->filename = p_control.master_table.entries[i].filename;
|
||||||
find_file->owner_id = getuid();
|
find_file->owner_id = getuid();
|
||||||
@@ -277,23 +279,6 @@ time_t lsfs_disk_truncate_file(lsfs_file *file, off_t offset) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int lsfs_disk_rename_tag(lsfs_file_id file_id, char* new_filename) {
|
|
||||||
// for (int i = 0; i < MAX_MASTER_TAGS; ++i)
|
|
||||||
// {
|
|
||||||
// if(p_control.master_table.entries[i].file_id == file_id) {
|
|
||||||
// memset(p_control.master_table.entries[i].filename, 0, sizeof(p_control.master_table.entries[i].filename));
|
|
||||||
// sprintf(p_control.master_table.entries[i].filename, "%s", new_filename);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // free the sectors including the tag table
|
|
||||||
|
|
||||||
// // Save the changes to disk
|
|
||||||
// fseek ( disk , (p_control.fsci.master_tag_records[0] * SECTOR_SIZE) , SEEK_SET );
|
|
||||||
// fwrite(p_control.master_table, 1, sizeof(table_entry) * DEFAULT_MASTER_TABLE_SIZE, disk);
|
|
||||||
// return 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
int lsfs_disk_rename_file(lsfs_file* file, const char* new_filename) {
|
int lsfs_disk_rename_file(lsfs_file* file, const char* new_filename) {
|
||||||
|
|
||||||
memset(file->filename, 0, 256);
|
memset(file->filename, 0, 256);
|
||||||
@@ -314,13 +299,7 @@ int lsfs_disk_delete_file(lsfs_file_id file_id) {
|
|||||||
mif* mif_record = calloc(1, SECTOR_SIZE);
|
mif* mif_record = calloc(1, SECTOR_SIZE);
|
||||||
read_data_from_disk(file_id, 1, mif_record);
|
read_data_from_disk(file_id, 1, mif_record);
|
||||||
|
|
||||||
for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i)
|
|
||||||
{
|
|
||||||
if(mif_record->tags[i] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//lsfs_disk_untag_file(mif_record->tags[i], file_id);
|
|
||||||
}
|
|
||||||
// TODO Delete/free all data sectors.
|
// TODO Delete/free all data sectors.
|
||||||
// Delete/free the mif record sector.
|
// Delete/free the mif record sector.
|
||||||
|
|
||||||
@@ -328,189 +307,44 @@ int lsfs_disk_delete_file(lsfs_file_id file_id) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*int lsfs_disk_delete_tag(lsfs_file_id file_id) {
|
int get_free_sectors_table() {
|
||||||
tag_record* tag_table = calloc(64, SECTOR_SIZE);
|
// We need DEFAULT_TABLE_SIZE sectors straight contigious for a table
|
||||||
read_data_from_disk(file_id, tag_table);
|
// Otherwise the file system cannot make a new table.
|
||||||
|
// We return the offset where the table is starting.
|
||||||
|
// If we cannot assing DEFAULT_TABLE_SIZE sectors, we report errror.
|
||||||
|
|
||||||
for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i)
|
int return_index = p_control.fsci.next_free_sector;
|
||||||
|
|
||||||
|
if ((p_control.fsci.next_free_sector + DEFAULT_TABLE_SIZE) > p_control.fsci.last_sector_index_on_partition)
|
||||||
{
|
{
|
||||||
if(tag_table[i].mif_record == 0) {
|
// We don't have space, report error
|
||||||
break;
|
return -EINVAL;
|
||||||
}
|
|
||||||
lsfs_disk_untag_file(file_id, tag_table[i].mif_record);
|
|
||||||
}
|
}
|
||||||
|
p_control.fsci.next_free_sector += DEFAULT_TABLE_SIZE;
|
||||||
|
|
||||||
|
fseek ( disk , (p_control.fsci.this_partition_offset_on_disk) * SECTOR_SIZE, SEEK_SET );
|
||||||
|
fwrite(&p_control.fsci, 1, SECTOR_SIZE, disk);
|
||||||
|
|
||||||
int truncate_table = 0;
|
return return_index;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_MASTER_TAGS; ++i)
|
|
||||||
{
|
|
||||||
if(p_control.master_table.entries[i].file_id == file_id) {
|
|
||||||
p_control.master_table.entries[i] = p_control.master_table[i+1];
|
|
||||||
truncate_table = 1;
|
|
||||||
printf("Tag deleted from master table - TagID: %lu\n", file_id);
|
|
||||||
}
|
|
||||||
else if (truncate_table) {
|
|
||||||
p_control.master_table.entries[i] = p_control.master_table[i+1];
|
|
||||||
if (p_control.master_table[i+1].file_id == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the sectors including the tag table
|
|
||||||
|
|
||||||
// Save the changes to disk
|
|
||||||
fseek ( disk , (p_control.fsci.master_tag_records[0] * SECTOR_SIZE) , SEEK_SET );
|
|
||||||
fwrite(p_control.master_table, 1, sizeof(table_entry) * DEFAULT_MASTER_TABLE_SIZE, disk);
|
|
||||||
free(tag_table);
|
|
||||||
return 1;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*int lsfs_disk_tag_file(lsfs_file_id file_id, lsfs_file_id file_id) {
|
|
||||||
mif* mif_record = calloc(1, SECTOR_SIZE);
|
|
||||||
read_data_from_disk(file_id, mif_record);
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i)
|
|
||||||
{
|
|
||||||
if(mif_record->tags[i] == 0) {
|
|
||||||
mif_record->tags[i] = file_id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_data_to_disk(file_id, mif_record);
|
|
||||||
free(mif_record);
|
|
||||||
|
|
||||||
tag_record* tag_table = calloc(64, SECTOR_SIZE);
|
|
||||||
read_data_from_disk(file_id, tag_table);
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i)
|
|
||||||
{
|
|
||||||
if(tag_table[i].mif_record == 0) {
|
|
||||||
tag_table[i].mif_record = file_id;
|
|
||||||
printf("file tagged - TagID: %lu - FileID: %lu \n", tag_table[i].mif_record, file_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_data_to_disk(file_id, tag_table);
|
|
||||||
free(tag_table);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*int lsfs_disk_untag_file(lsfs_file_id file_id, lsfs_file_id file_id) {
|
|
||||||
mif* mif_record = calloc(1, SECTOR_SIZE);
|
|
||||||
read_data_from_disk(file_id, mif_record);
|
|
||||||
int truncate_table = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_TAGS_FOR_A_FILE; ++i)
|
|
||||||
{
|
|
||||||
if(mif_record->tags[i] == file_id) {
|
|
||||||
mif_record->tags[i] = mif_record->tags[i+1];
|
|
||||||
truncate_table = 1;
|
|
||||||
printf("file untagged - TagID: %lu - FileID: %lu \n", file_id, file_id);
|
|
||||||
}
|
|
||||||
else if (truncate_table) {
|
|
||||||
mif_record->tags[i] = mif_record->tags[i+1];
|
|
||||||
if (mif_record->tags[i+1] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t current_time;
|
|
||||||
time ( ¤t_time );
|
|
||||||
|
|
||||||
mif_record->last_modification_data = (uint64_t) current_time;
|
|
||||||
mif_record->last_access_date = (uint64_t) current_time;
|
|
||||||
|
|
||||||
write_data_to_disk(file_id, mif_record);
|
|
||||||
free(mif_record);
|
|
||||||
|
|
||||||
tag_record* tag_table = calloc(64, SECTOR_SIZE);
|
|
||||||
read_data_from_disk(file_id, tag_table);
|
|
||||||
truncate_table = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_TAGS_IN_TAG_TABLE; ++i)
|
|
||||||
{
|
|
||||||
if(tag_table[i].mif_record == file_id) {
|
|
||||||
tag_table[i].mif_record = tag_table[i+1].mif_record;
|
|
||||||
truncate_table = 1;
|
|
||||||
printf("file untagged - TagID: %lu - FileID: %lu \n", tag_table[i].mif_record, file_id);
|
|
||||||
}
|
|
||||||
else if (truncate_table) {
|
|
||||||
tag_table[i].mif_record = tag_table[i+1].mif_record;
|
|
||||||
if (tag_table[i+1].mif_record == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_data_to_disk(file_id, tag_table);
|
|
||||||
free(tag_table);
|
|
||||||
return 1;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*lsfs_file_id lsfs_disk_create_tag(char* tag_name, bool is_filename) {
|
|
||||||
// Return ID of new tag, oterwise return 0
|
|
||||||
lsfs_file_id* free_sectors;
|
|
||||||
// Returns an array, with the sector numbers that is assignt to you
|
|
||||||
free_sectors = calloc(DEFAULT_TAG_TABLE_SIZE, sizeof(lsfs_file_id));
|
|
||||||
get_free_sectors(DEFAULT_TAG_TABLE_SIZE, free_sectors); // has to be freed
|
|
||||||
|
|
||||||
// Insert tag in the master tag, table an set the pointer to the first of the tag table
|
|
||||||
int index_in_mtt = 0;
|
|
||||||
while(p_control.master_table[index_in_mtt].file_id != 0) {
|
|
||||||
//TODO also have to count if we enter next data section.
|
|
||||||
index_in_mtt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
p_control.master_table[index_in_mtt].file_id = free_sectors[0];
|
|
||||||
printf("%lu\n", free_sectors[0]);
|
|
||||||
sprintf(p_control.master_table[index_in_mtt].filename, "%s", tag_name);
|
|
||||||
p_control.master_table[index_in_mtt].control_bits.is_filename = is_filename;
|
|
||||||
|
|
||||||
tag_record new_tag[DEFAULT_TAG_TABLE_SIZE];
|
|
||||||
memset(new_tag, 0, (DEFAULT_TAG_TABLE_SIZE * sizeof(tag_record)));
|
|
||||||
|
|
||||||
//printf("Sector number: %lu, is assignt to you \n", (*free_sectors));
|
|
||||||
//char* data = "red_file_1\nred_file_2\n";
|
|
||||||
//char* sector_to_write = write_mechanism_new_buffer(data);
|
|
||||||
fseek ( disk , (p_control.fsci.master_tag_records[0] * SECTOR_SIZE) , SEEK_SET );
|
|
||||||
fwrite(p_control.master_table, 1, sizeof(table_entry) * DEFAULT_MASTER_TABLE_SIZE, disk);
|
|
||||||
|
|
||||||
fseek ( disk , ((*free_sectors) * SECTOR_SIZE) , SEEK_SET );
|
|
||||||
fwrite(new_tag, 1, DEFAULT_TAG_TABLE_SIZE * sizeof(tag_record), disk);
|
|
||||||
|
|
||||||
//free(sector_to_write);
|
|
||||||
int return_value = free_sectors[0];
|
|
||||||
free(free_sectors);
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array) {
|
int get_free_sectors(int num_sectors_needed, lsfs_sector_offset* output_array) {
|
||||||
/*
|
|
||||||
* TODO - WARNING
|
|
||||||
* This has to be a much better algoritm, to pick free sctors.
|
|
||||||
* We have to keep some bookeeping of what is free.
|
|
||||||
* Also if more sctors are claimed, we want them to be sequtive.
|
|
||||||
* This is just a naiv counter, just added more sectors to the file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (num_sectors_needed > 1) {
|
if ((p_control.fsci.next_free_sector + num_sectors_needed) > p_control.fsci.last_sector_index_on_partition )
|
||||||
for (int i = 0; i < num_sectors_needed; ++i)
|
{
|
||||||
{
|
// We cannot assign what we want.
|
||||||
output_array[i] = p_control.fsci.next_free_sector;
|
return -EINVAL;
|
||||||
p_control.fsci.next_free_sector++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
for (int i = 0; i < num_sectors_needed; ++i)
|
||||||
output_array[0] = p_control.fsci.next_free_sector;
|
{
|
||||||
p_control.fsci.next_free_sector++;
|
output_array[i] = p_control.fsci.next_free_sector;
|
||||||
|
p_control.fsci.next_free_sector += DEFAULT_FILE_SIZE;
|
||||||
}
|
}
|
||||||
printf("Sector %lu is assignt\n", output_array[0]);
|
|
||||||
write_data_to_disk(0, 4, &p_control.fsci);
|
fseek ( disk , (p_control.fsci.this_partition_offset_on_disk) * SECTOR_SIZE, SEEK_SET );
|
||||||
return p_control.fsci.next_free_sector;
|
fwrite(&p_control.fsci, 1, SECTOR_SIZE, disk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_file_system() {
|
int create_file_system() {
|
||||||
@@ -522,7 +356,7 @@ int create_file_system() {
|
|||||||
// we need the first number to allocate memory at one go.
|
// we need the first number to allocate memory at one go.
|
||||||
int* zero_buffer;
|
int* zero_buffer;
|
||||||
FSCI fsci;
|
FSCI fsci;
|
||||||
fsci.offset_on_disk = 1;
|
fsci.this_partition_offset_on_disk = 1;
|
||||||
//fsci.maximum_sectors_on_partition = 1048576; // Max 4GiB
|
//fsci.maximum_sectors_on_partition = 1048576; // Max 4GiB
|
||||||
fsci.next_free_sector = 257;
|
fsci.next_free_sector = 257;
|
||||||
|
|
||||||
@@ -533,8 +367,8 @@ int create_file_system() {
|
|||||||
free(zero_buffer);
|
free(zero_buffer);
|
||||||
/* MASTER TAG TABLE */
|
/* MASTER TAG TABLE */
|
||||||
|
|
||||||
table_entry master_table[DEFAULT_MASTER_TABLE_SIZE];
|
table_entry master_table[DEFAULT_TABLE_SIZE];
|
||||||
memset(master_table, 0, (DEFAULT_MASTER_TABLE_SIZE * sizeof(table_entry)));
|
memset(master_table, 0, (DEFAULT_TABLE_SIZE * sizeof(table_entry)));
|
||||||
|
|
||||||
fwrite(&master_table, 1, sizeof(master_table), disk);
|
fwrite(&master_table, 1, sizeof(master_table), disk);
|
||||||
zero_buffer = calloc(1, 16);
|
zero_buffer = calloc(1, 16);
|
||||||
@@ -561,10 +395,12 @@ int lsfs_disk_load_disk() {
|
|||||||
// First we find the File system control information.
|
// First we find the File system control information.
|
||||||
fseek ( disk , mbr.partitions[i].LBA_abs_first_sector * SECTOR_SIZE, SEEK_SET );
|
fseek ( disk , mbr.partitions[i].LBA_abs_first_sector * SECTOR_SIZE, SEEK_SET );
|
||||||
fread(&p_control.fsci, 1, SECTOR_SIZE , disk);
|
fread(&p_control.fsci, 1, SECTOR_SIZE , disk);
|
||||||
|
//printf("next free sector: %d\n", p_control.fsci.next_free_sector);
|
||||||
|
//printf("next free ID: %d\n", p_control.fsci.next_uniqe_id);
|
||||||
|
|
||||||
// next we find the Mater Table.
|
// next we find the Mater Table.
|
||||||
fseek ( disk , (mbr.partitions[i].LBA_abs_first_sector + 1) * SECTOR_SIZE, SEEK_SET );
|
fseek ( disk , (mbr.partitions[i].LBA_abs_first_sector + 1) * SECTOR_SIZE, SEEK_SET );
|
||||||
fread(&p_control.master_table, 1, 10 * SECTOR_SIZE , disk);
|
fread(&p_control.master_table, 1, DEFAULT_TABLE_SIZE * SECTOR_SIZE , disk);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -573,62 +409,92 @@ int lsfs_disk_load_disk() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lsfs_file_id lsfs_disk_create_file(char* filename, lsfs_file_id* tags, void* file_data) {
|
int lsfs_disk_create_entry(const char* path, Table_Entry_Kind entry_kind)
|
||||||
|
{
|
||||||
|
|
||||||
// create space for mif
|
lsfs_string_array split_path = lsfs_string_split_c(path, '/', false);
|
||||||
mif new_file_data;
|
lsfs_string filename = split_path.strings[split_path.length-1];
|
||||||
lsfs_file_id return_id;
|
|
||||||
|
|
||||||
|
// Start from the master table
|
||||||
memset(new_file_data.filename, 0, sizeof(new_file_data.filename));
|
int free_index = -1; // -1 is no index found.
|
||||||
sprintf(new_file_data.filename, "%s", filename); // remeber that the 260 bytes has to be a /0 terminator. // 260 because it pads to a full sector.
|
Directory_Table *dir_table = &p_control.master_table;
|
||||||
|
lsfs_sector_offset table_disk_position = p_control.fsci.master_table_index;
|
||||||
printf("%s\n", new_file_data.filename);
|
for (int i = 0; i < split_path.length; ++i)
|
||||||
new_file_data.owner_id = getuid();
|
{
|
||||||
|
for (int j = 0; j < DEFAULT_TABLE_SIZE; ++j)
|
||||||
lsfs_file_id* index_to_mif_data;
|
{
|
||||||
index_to_mif_data = calloc(1, sizeof(lsfs_file_id));
|
if (i == (split_path.length - 1))
|
||||||
get_free_sectors(1, index_to_mif_data); // has to be freed
|
{
|
||||||
|
// Find free index and be sure that there dosent exist a file with the same name.
|
||||||
memset(new_file_data.tags, 0, (32 * sizeof(lsfs_file_id)));
|
if (dir_table->entries[j].entry_kind == ENTRY_EMPTY)
|
||||||
|
{
|
||||||
new_file_data.file_size = 0;
|
// Set the free index, continue to see if the filename exist.
|
||||||
|
// if not -1, we have found a better index.
|
||||||
time_t current_time;
|
if (free_index == -1)
|
||||||
time ( ¤t_time );
|
{
|
||||||
|
printf("Index found for file: %d\n", j);
|
||||||
new_file_data.creation_date = (uint64_t) current_time;
|
free_index = j;
|
||||||
new_file_data.last_modification_data = (uint64_t) current_time;
|
}
|
||||||
new_file_data.last_access_date = (uint64_t) current_time;
|
}
|
||||||
|
else if (strcmp(dir_table->entries[j].filename, split_path.strings[0].chars) == 0)
|
||||||
new_file_data.control_bits = 0;
|
{
|
||||||
memset(new_file_data.one_level_pointer_data, 0, (256 * sizeof(lsfs_sector_offset)));
|
// Abort mission, we have a file with the same name.
|
||||||
memset(new_file_data.two_level_pointer_data, 0, (94 * sizeof(lsfs_sector_offset)));
|
return -EINVAL;
|
||||||
memset(new_file_data.three_level_pointer_data, 0, (94 * sizeof(lsfs_sector_offset)));
|
}
|
||||||
get_free_sectors(1, new_file_data.one_level_pointer_data);
|
}
|
||||||
int actual_file_size = 0;
|
else
|
||||||
|
{
|
||||||
new_file_data.file_size = actual_file_size;
|
if (strcmp(dir_table->entries[j].filename, split_path.strings[0].chars) == 0)
|
||||||
fseek ( disk , index_to_mif_data[0] * SECTOR_SIZE, SEEK_SET );
|
{
|
||||||
fwrite(&new_file_data, 1, SECTOR_SIZE, disk);
|
// We have found the next directory to traverse.
|
||||||
|
;
|
||||||
printf("MIF written at sector: %lu\n", index_to_mif_data[0]);
|
}
|
||||||
printf("DATA written at sector: %lu\n", new_file_data.one_level_pointer_data[0]);
|
}
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
if (tags != NULL) {
|
|
||||||
while(tags[i] != 0) {
|
|
||||||
printf("A tag is found \n");
|
|
||||||
//lsfs_disk_tag_file(tags[i], index_to_mif_data[0]);
|
|
||||||
new_file_data.tags[i] = tags[i];
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (free_index == -1)
|
||||||
|
{
|
||||||
|
// The table is full, and we cannot create an entry
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
return_id = index_to_mif_data[0];
|
// Find the entry for the file in the table structure:
|
||||||
free(index_to_mif_data);
|
dir_table->entries[free_index].file_id = p_control.fsci.next_uniqe_id;
|
||||||
return return_id;
|
p_control.fsci.next_uniqe_id++;
|
||||||
|
|
||||||
|
sprintf(dir_table->entries[free_index].filename, "%s", filename.chars);
|
||||||
|
dir_table->entries[free_index].entry_kind = entry_kind;
|
||||||
|
if (entry_kind == ENTRY_DIRECTORY)
|
||||||
|
{
|
||||||
|
dir_table->entries[free_index].data_pointer[0] = get_free_sectors_table();
|
||||||
|
dir_table->entries[free_index].file_size = 5120;
|
||||||
|
}
|
||||||
|
else if (entry_kind == ENTRY_FILE)
|
||||||
|
{
|
||||||
|
// We assign one data pointer consiting of DEFAULT_FILE_SIZE sectors
|
||||||
|
get_free_sectors_table(1, dir_table->entries[free_index].data_pointer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
find_file->creation_date = (uint64_t) current_time;
|
||||||
|
find_file->access_time = (uint64_t) current_time;
|
||||||
|
find_file->modification_time = (uint64_t) current_time;
|
||||||
|
find_file->data = p_control.master_table.entries[i].data_pointer;
|
||||||
|
find_file->owner_id = getuid();
|
||||||
|
new_file_data.owner_id = getuid();
|
||||||
|
time_t current_time;
|
||||||
|
time ( ¤t_time );
|
||||||
|
*/
|
||||||
|
|
||||||
|
fseek ( disk , (table_disk_position + free_index) * SECTOR_SIZE, SEEK_SET );
|
||||||
|
fwrite(&dir_table->entries[free_index], 1, SECTOR_SIZE, disk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_modified_file_information(lsfs_file* file) {
|
int save_modified_file_information(lsfs_file* file) {
|
||||||
|
|||||||
+23
-131
@@ -1,8 +1,3 @@
|
|||||||
/*
|
|
||||||
TODO(jakob): we have a lot of memory leaks
|
|
||||||
TODO(jakob): handle multiple files with the same name!!!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fuse.h>
|
#include <fuse.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -51,8 +46,7 @@ static struct fuse_operations lsfs_oper = {
|
|||||||
int lsfs_mkdir(const char *path, mode_t mode) {
|
int lsfs_mkdir(const char *path, mode_t mode) {
|
||||||
(void)mode;
|
(void)mode;
|
||||||
|
|
||||||
// Call to the disk controller make the dir
|
return lsfs_disk_create_entry(path, ENTRY_DIRECTORY);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -100,7 +94,19 @@ int lsfs_getattr( const char *path, struct stat *stbuf ) {
|
|||||||
stbuf->st_nlink = 2;
|
stbuf->st_nlink = 2;
|
||||||
} else {
|
} else {
|
||||||
if(lsfs_disk_getattr(found_file, path)) {
|
if(lsfs_disk_getattr(found_file, path)) {
|
||||||
stbuf->st_mode = S_IFREG | 0777; // @Hardcode
|
if (found_file->entry_kind == ENTRY_FILE)
|
||||||
|
{
|
||||||
|
stbuf->st_mode = S_IFREG | 0777;
|
||||||
|
}
|
||||||
|
else if (found_file->entry_kind == ENTRY_DIRECTORY)
|
||||||
|
{
|
||||||
|
stbuf->st_mode = S_IFDIR | 0755;
|
||||||
|
stbuf->st_nlink = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = -ENOENT;
|
||||||
|
}
|
||||||
stbuf->st_nlink = 1; // @Hardcode
|
stbuf->st_nlink = 1; // @Hardcode
|
||||||
stbuf->st_size = found_file->size;
|
stbuf->st_size = found_file->size;
|
||||||
stbuf->st_uid = found_file->owner_id;
|
stbuf->st_uid = found_file->owner_id;
|
||||||
@@ -114,78 +120,7 @@ int lsfs_getattr( const char *path, struct stat *stbuf ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*else {
|
|
||||||
if (lsfs_disk_getattr(found_file, path)) {
|
|
||||||
stbuf->st_mode = S_IFREG | 0777; // @Hardcode
|
|
||||||
stbuf->st_nlink = 1; // @Hardcode
|
|
||||||
stbuf->st_size = found_file->size;
|
|
||||||
stbuf->st_uid = found_file->owner_id;
|
|
||||||
stbuf->st_gid = found_file->owner_id;
|
|
||||||
stbuf->st_atime = found_file->access_time;
|
|
||||||
stbuf->st_mtime = found_file->modification_time;
|
|
||||||
free(found_file);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = -ENOENT;
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
// printf("getattr: (path=%s)\n", path);
|
|
||||||
|
|
||||||
/*memset(stbuf, 0, sizeof(struct stat));
|
|
||||||
|
|
||||||
if( strcmp( path, "/" ) == 0 ) {
|
|
||||||
stbuf->st_mode = S_IFDIR | 0755;
|
|
||||||
stbuf->st_nlink = 3;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
lsfs_string_array split_path = lsfs_string_split_c(path, '/', false);
|
|
||||||
|
|
||||||
lsfs_string filename = split_path.strings[split_path.length-1];
|
|
||||||
|
|
||||||
lsfs_tag *filename_tag = lsfs_hash_find(globals.tag_table, filename);
|
|
||||||
|
|
||||||
if (filename_tag) {
|
|
||||||
if (filename_tag->is_filename) {
|
|
||||||
lsfs_file *found_file = lsfs_find_unique_file(filename_tag, split_path);
|
|
||||||
|
|
||||||
if (found_file) {
|
|
||||||
if (found_file == &dummy_ambiguous_file) {
|
|
||||||
// stbuf->st_mode = S_IFDIR | 0755; // @Hardcode
|
|
||||||
// stbuf->st_nlink = 3; // @Hardcode
|
|
||||||
res = -ENOENT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
stbuf->st_mode = S_IFREG | 0777; // @Hardcode
|
|
||||||
stbuf->st_nlink = 1; // @Hardcode
|
|
||||||
|
|
||||||
stbuf->st_size = found_file->size; // @Hardcode
|
|
||||||
stbuf->st_uid = found_file->owner_id;
|
|
||||||
stbuf->st_gid = found_file->owner_id;
|
|
||||||
stbuf->st_atime = found_file->access_time;
|
|
||||||
stbuf->st_mtime = found_file->modification_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = -ENOENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
stbuf->st_mode = S_IFDIR | 0755; // @Hardcode
|
|
||||||
stbuf->st_nlink = 3; // @Hardcode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res = -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
lsfs_destroy_string_array(split_path);
|
|
||||||
*/
|
|
||||||
//return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lsfs_write(const char *path, const char *content, size_t content_length, off_t offset_to_next_entry, struct fuse_file_info *file_info) {
|
int lsfs_write(const char *path, const char *content, size_t content_length, off_t offset_to_next_entry, struct fuse_file_info *file_info) {
|
||||||
@@ -216,12 +151,13 @@ int lsfs_readdir( const char *path, void *buf, fuse_fill_dir_t filler, off_t off
|
|||||||
filler(buf, ".", NULL, 0);
|
filler(buf, ".", NULL, 0);
|
||||||
filler(buf, "..", NULL, 0);
|
filler(buf, "..", NULL, 0);
|
||||||
|
|
||||||
int i = 0;
|
for (int i = 0; i < DEFAULT_TABLE_SIZE; ++i)
|
||||||
while(strcmp( "", p_control.master_table.entries[i].filename ) != 0) {
|
{
|
||||||
filler(buf, p_control.master_table.entries[i].filename, NULL, 0);
|
if (strcmp( "", p_control.master_table.entries[i].filename ) != 0)
|
||||||
i++;
|
{
|
||||||
|
filler(buf, p_control.master_table.entries[i].filename, NULL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,59 +194,15 @@ int lsfs_release(const char *path, struct fuse_file_info *fi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lsfs_mknod(const char *path, mode_t mode, dev_t device) {
|
int lsfs_mknod(const char *path, mode_t mode, dev_t device) {
|
||||||
/*(void)mode;
|
(void)mode;
|
||||||
(void)device;
|
(void)device;
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
lsfs_string_array split_path = lsfs_string_split_c(path, '/', false);
|
return lsfs_disk_create_entry(path, ENTRY_FILE);
|
||||||
|
|
||||||
lsfs_string filename = split_path.strings[split_path.length-1];
|
|
||||||
if(filename.chars[0] == '@') {
|
|
||||||
res = -EINVAL;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
lsfs_file *file = NULL;
|
|
||||||
|
|
||||||
lsfs_tag *filename_tag = lsfs_hash_find(globals.tag_table, filename);
|
|
||||||
if (filename_tag) {
|
|
||||||
file = lsfs_find_unique_file(filename_tag, split_path);
|
|
||||||
if (file == &dummy_ambiguous_file) file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file) {
|
|
||||||
res = -EINVAL;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
lsfs_file_id file_id = lsfs_disk_create_file(filename.chars, NULL, NULL );
|
|
||||||
lsfs_set *tagset = lsfs_create_set(split_path.length - 1);
|
|
||||||
filename_tag = lsfs_get_or_create_tag(filename, true, true);
|
|
||||||
|
|
||||||
file = lsfs_create_file(filename, file_id, tagset, filename_tag);
|
|
||||||
|
|
||||||
lsfs_hash_table_index *index = malloc(sizeof(*index));
|
|
||||||
*index = lsfs_hash_insert(globals.file_table, lsfs_create_id_string(file_id), file);
|
|
||||||
lsfs_set_insert(&filename_tag->fileset, file->file_id, index);
|
|
||||||
lsfs_disk_tag_file(filename_tag->tag_id, file->file_id);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < split_path.length - 1; ++i) {
|
|
||||||
lsfs_string tag_name = split_path.strings[i];
|
|
||||||
lsfs_tag *tag = lsfs_get_or_create_tag(tag_name, true, false);
|
|
||||||
lsfs_tag_file(tag, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
lsfs_set_insert(&globals.all_files, file_id, index);
|
|
||||||
|
|
||||||
end:
|
|
||||||
lsfs_destroy_string_array(split_path);
|
|
||||||
return res;*/
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main( int argc, char *argv[] ) {
|
int main( int argc, char *argv[] ) {
|
||||||
// "/home/rhodez-x/Documents/github/SingOS/SingOS.img"
|
// "/home/rhodez-x/Documents/github/SingOS/SingOS.img"
|
||||||
disk = fopen ("/home/rhodez-x/Documents/github/SingOS/SingOS.img", "r+b");
|
disk = fopen ("/home/rhodezx/Documents/github/SingOS/SingOS.img", "r+b");
|
||||||
if (lsfs_disk_load_disk())
|
if (lsfs_disk_load_disk())
|
||||||
{
|
{
|
||||||
return fuse_main( argc, argv, &lsfs_oper );
|
return fuse_main( argc, argv, &lsfs_oper );
|
||||||
|
|||||||
BIN
Binary file not shown.
+152
@@ -0,0 +1,152 @@
|
|||||||
|
#ifndef LSFS_STRING_H
|
||||||
|
#define LSFS_STRING_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct lsfs_string {
|
||||||
|
bool dynamic;
|
||||||
|
unsigned int length;
|
||||||
|
char *chars;
|
||||||
|
} lsfs_string;
|
||||||
|
|
||||||
|
typedef struct lsfs_string_array {
|
||||||
|
unsigned int length;
|
||||||
|
lsfs_string *strings;
|
||||||
|
} lsfs_string_array;
|
||||||
|
|
||||||
|
|
||||||
|
static inline lsfs_string lsfs_make_id_string(uint64_t *id) {
|
||||||
|
return (lsfs_string){
|
||||||
|
.dynamic = false,
|
||||||
|
.length = sizeof(*id),
|
||||||
|
.chars = (char *)id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lsfs_string lsfs_create_id_string(uint64_t id) {
|
||||||
|
uint64_t *id_ = malloc(sizeof(id));
|
||||||
|
*id_ = id;
|
||||||
|
return (lsfs_string){
|
||||||
|
.dynamic = true,
|
||||||
|
.length = sizeof(id),
|
||||||
|
.chars = (char *)id_
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lsfs_string lsfs_make_string(unsigned int length, const char *chars) {
|
||||||
|
return (lsfs_string){
|
||||||
|
.dynamic = false,
|
||||||
|
.length = length,
|
||||||
|
.chars = (char *)chars
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lsfs_string lsfs_make_string_c(const char *cstring) {
|
||||||
|
return lsfs_make_string(strlen(cstring), cstring);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lsfs_string lsfs_create_string(unsigned int length, const char *chars) {
|
||||||
|
|
||||||
|
char *copy = malloc(length + 1); // Space for null terminator
|
||||||
|
memcpy(copy, chars, length);
|
||||||
|
copy[length] = '\0';
|
||||||
|
|
||||||
|
return (lsfs_string){
|
||||||
|
.dynamic = true,
|
||||||
|
.length = length,
|
||||||
|
.chars = copy
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lsfs_string lsfs_clone_string(lsfs_string string) {
|
||||||
|
return lsfs_create_string(string.length, string.chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lsfs_destroy_string(lsfs_string string) {
|
||||||
|
if(string.dynamic) free(string.chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool lsfs_string_equal(lsfs_string a, lsfs_string b) {
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
return strncmp(a.chars, b.chars, b.length) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsfs_string_array lsfs_create_string_array(size_t array_size) {
|
||||||
|
lsfs_string_array result;
|
||||||
|
result.length = array_size;
|
||||||
|
result.strings = malloc(array_size * sizeof(lsfs_string));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lsfs_destroy_string_array(lsfs_string_array array) {
|
||||||
|
for (unsigned int i = 0; i < array.length; ++i) {
|
||||||
|
lsfs_destroy_string(array.strings[i]);
|
||||||
|
}
|
||||||
|
free(array.strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lsfs_string_array lsfs_string_split(lsfs_string string, char delim, bool keep_delim) {
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int last;
|
||||||
|
|
||||||
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
last = 0;
|
||||||
|
while(i < string.length) {
|
||||||
|
if (string.chars[i] == delim) {
|
||||||
|
if (i > last+1) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (i > last+1) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsfs_string_array result = lsfs_create_string_array(count);
|
||||||
|
|
||||||
|
unsigned int insert_index = 0;
|
||||||
|
int k = keep_delim ? 0 : 1;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
last = 0;
|
||||||
|
while(i < string.length) {
|
||||||
|
if (string.chars[i] == delim) {
|
||||||
|
if (i > last+1) {
|
||||||
|
result.strings[insert_index++] = lsfs_create_string(i-(last+k), string.chars+(last+k));
|
||||||
|
}
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (i > last+1) {
|
||||||
|
result.strings[insert_index++] = lsfs_create_string(i-(last+k), string.chars+(last+k));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lsfs_string_array lsfs_string_split_c(const char *string, char delim, bool keep_delim) {
|
||||||
|
return lsfs_string_split(lsfs_make_string_c(string), delim, keep_delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *dbg_strarr(lsfs_string_array strings) {
|
||||||
|
static char temp[8192];
|
||||||
|
memset(temp, 0, sizeof(temp));
|
||||||
|
|
||||||
|
int where = 0;
|
||||||
|
where += sprintf(temp+where, "{");
|
||||||
|
for (unsigned int i = 0; i < strings.length; ++i) {
|
||||||
|
where += sprintf(temp+where, "<'%.*s'>", strings.strings[i].length, strings.strings[i].chars);
|
||||||
|
}
|
||||||
|
where += sprintf(temp+where, "}");
|
||||||
|
|
||||||
|
return temp; // @Leak
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in new issue
Block a user