parent
845aba61ed
commit
1c736c3324
@ -0,0 +1,143 @@ |
|||||||
|
#include <stdint.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include <flash.h> |
||||||
|
#include <macros.h> |
||||||
|
|
||||||
|
#include <fs/mufs.h> |
||||||
|
|
||||||
|
#include "dir.h" |
||||||
|
#include "tree.h" |
||||||
|
|
||||||
|
struct mufs_file { |
||||||
|
struct mufs *fs; |
||||||
|
struct mufs_tree *tree; |
||||||
|
uint32_t va; |
||||||
|
}; |
||||||
|
|
||||||
|
int mufs_create(struct mufs *fs, const char *path) |
||||||
|
{ |
||||||
|
struct mufs_dirent dirent; |
||||||
|
struct mufs_tree *tree; |
||||||
|
size_t len; |
||||||
|
char *s; |
||||||
|
char *name; |
||||||
|
|
||||||
|
if (!path || *path == '\0') |
||||||
|
return -1; |
||||||
|
|
||||||
|
if (!(s = mufs_abspath(path))) |
||||||
|
return -1; |
||||||
|
|
||||||
|
/* TODO: already exists. */ |
||||||
|
if (resolve_path(fs, s)) { |
||||||
|
free(s); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (!(name = strrchr(s, '/'))) { |
||||||
|
name = s; |
||||||
|
s = "/"; |
||||||
|
} else { |
||||||
|
*name++ = '\0'; |
||||||
|
} |
||||||
|
|
||||||
|
if (*name == '\0') |
||||||
|
return -1; |
||||||
|
|
||||||
|
if (!(tree = resolve_path(fs, s))) |
||||||
|
return -1; |
||||||
|
|
||||||
|
len = min(strlen(name), sizeof(dirent.path) - 1); |
||||||
|
memcpy(dirent.path, name, len); |
||||||
|
dirent.path[len] = '\0'; |
||||||
|
dirent.type = MUFS_FILE; |
||||||
|
|
||||||
|
dirent.tree.fs = fs; |
||||||
|
dirent.tree.file_size = 0; |
||||||
|
dirent.tree.root = 0; |
||||||
|
dirent.tree.depth = 0; |
||||||
|
|
||||||
|
if (!is_aligned(tree->file_size, fs->dev->log2_block_size) && |
||||||
|
write_dirent(tree, tree->file_size, &dirent) > 0) |
||||||
|
return 0; |
||||||
|
|
||||||
|
if (write_dirent(tree, align_up(tree->file_size, |
||||||
|
fs->dev->log2_block_size), &dirent) > 0) |
||||||
|
return 0; |
||||||
|
|
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
struct mufs_file *mufs_open(struct mufs *fs, const char *path) |
||||||
|
{ |
||||||
|
struct mufs_file *file; |
||||||
|
|
||||||
|
if (!(file = malloc(sizeof(*file)))) |
||||||
|
return NULL; |
||||||
|
|
||||||
|
file->fs = fs; |
||||||
|
|
||||||
|
if (!(file->tree = resolve_path(fs, path))) |
||||||
|
goto err_free_file; |
||||||
|
|
||||||
|
file->va = 0; |
||||||
|
|
||||||
|
return file; |
||||||
|
|
||||||
|
err_free_file: |
||||||
|
free(file); |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void mufs_close(struct mufs_file *file) |
||||||
|
{ |
||||||
|
if (!file) |
||||||
|
return; |
||||||
|
|
||||||
|
free(file); |
||||||
|
} |
||||||
|
|
||||||
|
size_t mufs_read(struct mufs_file *file, void *data, size_t len) |
||||||
|
{ |
||||||
|
size_t ret; |
||||||
|
|
||||||
|
if (!file || !data || !len) |
||||||
|
return 0; |
||||||
|
|
||||||
|
if (!(ret = mufs_tree_read(file->tree, data, file->va, len))) |
||||||
|
return 0; |
||||||
|
|
||||||
|
file->va += ret; |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
size_t mufs_write(struct mufs_file *file, const void *data, size_t len) |
||||||
|
{ |
||||||
|
size_t ret; |
||||||
|
|
||||||
|
if (!file || !data || !len) |
||||||
|
return 0; |
||||||
|
|
||||||
|
if (!(ret = mufs_tree_write(file->tree, (void *)data, file->va, len))) |
||||||
|
return 0; |
||||||
|
|
||||||
|
file->va += ret; |
||||||
|
|
||||||
|
if (file->tree->file_size <= file->va) { |
||||||
|
struct mufs_dtree dtree; |
||||||
|
|
||||||
|
dtree.file_size = file->tree->file_size; |
||||||
|
dtree.root = file->tree->root; |
||||||
|
dtree.depth = file->tree->depth; |
||||||
|
|
||||||
|
if (flash_write(file->fs->dev, file->tree->va, &dtree, |
||||||
|
sizeof dtree) == 0) |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
return ret; |
||||||
|
} |
Loading…
Reference in new issue