1 #ifndef _FILESEL_FILESYSTEM_H
2 #define _FILESEL_FILESYSTEM_H 1
3
4 struct ocpdir_t;
5 struct ocpfile_t;
6 struct ocpfilehandle_t;
7 struct ocpfiledecompressor_t;
8 struct ocpdirdecompressor_t;
9
10 typedef void *ocpdirhandle_pt;
11
12 #define FILESIZE_STREAM UINT64_C(0xffffffffffffffff) /* STREAM - so we recommend to open and analyze the file asap */
13 #define FILESIZE_ERROR UINT64_C(0xfffffffffffffffe)
14
15 struct ocpdir_charset_override_API_t
16 {
17 void (*get_default_string)(struct ocpdir_t *self, const char **label, const char **charset);
18 const char *(*get_byuser_string)(struct ocpdir_t *self); /* can return NULL, gives link to internal reference */
19 void (*set_byuser_string)(struct ocpdir_t *self, const char *byuser); /* duplicates the string, if NULL, default string should be used - only valid if get_default_string is non-null */
20 char **(*get_test_strings)(struct ocpdir_t *self); /* zero-terminated list of strings, should be freed, together will all the nodes when done */
21 };
22
23
24 struct ocpdir_t /* can be an archive */
25 {
26 void (*ref)(struct ocpdir_t *);
27 void (*unref)(struct ocpdir_t *);
28
29 struct ocpdir_t *parent;
30
31 /* read directory the usual way */
32 ocpdirhandle_pt (*readdir_start)(struct ocpdir_t *, void(*callback_file)(void *token, struct ocpfile_t *),
33 void(*callback_dir )(void *token, struct ocpdir_t *), void *token);
34 /* dumps all files. Only archives will let this be non-null */
35 ocpdirhandle_pt (*readflatdir_start)(struct ocpdir_t *, void(*callback_file)(void *token, struct ocpfile_t *), void *token);
36 void (*readdir_cancel)(ocpdirhandle_pt);
37 int (*readdir_iterate)(ocpdirhandle_pt); /* returns non-zero if more iterations is needed - ADB needs this */
38 struct ocpdir_t *(*readdir_dir) (struct ocpdir_t *, uint32_t dirdb_ref); /* find a specific dir */
39 struct ocpfile_t *(*readdir_file) (struct ocpdir_t *, uint32_t dirdb_ref); /* find a specific file */
40
41 const struct ocpdir_charset_override_API_t *charset_override_API;
42
43 int dirdb_ref;
44 int refcount; /* internal use by all object variants */
45 uint8_t is_archive;
46 uint8_t is_playlist;
47 };
48
ocpdir_t_fill(struct ocpdir_t * s,void (* ref)(struct ocpdir_t *),void (* unref)(struct ocpdir_t *),struct ocpdir_t * parent,ocpdirhandle_pt (* readdir_start)(struct ocpdir_t *,void (* callback_file)(void * token,struct ocpfile_t *),void (* callback_dir)(void * token,struct ocpdir_t *),void * token),ocpdirhandle_pt (* readflatdir_start)(struct ocpdir_t *,void (* callback_file)(void * token,struct ocpfile_t *),void * token),void (* readdir_cancel)(ocpdirhandle_pt),int (* readdir_iterate)(ocpdirhandle_pt),struct ocpdir_t * (* readdir_dir)(struct ocpdir_t *,uint32_t dirdb_ref),struct ocpfile_t * (* readdir_file)(struct ocpdir_t *,uint32_t dirdb_ref),const struct ocpdir_charset_override_API_t * charset_override_API,int dirdb_ref,int refcount,uint8_t is_archive,uint8_t is_playlist)49 static inline void ocpdir_t_fill (
50 struct ocpdir_t *s,
51 void (*ref)(struct ocpdir_t *),
52 void (*unref)(struct ocpdir_t *),
53 struct ocpdir_t *parent, /* ref-counting is the callers and unref handlers responsibility */
54 ocpdirhandle_pt (*readdir_start)(struct ocpdir_t *, void(*callback_file)(void *token, struct ocpfile_t *),
55 void(*callback_dir )(void *token, struct ocpdir_t *), void *token),
56 ocpdirhandle_pt (*readflatdir_start)(struct ocpdir_t *, void(*callback_file)(void *token, struct ocpfile_t *), void *token),
57 void (*readdir_cancel)(ocpdirhandle_pt),
58 int (*readdir_iterate)(ocpdirhandle_pt),
59 struct ocpdir_t *(*readdir_dir) (struct ocpdir_t *, uint32_t dirdb_ref),
60 struct ocpfile_t *(*readdir_file) (struct ocpdir_t *, uint32_t dirdb_ref),
61 const struct ocpdir_charset_override_API_t *charset_override_API,
62 int dirdb_ref,
63 int refcount,
64 uint8_t is_archive,
65 uint8_t is_playlist)
66 {
67 s->ref = ref;
68 s->unref = unref;
69 s->parent = parent;
70 s->readdir_start = readdir_start;
71 s->readflatdir_start = readflatdir_start;
72 s->readdir_cancel = readdir_cancel;
73 s->readdir_iterate = readdir_iterate;
74 s->readdir_dir = readdir_dir;
75 s->readdir_file = readdir_file;
76 s->charset_override_API = charset_override_API;
77 s->dirdb_ref = dirdb_ref;
78 s->refcount = refcount;
79 s->is_archive = is_archive;
80 s->is_playlist = is_playlist;
81 }
82
83 struct ocpfile_t /* can be virtual */
84 {
85 void (*ref)(struct ocpfile_t *);
86 void (*unref)(struct ocpfile_t *);
87 struct ocpdir_t *parent;
88 struct ocpfilehandle_t *(*open)(struct ocpfile_t *);
89
90 uint64_t (*filesize)(struct ocpfile_t *); // can return FILESIZE_STREAM FILESIZE_ERROR
91 int (*filesize_ready)(struct ocpfile_t *); // if this is false, asking for filesize might be very slow
92
93 int dirdb_ref;
94 int refcount; /* internal use by all object variants */
95 uint8_t is_nodetect; /* do not use mdbReadInfo on this file please */
96 };
97
ocpfile_t_fill(struct ocpfile_t * s,void (* ref)(struct ocpfile_t *),void (* unref)(struct ocpfile_t *),struct ocpdir_t * parent,struct ocpfilehandle_t * (* open)(struct ocpfile_t *),uint64_t (* filesize)(struct ocpfile_t *),int (* filesize_ready)(struct ocpfile_t *),int dirdb_ref,int refcount,uint8_t is_nodetect)98 static inline void ocpfile_t_fill (
99 struct ocpfile_t *s,
100 void (*ref)(struct ocpfile_t *),
101 void (*unref)(struct ocpfile_t *),
102 struct ocpdir_t *parent, /* ref-counting is the callers and unref handlers responsibility */
103 struct ocpfilehandle_t *(*open)(struct ocpfile_t *),
104 uint64_t (*filesize)(struct ocpfile_t *),
105 int (*filesize_ready)(struct ocpfile_t *),
106 int dirdb_ref,
107 int refcount,
108 uint8_t is_nodetect)
109 {
110 s->ref = ref;
111 s->unref = unref;
112 s->parent = parent;
113 s->open = open;
114 s->filesize = filesize;
115 s->filesize_ready = filesize_ready;
116 s->dirdb_ref = dirdb_ref;
117 s->refcount = refcount;
118 s->is_nodetect = is_nodetect;
119 }
120
121 struct ocpfilehandle_t
122 {
123 void (*ref)(struct ocpfilehandle_t *);
124 void (*unref)(struct ocpfilehandle_t *);
125
126 int (*seek_set)(struct ocpfilehandle_t *, int64_t pos); /* returns 0 for OK, and -1 on error, should use positive numbers */
127 int (*seek_cur)(struct ocpfilehandle_t *, int64_t pos); /* returns 0 for OK, and -1 on error */
128 int (*seek_end)(struct ocpfilehandle_t *, int64_t pos); /* returns 0 for OK, and -1 on error, should use negative numbers */
129 uint64_t (*getpos)(struct ocpfilehandle_t *);
130
131 int (*eof)(struct ocpfilehandle_t *); /* 0 = more data, 1 = EOF, -1 = error - probably tried to read beyond EOF */
132 int (*error)(struct ocpfilehandle_t *); /* 0 or 1 */
133
134 int (*read)(struct ocpfilehandle_t *, void *dst, int len); /* returns 0 or the number of bytes read - short reads only happens if EOF or error is hit! */
135
136 // can be FILESIZE_STREAM
137 uint64_t (*filesize)(struct ocpfilehandle_t *); // can be FILESIZE_STREAM
138 int (*filesize_ready)(struct ocpfilehandle_t *); // if this is false, asking for filesize might be very slow
139 int dirdb_ref;
140 int refcount; /* internal use by all object variants */
141 };
142
ocpfilehandle_t_fill(struct ocpfilehandle_t * s,void (* ref)(struct ocpfilehandle_t *),void (* unref)(struct ocpfilehandle_t *),int (* seek_set)(struct ocpfilehandle_t *,int64_t pos),int (* seek_cur)(struct ocpfilehandle_t *,int64_t pos),int (* seek_end)(struct ocpfilehandle_t *,int64_t pos),uint64_t (* getpos)(struct ocpfilehandle_t *),int (* eof)(struct ocpfilehandle_t *),int (* error)(struct ocpfilehandle_t *),int (* read)(struct ocpfilehandle_t *,void * dst,int len),uint64_t (* filesize)(struct ocpfilehandle_t *),int (* filesize_ready)(struct ocpfilehandle_t *),int dirdb_ref)143 static inline void ocpfilehandle_t_fill (
144 struct ocpfilehandle_t *s,
145 void (*ref)(struct ocpfilehandle_t *),
146 void (*unref)(struct ocpfilehandle_t *),
147 int (*seek_set)(struct ocpfilehandle_t *, int64_t pos),
148 int (*seek_cur)(struct ocpfilehandle_t *, int64_t pos),
149 int (*seek_end)(struct ocpfilehandle_t *, int64_t pos),
150 uint64_t (*getpos)(struct ocpfilehandle_t *),
151 int (*eof)(struct ocpfilehandle_t *),
152 int (*error)(struct ocpfilehandle_t *),
153 int (*read)(struct ocpfilehandle_t *, void *dst, int len),
154 uint64_t (*filesize)(struct ocpfilehandle_t *),
155 int (*filesize_ready)(struct ocpfilehandle_t *),
156 int dirdb_ref)
157 {
158 s->ref = ref;
159 s->unref = unref;
160 s->seek_set = seek_set;
161 s->seek_cur = seek_cur;
162 s->seek_end = seek_end;
163 s->getpos = getpos;
164 s->eof = eof;
165 s->error = error;
166 s->read = read;
167 s->filesize = filesize;
168 s->filesize_ready = filesize_ready;
169 s->dirdb_ref = dirdb_ref;
170 }
171
172 int ocpfilehandle_read_uint8 (struct ocpfilehandle_t *, uint8_t *dst); /* returns 0 for OK, and -1 on error */
173 int ocpfilehandle_read_uint16_be (struct ocpfilehandle_t *, uint16_t *dst); /* returns 0 for OK, and -1 on error */
174 int ocpfilehandle_read_uint16_le (struct ocpfilehandle_t *, uint16_t *dst); /* returns 0 for OK, and -1 on error */
175 int ocpfilehandle_read_uint24_be (struct ocpfilehandle_t *, uint32_t *dst); /* returns 0 for OK, and -1 on error */
176 int ocpfilehandle_read_uint24_le (struct ocpfilehandle_t *, uint32_t *dst); /* returns 0 for OK, and -1 on error */
177 int ocpfilehandle_read_uint32_be (struct ocpfilehandle_t *, uint32_t *dst); /* returns 0 for OK, and -1 on error */
178 int ocpfilehandle_read_uint32_le (struct ocpfilehandle_t *, uint32_t *dst); /* returns 0 for OK, and -1 on error */
179 int ocpfilehandle_read_uint64_be (struct ocpfilehandle_t *, uint64_t *dst); /* returns 0 for OK, and -1 on error */
180 int ocpfilehandle_read_uint64_le (struct ocpfilehandle_t *, uint64_t *dst); /* returns 0 for OK, and -1 on error */
181
182 /* .tar .zip .. */
183 struct ocpdirdecompressor_t
184 {
185 const char *name;
186 const char *description;
187 struct ocpdir_t *(*check)(const struct ocpdirdecompressor_t *, struct ocpfile_t *, const char *filetype); /* wraps the handle if it matches */
188 };
189
190 void register_dirdecompressor(const struct ocpdirdecompressor_t *);
191
192 struct ocpdir_t *ocpdirdecompressor_check (struct ocpfile_t *, const char *filetype);
193
194 #endif
195