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