1a680e621f4745b54e49257f22e774c93ef464c6
[assman] / src / mod_path.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <errno.h>
6
7 #ifdef __MSVCRT__
8 #include <malloc.h>
9 #else
10 #include <alloca.h>
11 #endif
12
13 #include "assman_impl.h"
14
15
16 static void *fop_open(const char *fname, void *udata);
17 static void fop_close(void *fp, void *udata);
18 static long fop_seek(void *fp, long offs, int whence, void *udata);
19 static long fop_read(void *fp, void *buf, long size, void *udata);
20
21
22 struct ass_fileops *ass_alloc_path(const char *path)
23 {
24         char *p;
25         struct ass_fileops *fop;
26
27         if(!(fop = malloc(sizeof *fop))) {
28                 return 0;
29         }
30         if(!(p = malloc(strlen(path) + 1))) {
31                 free(fop);
32                 return 0;
33         }
34         fop->udata = p;
35
36         while(*path) {
37                 *p++ = *path++;
38         }
39         while(p > (char*)fop->udata && (p[-1] == '/' || isspace(p[-1]))) p--;
40         *p = 0;
41
42         fop->open = fop_open;
43         fop->close = fop_close;
44         fop->seek = fop_seek;
45         fop->read = fop_read;
46         return fop;
47 }
48
49 void ass_free_path(struct ass_fileops *fop)
50 {
51         free(fop->udata);
52 }
53
54 static void *fop_open(const char *fname, void *udata)
55 {
56         const char *prefix = (char*)udata;
57         char *path;
58         FILE *fp;
59
60         path = alloca(strlen(prefix) + strlen(fname) + 2);
61         sprintf(path, "%s/%s", path, fname);
62
63         if(!(fp = fopen(path, "rb"))) {
64                 ass_errno = errno;
65                 return 0;
66         }
67         return fp;
68 }
69
70 static void fop_close(void *fp, void *udata)
71 {
72         fclose(fp);
73 }
74
75 static long fop_seek(void *fp, long offs, int whence, void *udata)
76 {
77         fseek(fp, offs, whence);
78         return ftell(fp);
79 }
80
81 static long fop_read(void *fp, void *buf, long size, void *udata)
82 {
83         return fread(buf, 1, size, fp);
84 }