5 #include "assman_impl.h"
7 static int add_fop(const char *prefix, int type, struct ass_fileops *fop);
8 static const char *match_prefix(const char *str, const char *prefix);
9 static int add_file(ass_file *file);
10 static int remove_file(ass_file *file);
12 #define DEF_FLAGS (1 << ASS_OPEN_FALLTHROUGH)
14 static unsigned int assflags = DEF_FLAGS;
15 static struct mount *mlist;
17 void ass_set_option(int opt, int val)
22 assflags &= ~(1 << opt);
26 int ass_get_option(int opt)
28 return assflags & (1 << opt);
31 int ass_add_path(const char *prefix, const char *path)
33 return add_fop(prefix, MOD_PATH, ass_alloc_path(path));
36 int ass_add_archive(const char *prefix, const char *arfile)
38 return add_fop(prefix, MOD_ARCHIVE, ass_alloc_archive(arfile));
41 int ass_add_url(const char *prefix, const char *url)
43 return add_fop(prefix, MOD_URL, ass_alloc_url(url));
46 int ass_add_user(const char *prefix, struct ass_fileops *fop)
48 return add_fop(prefix, MOD_USER, fop);
51 static int add_fop(const char *prefix, int type, struct ass_fileops *fop)
56 fprintf(stderr, "assman: failed to allocate asset source\n");
60 if(!(m = malloc(sizeof *m))) {
61 perror("assman: failed to allocate mount node");
65 if(!(m->prefix = malloc(strlen(prefix) + 1))) {
69 strcpy(m->prefix, prefix);
84 struct mount *m = mlist;
89 ass_free_path(m->fop);
92 ass_free_archive(m->fop);
106 ass_file *ass_fopen(const char *fname, const char *mode)
112 const char *after_prefix;
116 if((after_prefix = match_prefix(fname, m->prefix))) {
117 if((mfile = m->fop->open(after_prefix, m->fop->udata))) {
118 if(!(file = malloc(sizeof *file))) {
119 perror("assman: ass_fopen failed to allocate file structure");
120 m->fop->close(mfile, m->fop->udata);
126 if(add_file(file) == -1) {
127 m->fop->close(mfile, m->fop->udata);
133 if(!(assflags & (1 << ASS_OPEN_FALLTHROUGH))) {
141 /* nothing matched, or failed to open, try the filesystem */
142 if((fp = fopen(fname, mode))) {
143 if(!(file = malloc(sizeof *file))) {
145 perror("assman: ass_fopen failed to allocate file structure");
152 if(add_file(file) == -1) {
163 static const char *match_prefix(const char *str, const char *prefix)
165 if(!prefix || !*prefix) return str; /* match on null or empty prefix */
168 if(*prefix++ != *str++) {
175 void ass_fclose(ass_file *fp)
178 fp->fop->close(fp->file, fp->fop->udata);
186 long ass_fseek(ass_file *fp, long offs, int whence)
189 return fp->fop->seek(fp->file, offs, whence, fp->fop->udata);
192 if(fseek(fp->file, offs, whence) == -1) {
195 return ftell(fp->file);
198 long ass_ftell(ass_file *fp)
200 return ass_fseek(fp, 0, SEEK_CUR);
203 size_t ass_fread(void *buf, size_t size, size_t count, ass_file *fp)
206 long res = fp->fop->read(fp->file, buf, size * count, fp->fop->udata);
207 if(res <= 0) return 0;
211 return fread(buf, size, count, fp->file);
215 /* --- convenience functions --- */
217 int ass_fgetc(ass_file *fp)
221 if(ass_fread(&c, 1, 1, fp) < 1) {
227 char *ass_fgets(char *s, int size, ass_file *fp)
234 for(i=0; i<size - 1; i++) {
235 if((c = ass_fgetc(fp)) == -1) {
243 return ptr == s ? 0 : s;
247 static int add_file(ass_file *file)
249 return -1; /* TODO */
252 static int remove_file(ass_file *file)
254 return -1; /* TODO */