hbc/channel/channelapp/source/isfs.c
2016-11-23 14:35:12 +09:00

130 lines
2.5 KiB
C

#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <gccore.h>
#include "../config.h"
#include "blob.h"
#include "panic.h"
#include "isfs.h"
#define ROUNDUP32B(x) ((x + 32 - 1) & ~(32 - 1))
static fstats __st ATTRIBUTE_ALIGN(32);
s32 isfs_get(const char *path, u8 **buf, u32 expected, u32 maxsize, bool use_blob) {
s32 ret;
s32 fd;
u8 *__buf;
gprintf("reading %s (expecting %lu bytes)\n", path, expected);
ret = ISFS_Open(path, ISFS_OPEN_READ);
if (ret < 0) {
gprintf("ISFS_Open failed (%ld)\n", ret);
return ret;
}
fd = ret;
ret = ISFS_GetFileStats(fd, &__st);
if (ret < 0) {
gprintf("ISFS_GetFileStats failed (%ld)\n", ret);
return ret;
}
DCInvalidateRange(&__st, sizeof(__st));
if ((__st.file_length == 0) ||
(maxsize && (__st.file_length > maxsize)) ||
(expected && (__st.file_length != expected))) {
gprintf("invalid size: %lu\n", __st.file_length);
ISFS_Close(fd);
return -1;
}
if (use_blob) {
__buf = blob_alloc(ROUNDUP32B(__st.file_length + 1));
if (!__buf)
panic();
} else {
__buf = pmemalign(32, ROUNDUP32B(__st.file_length + 1));
}
gprintf("reading %lu bytes\n", __st.file_length);
ret = ISFS_Read(fd, __buf, __st.file_length);
if (ret < 0) {
gprintf("ISFS_Read failed (%ld)\n", ret);
free(__buf);
ISFS_Close(fd);
return ret;
}
DCInvalidateRange(__buf, __st.file_length + 1);
__buf[__st.file_length] = 0;
if (ret != __st.file_length) {
gprintf("ISFS_Read short read (%ld)\n", ret);
free(__buf);
ISFS_Close(fd);
return -1;
}
ret = ISFS_Close(fd);
if (ret < 0) {
gprintf("ISFS_Close failed (%ld)\n", ret);
free(__buf);
return ret;
}
*buf = __buf;
return __st.file_length;
}
s32 isfs_put(const char *path, const void *buf, u32 len) {
s32 fd, ret;
ISFS_Delete(path);
gprintf("writing %s (%lu bytes)\n", path, len);
ret = ISFS_CreateFile(path, 0, 3, 3, 0);
if (ret < 0) {
gprintf("ISFS_CreateFile failed (%ld)\n", ret);
return ret;
}
ret = ISFS_Open(path, 3);
if (ret < 0) {
gprintf("ISFS_Open failed (%ld)\n", ret);
ISFS_Delete(path);
return ret;
}
fd = ret;
DCFlushRange((void *) buf, len);
ret = ISFS_Write(fd, buf, len);
if (ret < 0) {
gprintf("ISFS_Write failed (%ld)\n", ret);
ISFS_Close(fd);
ISFS_Delete(path);
return ret;
}
if (ret != len) {
gprintf("ISFS_Write short write (%ld)\n", ret);
ISFS_Close(fd);
ISFS_Delete(path);
return -1;
}
ret = ISFS_Close(fd);
if (ret < 0) {
gprintf("ISFS_Close failed (%ld)\n", ret);
ISFS_Delete(path);
return ret;
}
return 0;
}