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