YAP 7.1.0
assets.c
Go to the documentation of this file.
1/*************************************************************************
2 * *
3 * YAP Prolog *
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8 * *
9 **************************************************************************
10 * *
11 * File: assets.c *
12 * Last rev: 5/2/88 *
13 * mods: *
14 * comments: Asset Support in ANDROID *
15 * *
16 *************************************************************************/
17#ifdef SCCSA
18static char SccsId[] = "%W% %G%";
19#endif
20
31#include <stdbool.h>
32#include "sysbits.h"
33// for native asset manager
34#include <sys/types.h>
35
36
37#if __ANDROID__
38
39#include <jni.h>
40#include <android/asset_manager.h>
41#include <android/native_activity.h>
42
43
44extern X_API void
45Java_pt_up_yap_yapdroid_YAPDroid_loadAssetManager(JNIEnv *env, jclass clazz, jobject assetManager);
46
47jobject *Yap_aref;
48JNIEnv *Yap_env;
49
50AAssetManager *Yap_assetManager(void)
51{
52 return AAssetManager_fromJava(Yap_env, Yap_aref);
53}
54
55X_API void
56Java_pt_up_yap_yapdroid_YAPDroid_loadAssetManager(JNIEnv *env, jclass clazz, jobject assetManager) {
57 Yap_aref = (*env)->NewGlobalRef(env,assetManager);
58 Yap_env = env;
59}
60
61
62static void *
63open_asset(VFS_t *me, const char *fname, const char *io_mode, int sno) {
64 int mode;
65 const void *buf;
66
67 AAsset *am = NULL;
68 //__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s-%s <%s>", fname, me->prefix,io_mode);
69 if (strchr(io_mode, 'B')) {
70 mode = AASSET_MODE_BUFFER;
71 } else {
72 mode = AASSET_MODE_UNKNOWN;
73 }
74 GLOBAL_Stream[sno].name = Yap_LookupAtom(fname);
75 fname += strlen(me->prefix)+1;
76// strcpy(dir, fname);
77// AAssetDir *dp = AAssetManager_openDir( Yap_assetManager(), dirname(dir) );
78// strcpy(dir, fname);
79// char *d = basename(dir);
80 am = AAssetManager_open(Yap_assetManager(), fname, AASSET_MODE_UNKNOWN);
81 //if (am==NULL)
82 // __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "failed open %s <%s>", fname, strerror(errno) );
83 __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", fname, io_mode);
84// while (dp) {
85// char *f = AAssetDir_getNextFileName(dp);
86// __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "open %s <%s>", fname, mode);
87// if (f && strcasecmp(d,f) == 0) {
88//
89// }
90// }
91 if (!am) {
92 __android_log_print(ANDROID_LOG_INFO, "YAPDroid", "failed %s <%s>", fname, io_mode);
93
94 return NULL;
95 }
96 // try not to use it as an asset
97 off64_t sz = AAsset_getLength64(am), sz0 = 0;
98 int fd;
99 StreamDesc *st = GLOBAL_Stream + sno;
100 if ((buf = AAsset_getBuffer(am))) {
101 // copy to memory
102 char *bf = malloc(sz);
103 memmove(bf, buf, sz);
104 bool rc = Yap_set_stream_to_buf(st, bf, sz);
105 if (rc) AAsset_close(am);
106 st->vfs = NULL;
107 st->vfs_handle = NULL;
108 st->status = InMemory_Stream_f|Seekable_Stream_f|Input_Stream_f;
109 return st;
110 } else if ((fd = AAsset_openFileDescriptor64(am, &sz0, &sz)) >= 0) {
111 // can use it as read-only file
112 st->file = fdopen(fd, "r");
113 st->vfs = NULL;
114 st->vfs_handle = NULL;
115 st->status = Seekable_Stream_f|Input_Stream_f;
116 return st->file;
117 } else {
118 // should be done, but if not
119 GLOBAL_Stream[sno].vfs_handle = am;
120 st->vfs = me;
121 st->status = Input_Stream_f;
122 return am;
123 }
124}
125
126static bool
127close_asset(int sno) {
128 AAsset_close(GLOBAL_Stream[sno].vfs_handle);
129 return true;
130}
131
132static int64_t seek64(int sno, int64_t offset, int whence) {
133 return AAsset_seek64(GLOBAL_Stream[sno].vfs_handle, offset, whence);
134}
135
136static int getc_asset(int sno) {
137 int ch;
138 if (AAsset_read(GLOBAL_Stream[sno].vfs_handle, &ch, 1))
139 return ch;
140 return -1;
141}
142
143
144static void *opendir_a(VFS_t *me, const char *dirName) {
145 dirName += strlen(me->prefix) + 1;
146 return (void *) AAssetManager_openDir(Yap_assetManager(), dirName);
147}
148
149static const char *readdir_a(void *dirHandle) {
150 return AAssetDir_getNextFileName((AAssetDir *) dirHandle);
151}
152
153static bool closedir_a(void *dirHandle) {
154 AAssetDir_close((AAssetDir *) dirHandle);
155 return true;
156}
157
158
159static bool stat_a(VFS_t *me, const char *fname, vfs_stat *out) {
160 struct stat bf;
161 fname += strlen(me->prefix) + 1;
162 if (stat("/assets", &bf)) {
163 out->st_mode = me ->vflags ;
164 out->st_dev = bf.st_dev;
165 out->st_uid = bf.st_uid;
166 out->st_gid = bf.st_gid;
167 memmove(&out->st_atimespec, (const void *) &bf.st_atim, sizeof(struct timespec));
168 memmove(&out->st_mtimespec, (const void *) &bf.st_mtim, sizeof(struct timespec));
169 memmove(&out->st_ctimespec, (const void *) &bf.st_ctim, sizeof(struct timespec));
170 memmove(&out->st_birthtimespec, (const void *) &bf.st_ctim,
171 sizeof(struct timespec));
172 }
173 AAsset *a = AAssetManager_open(Yap_assetManager(), fname, AASSET_MODE_UppppppppNKNOWN);
174 // try not to use it as an asset
175 if (!a)
176 return false;
177 out->st_size = AAsset_getLength64(a);
178 AAsset_close(a);
179 return true;
180
181}
182
183static
184bool is_dir_a(VFS_t *me, const char *dirName) {
185 dirName += strlen(me->prefix)+1;
186 if (dirName[0] == '\0')
187 return true;
188 // try not to use it as an asset
189 AAssetDir *d = AAssetManager_openDir(Yap_assetManager(), dirName);
190 if (d == NULL || AAssetDir_getNextFileName(d) == NULL)
191 return false;
192 (AAssetDir_close(d));
193 //__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "isdir %s <%p>", dirName, d);
194
195 return true;
196}
197
198static
199bool exists_a(VFS_t *me, const char *dirName) {
200 dirName += strlen(me->prefix) + 1;
201 // try not to use it as an asset
202 AAsset *d = AAssetManager_open(Yap_assetManager(), dirName, AASSET_MODE_UNKNOWN);
203 //__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exists %s <%p>", dirName, d);
204 if (d == NULL)
205 return false;
206 AAsset_close(d);
207 return true;
208}
209
210
211char *virtual_cwd;
212
213static bool set_cwd(VFS_t *me, const char *dirName) {
214
215 chdir("/assets");
216 if (GLOBAL_cwd) {
217 free(GLOBAL_cwd);
218 }
219 if (!is_dir_a(me,dirName))
220 dirName = dirname(dirName);
221 GLOBAL_cwd = malloc(strlen(dirName)+1);
222 strcpy(GLOBAL_cwd, dirName);
223//__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "chdir %s", GLOBAL_cwd);
224return true;
225}
226
227#endif
228
229
230VFS_t *
232
233#if __ANDROID__
234 VFS_t *me;
235 /* init standard VFS */
236 me = (VFS_t *) Yap_AllocCodeSpace(sizeof(struct vfs));
237 me->name = "/assets";
238 me->vflags = VFS_CAN_EXEC | VFS_CAN_SEEK | VFS_CAN_READ |
239 VFS_HAS_PREFIX;
240 me->prefix = "/assets";
242 me->open = open_asset;
243 me->close = close_asset;
244 me->get_char = getc_asset;
245 me->put_char = NULL;
246 me->seek = seek64;
247 me->opendir = opendir_a;
248 me->nextdir = readdir_a;
249 me->closedir = closedir_a;
250 me->stat = stat_a;
251 me->isdir = is_dir_a;
252 me->exists = exists_a;
253 me->chdir = set_cwd;
254 me->enc = ENC_ISO_UTF8;
255 me->parsers = NULL;
256 me->writers = NULL;
257 GLOBAL_cwd = NULL;
258 LOCK(BGL);
259 me->next = GLOBAL_VFS;
260 GLOBAL_VFS = me;
261 return me;
262 UNLOCK(BGL);
263 return me;
264#else
265 return NULL;
266#endif
267}
268
269
VFS_t * Yap_InitAssetManager(void)
Definition: assets.c:231
void * vfs_handle
stream belongs to a space
Definition: YapStreams.h:260
struct vfs * vfs
function the stream uses for reading a character
Definition: YapStreams.h:259
Definition: VFS.h:36
Definition: VFS.h:74
void *(* open)(struct vfs *, const char *fname, const char *io_mode, int sno)
operations
Definition: VFS.h:82
void *(* opendir)(struct vfs *, const char *s)
jump around the stream
Definition: VFS.h:96
bool(* stat)(struct vfs *, const char *s, vfs_stat *)
close access a directory object
Definition: VFS.h:102
int64_t(* seek)(int sno, int64_t offset, int whence)
flush a stream
Definition: VFS.h:94
bool(* close)(int sno)
open an object
Definition: VFS.h:86
YAP_Term(* parsers)(int sno)
default file encoded
Definition: VFS.h:109
const char * prefix
the main flags describing the operation of the Fs
Definition: VFS.h:78
bool(* exists)(struct vfs *, const char *s)
verify whether is directory
Definition: VFS.h:105
int(* put_char)(int sno, int ch)
unget an octet from the stream
Definition: VFS.h:91
bool(* chdir)(struct vfs *, const char *s)
verify whether a file exists
Definition: VFS.h:106
const char *(* nextdir)(void *d)
open a directory object, if one exists
Definition: VFS.h:98
int(* get_char)(int sno)
close the object
Definition: VFS.h:87
uintptr_t vflags
A text that explains the file system.
Definition: VFS.h:76
bool(* isdir)(struct vfs *, const char *s)
obtain size, age, permissions of a file
Definition: VFS.h:104
bool(* closedir)(void *d)
walk to the next entry in a directory object
Definition: VFS.h:100
encoding_t enc
set working directory (may be virtual)
Definition: VFS.h:108