assets VFS
This commit is contained in:
parent
2b9b92dac7
commit
e6eff20e82
249
os/assets.c
Normal file
249
os/assets.c
Normal file
@ -0,0 +1,249 @@
|
||||
/*************************************************************************
|
||||
* *
|
||||
* YAP Prolog *
|
||||
* *
|
||||
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
||||
* *
|
||||
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
||||
* *
|
||||
**************************************************************************
|
||||
* *
|
||||
* File: assets.c *
|
||||
* Last rev: 5/2/88 *
|
||||
* mods: *
|
||||
* comments: Asset Support in ANDROID *
|
||||
* *
|
||||
*************************************************************************/
|
||||
#ifdef SCCSA
|
||||
static char SccsId[] = "%W% %G%";
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file assets.c
|
||||
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
|
||||
* @date Thu Nov 19 10:53:20 2015
|
||||
*
|
||||
* @brief File Aliases
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "sysbits.h"
|
||||
// for native asset manager
|
||||
#include <sys/types.h>
|
||||
|
||||
#if __ANDROID__
|
||||
|
||||
|
||||
static AAssetManager * getMgr(struct vfs *me)
|
||||
{
|
||||
return me->priv[0].mgr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Java_pt_up_yap_app_YAPDroid_load(JNIEnv *env,
|
||||
jobject assetManager) {
|
||||
|
||||
AAssetManager *mgr = AAssetManager_fromJava(env, assetManager);
|
||||
if (mgr == NULL) {
|
||||
return;
|
||||
}
|
||||
VFS_t *me = GLOBAL_VFS;
|
||||
while ( strcmp(me->name, "/assets") == 0)
|
||||
me = me->next;
|
||||
me->priv[0].mgr = mgr;
|
||||
|
||||
}
|
||||
|
||||
static bool
|
||||
open_asset(struct vfs *me, struct stream_desc *st, const char *fname, const char
|
||||
*io_mode)
|
||||
{
|
||||
AAssetManager *mgr;
|
||||
int mode;
|
||||
const void *buf;
|
||||
if (strstr(fname,"/assets") == fname) {
|
||||
// we're in
|
||||
mgr = getMgr(me);
|
||||
if (mgr == NULL) {
|
||||
return PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, TermNil,
|
||||
"asset manager",
|
||||
fname);
|
||||
}
|
||||
if (strchr(io_mode, 'w') || strchr(io_mode, 'a')) {
|
||||
return PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, TermNil,
|
||||
"%s: no writing but flags are %s",
|
||||
fname, io_mode);
|
||||
}
|
||||
if (strchr(io_mode, 'B'))
|
||||
mode = AASSET_MODE_BUFFER;
|
||||
else
|
||||
{
|
||||
mode = AASSET_MODE_UNKNOWN;
|
||||
}
|
||||
AAsset *a = AAssetManager_open(mgr , fname, mode);
|
||||
// try not to use it as an asset
|
||||
off64_t sz = AAsset_getLength64(a), sz0 = 0;
|
||||
int fd;
|
||||
if ((fd = AAsset_openFileDescriptor64(a, &sz0, &sz)) >= 0) {
|
||||
// can use it as red-only file
|
||||
st->file = fdopen( fd, "r");
|
||||
st->vfs = me;
|
||||
st->vfs_handle = a;
|
||||
return true;
|
||||
} else if ((buf = AAsset_getBuffer(a)) ) {
|
||||
// copy to memory
|
||||
bool rc = Yap_set_stream_to_buf(st, buf, sz);
|
||||
AAsset_close(a);
|
||||
return rc;
|
||||
}
|
||||
// should be done, but if not
|
||||
st->vfs_handle = a;
|
||||
st->vfs = me;
|
||||
return true;
|
||||
}
|
||||
if (me->next) {
|
||||
return me->next->open(me->next, st, fname, io_mode);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
close_asset(struct stream_desc *st)
|
||||
{
|
||||
AAsset_close(st->vfs_handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int64_t seek64(struct stream_desc *st, int64_t offset, int whence)
|
||||
{
|
||||
return AAsset_seek64(st->vfs_handle, offset, whence);
|
||||
}
|
||||
|
||||
static int getc_asset(struct stream_desc *st)
|
||||
{
|
||||
int ch;
|
||||
if ( AAsset_read (st->vfs_handle, &ch, 1) )
|
||||
return ch;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void *opendir_a(struct vfs *me, const char *dirName)
|
||||
{
|
||||
return (void *)AAssetManager_openDir (getMgr(me), dirName);
|
||||
}
|
||||
|
||||
static const char *readdir_a(void *dirHandle)
|
||||
{
|
||||
return AAssetDir_getNextFileName ((AAssetDir *)dirHandle);
|
||||
}
|
||||
|
||||
static bool closedir_a(void *dirHandle)
|
||||
{
|
||||
AAssetDir_close ((AAssetDir *)dirHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool stat_a(struct vfs *me, const char *fname, vfs_stat *out)
|
||||
{
|
||||
struct stat64 bf;
|
||||
if (stat64( "/assets", &bf)) {
|
||||
|
||||
out->st_dev = bf.st_dev;
|
||||
out->st_uid = bf.st_uid;
|
||||
out->st_gid = bf.st_gid;
|
||||
memcpy(&out->st_atimespec, (const void *)&out->st_atimespec, sizeof(struct timespec));
|
||||
memcpy(&out->st_mtimespec,(const void *) &out->st_mtimespec, sizeof(struct timespec));
|
||||
memcpy(&out->st_ctimespec, (const void *)&out->st_ctimespec, sizeof(struct timespec));
|
||||
memcpy(&out->st_birthtimespec, (const void *)&out->st_birthtimespec, sizeof(struct timespec));
|
||||
}
|
||||
AAssetManager *mgr = getMgr(me);
|
||||
AAsset *a = AAssetManager_open(mgr , fname, AASSET_MODE_UNKNOWN);
|
||||
// try not to use it as an asset
|
||||
out->st_size = AAsset_getLength64(a);
|
||||
AAsset_close(a);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
bool is_dir_a(struct vfs *me, const char *dirName)
|
||||
{
|
||||
bool rc;
|
||||
// try not to use it as an asset
|
||||
AAssetDir *d = AAssetManager_openDir (getMgr(me), dirName);
|
||||
if (d == NULL)
|
||||
return false;
|
||||
rc = (AAssetDir_getNextFileName(d) != NULL);
|
||||
AAssetDir_close(d);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static
|
||||
bool exists_a(struct vfs *me, const char *dirName)
|
||||
{
|
||||
// try not to use it as an asset
|
||||
AAsset *d = AAssetManager_open (getMgr(me), dirName, AASSET_MODE_UNKNOWN);
|
||||
if (d == NULL)
|
||||
return false;
|
||||
AAsset_close(d);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool set_cwd (struct vfs *me, const char *dirName) {
|
||||
|
||||
chdir("/assets");
|
||||
if (me->virtual_cwd)
|
||||
free(me->virtual_cwd);
|
||||
me->virtual_cwd = malloc( sizeof(dirName) + 1 );
|
||||
return me!= NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* create a new alias arg for stream sno */
|
||||
VFS_t *
|
||||
Yap_InitAssetManager(void)
|
||||
{
|
||||
|
||||
#if __ANDROID__
|
||||
VFS_t *me;
|
||||
/* init standard VFS */
|
||||
me = (VFS_t *)Yap_AllocCodeSpace(sizeof(struct vfs));
|
||||
me->name = "/assets";
|
||||
me->vflags = VFS_CAN_EXEC|VFS_CAN_SEEK|VFS_HAS_PREFIX; /// the main flags describing the operation of the Fs.
|
||||
me->prefix = "/assets";
|
||||
/** operations */
|
||||
me->open = open_asset; /// open an object in this space
|
||||
me->close= close_asset; /// close the object
|
||||
me->get_char = getc_asset; /// get an octet to the stream
|
||||
me->putc = NULL; /// output an octet to the stream
|
||||
me->seek = seek64; /// jump around the stream
|
||||
me->opendir = opendir_a; /// open a directory object, if one exists
|
||||
me->nextdir = readdir_a; /// open a directory object, if one exists
|
||||
me->closedir = closedir_a; /// close access a directory object
|
||||
me->stat = stat_a; /// obtain size, age, permissions of a file.
|
||||
me->isdir = is_dir_a; /// obtain size, age, permissions of a file.
|
||||
me->exists = exists_a; /// obtain size, age, permissions of a file.
|
||||
me->chdir = set_cwd; /// chnage working directory.
|
||||
me->enc = ENC_ISO_UTF8; /// how the file is encoded.
|
||||
me->parsers = NULL; /// a set of parsers that can read the stream and generate a term
|
||||
me->writers = NULL;
|
||||
LOCK(BGL);
|
||||
me-> next = GLOBAL_VFS;
|
||||
GLOBAL_VFS = me;
|
||||
return me;
|
||||
UNLOCK(BGL);
|
||||
return me;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user