Skip to content

Commit

Permalink
JS: Refactor storage to use array buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
Willy-JL committed Apr 5, 2024
1 parent d4cd068 commit 309889e
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 21 deletions.
19 changes: 18 additions & 1 deletion applications/system/js_app/examples/apps/Scripts/storage.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
let storage = require("storage");
let path = "/ext/storage.test";

function arraybuf_to_string(arraybuf) {
let string = "";
let data_view = Uint8Array(arraybuf);
for (let i = 0; i < data_view.length; i++) {
string += chr(data_view[i]);
}
return string;
}

print("File exists:", storage.exists(path));

print("Writing...");
// write(path, data, offset)
// If offset is specified, the file is not cleared, content is kept and data is written at specified offset
// Takes both strings and array buffers
storage.write(path, "Hello ");

print("File exists:", storage.exists(path));

// Append will create the file even if it doesnt exist!
// Takes both strings and array buffers
storage.append(path, "World!");

print("Reading...");
// read(path, size, offset)
// If no size specified, total filesize is used
// If offset is specified, size is capped at (filesize - offset)
let data = storage.read(path);
print(data);
// read returns an array buffer, to allow proper usage of raw binary data
print(arraybuf_to_string(data));

print("Removing...")
storage.remove(path);
Expand Down
68 changes: 48 additions & 20 deletions applications/system/js_app/modules/js_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ static bool get_path_arg(struct mjs* mjs, const char** path) {

static void js_storage_read(struct mjs* mjs) {
JsStorageInst* storage = get_this_ctx(mjs);
if(!check_arg_count(mjs, 1)) return;

const char* path;
if(!get_path_arg(mjs, &path)) return;
Expand All @@ -62,15 +61,26 @@ static void js_storage_read(struct mjs* mjs) {
}

uint64_t size = storage_file_size(file);
if(size > 128 * 1024) {
ret_int_err(mjs, "File too large");
mjs_val_t size_arg = mjs_arg(mjs, 1);
if(mjs_is_number(size_arg)) {
size = mjs_get_int32(mjs, size_arg);
}

mjs_val_t seek_arg = mjs_arg(mjs, 2);
if(mjs_is_number(seek_arg)) {
storage_file_seek(file, mjs_get_int32(mjs, seek_arg), true);
size = MIN(size, storage_file_size(file) - storage_file_tell(file));
}

if(size > memmgr_heap_get_max_free_block()) {
ret_int_err(mjs, "Read size too large");
break;
}

uint8_t* data = malloc(size);
size_t read = storage_file_read(file, data, size);
if(read == size) {
mjs_return(mjs, mjs_mk_string(mjs, (const char*)data, size, true));
mjs_return(mjs, mjs_mk_array_buf(mjs, (char*)data, size));
} else {
ret_int_err(mjs, "File read failed");
}
Expand All @@ -81,27 +91,41 @@ static void js_storage_read(struct mjs* mjs) {

static void js_storage_write(struct mjs* mjs) {
JsStorageInst* storage = get_this_ctx(mjs);
if(!check_arg_count(mjs, 2)) return;

const char* path;
if(!get_path_arg(mjs, &path)) return;

mjs_val_t data_obj = mjs_arg(mjs, 1);
if(!mjs_is_string(data_obj)) {
ret_bad_args(mjs, "Data must be a string");
mjs_val_t data_arg = mjs_arg(mjs, 1);
if(!mjs_is_typed_array(data_arg) && !mjs_is_string(data_arg)) {
ret_bad_args(mjs, "Data must be string, arraybuf or dataview");
return;
}
if(mjs_is_data_view(data_arg)) {
data_arg = mjs_dataview_get_buf(mjs, data_arg);
}
size_t data_len = 0;
const char* data = mjs_get_string(mjs, &data_obj, &data_len);
if((data_len == 0) || (data == NULL)) {
ret_bad_args(mjs, "Bad data argument");
return;
const char* data = NULL;
if(mjs_is_string(data_arg)) {
data = mjs_get_string(mjs, &data_arg, &data_len);
} else if(mjs_is_typed_array(data_arg)) {
data = mjs_array_buf_get_ptr(mjs, data_arg, &data_len);
}

mjs_val_t seek_arg = mjs_arg(mjs, 2);

File* file = storage_file_alloc(storage->api);
if(!storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
if(!storage_file_open(
file,
path,
FSAM_WRITE,
mjs_is_number(seek_arg) ? FSOM_OPEN_ALWAYS : FSOM_CREATE_ALWAYS)) {
ret_int_err(mjs, storage_file_get_error_desc(file));

} else {
if(mjs_is_number(seek_arg)) {
storage_file_seek(file, mjs_get_int32(mjs, seek_arg), true);
}

size_t write = storage_file_write(file, data, data_len);
mjs_return(mjs, mjs_mk_boolean(mjs, write == data_len));
}
Expand All @@ -115,16 +139,20 @@ static void js_storage_append(struct mjs* mjs) {
const char* path;
if(!get_path_arg(mjs, &path)) return;

mjs_val_t data_obj = mjs_arg(mjs, 1);
if(!mjs_is_string(data_obj)) {
ret_bad_args(mjs, "Data must be a string");
mjs_val_t data_arg = mjs_arg(mjs, 1);
if(!mjs_is_typed_array(data_arg) && !mjs_is_string(data_arg)) {
ret_bad_args(mjs, "Data must be string, arraybuf or dataview");
return;
}
if(mjs_is_data_view(data_arg)) {
data_arg = mjs_dataview_get_buf(mjs, data_arg);
}
size_t data_len = 0;
const char* data = mjs_get_string(mjs, &data_obj, &data_len);
if((data_len == 0) || (data == NULL)) {
ret_bad_args(mjs, "Bad data argument");
return;
const char* data = NULL;
if(mjs_is_string(data_arg)) {
data = mjs_get_string(mjs, &data_arg, &data_len);
} else if(mjs_is_typed_array(data_arg)) {
data = mjs_array_buf_get_ptr(mjs, data_arg, &data_len);
}

File* file = storage_file_alloc(storage->api);
Expand Down

0 comments on commit 309889e

Please sign in to comment.