Mercurial > audlegacy
annotate libaudacious/vfs.c @ 2032:7aed5cf10141 trunk
[svn] - document the VFS layer.
author | nenolod |
---|---|
date | Sun, 03 Dec 2006 22:35:18 -0800 |
parents | ebce0d5efac1 |
children | c43fb0845b71 |
rev | line source |
---|---|
1997 | 1 /* Audacious |
2 * Copyright (c) 2006 William Pitcock | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
1460 | 5 * it under the terms of the GNU General Public License as published by |
0 | 6 * the Free Software Foundation; either version 2 of the License, or |
7 * (at your option) any later version. | |
8 * | |
9 * This program is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with this program; if not, write to the Free Software | |
1459 | 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
0 | 17 */ |
18 | |
19 #include "vfs.h" | |
20 #include <stdio.h> | |
21 | |
22 #include <unistd.h> | |
23 #include <sys/stat.h> | |
24 #include <sys/types.h> | |
25 | |
1997 | 26 static GList *vfs_transports = NULL; |
27 | |
28 #ifdef VFS_DEBUG | |
29 # define DBG(x, args...) g_print(x, ## args); | |
30 #else | |
31 # define DBG(x, args...) | |
32 #endif | |
33 | |
2032 | 34 /* |
35 * vfs_register_transport(VFSConstructor *vtable) | |
36 * | |
37 * Registers a VFSConstructor vtable with the VFS system. | |
38 * | |
39 * Inputs: | |
40 * - a VFSConstructor object | |
41 * | |
42 * Outputs: | |
43 * - TRUE on success, FALSE on failure. | |
44 * | |
45 * Side Effects: | |
46 * - none | |
47 */ | |
0 | 48 gboolean |
1997 | 49 vfs_register_transport(VFSConstructor *vtable) |
0 | 50 { |
1997 | 51 vfs_transports = g_list_append(vfs_transports, vtable); |
52 | |
0 | 53 return TRUE; |
54 } | |
55 | |
2032 | 56 /* |
57 * vfs_fopen(const gchar * path, const gchar * mode) | |
58 * | |
59 * Opens a stream from a VFS transport using a VFSConstructor. | |
60 * | |
61 * Inputs: | |
62 * - path or URI to open | |
63 * - preferred access privileges (not guaranteed) | |
64 * | |
65 * Outputs: | |
66 * - on success, a VFSFile object representing the VFS stream | |
67 * - on failure, nothing | |
68 * | |
69 * Side Effects: | |
70 * - file descriptors are opened or more memory is allocated. | |
71 */ | |
0 | 72 VFSFile * |
73 vfs_fopen(const gchar * path, | |
74 const gchar * mode) | |
75 { | |
76 VFSFile *file; | |
1997 | 77 gchar **vec; |
78 VFSConstructor *vtable = NULL; | |
79 GList *node; | |
0 | 80 |
550 | 81 if (!path || !mode) |
82 return NULL; | |
83 | |
1997 | 84 vec = g_strsplit(path, "://", 2); |
85 | |
86 /* special case: no transport specified, look for the "/" transport */ | |
87 if (vec[1] == NULL) | |
88 { | |
89 for (node = vfs_transports; node != NULL; node = g_list_next(node)) | |
90 { | |
91 vtable = (VFSConstructor *) node->data; | |
92 | |
93 if (*vtable->uri_id == '/') | |
94 break; | |
95 } | |
96 } | |
97 else | |
98 { | |
99 for (node = vfs_transports; node != NULL; node = g_list_next(node)) | |
100 { | |
101 vtable = (VFSConstructor *) node->data; | |
0 | 102 |
1997 | 103 if (!g_strcasecmp(vec[0], vtable->uri_id)) |
104 break; | |
105 } | |
106 } | |
107 | |
108 /* no transport vtable has been registered, bail. */ | |
109 if (vtable == NULL) | |
110 { | |
2031
ebce0d5efac1
[svn] - don't leak the split URI vector after doing the vtable lookup
nenolod
parents:
1999
diff
changeset
|
111 g_strfreev(vec); |
1997 | 112 return NULL; |
0 | 113 } |
114 | |
1997 | 115 file = vtable->vfs_fopen_impl(vec[1] ? vec[1] : vec[0], mode); |
116 | |
117 if (file == NULL) | |
118 { | |
2032 | 119 g_strfreev(vec); |
1997 | 120 return NULL; |
121 } | |
122 | |
123 file->uri = g_strdup(path); | |
124 file->base = vtable; | |
125 | |
2031
ebce0d5efac1
[svn] - don't leak the split URI vector after doing the vtable lookup
nenolod
parents:
1999
diff
changeset
|
126 g_strfreev(vec); |
ebce0d5efac1
[svn] - don't leak the split URI vector after doing the vtable lookup
nenolod
parents:
1999
diff
changeset
|
127 |
0 | 128 return file; |
129 } | |
130 | |
2032 | 131 /* |
132 * vfs_fclose(VFSFile * file) | |
133 * | |
134 * Closes a VFS stream and destroys a VFSFile object. | |
135 * | |
136 * Inputs: | |
137 * - a VFSFile object to destroy | |
138 * | |
139 * Outputs: | |
140 * - -1 on success, otherwise 0 | |
141 * | |
142 * Side Effects: | |
143 * - a file description is closed or allocated memory is freed | |
144 */ | |
0 | 145 gint |
146 vfs_fclose(VFSFile * file) | |
147 { | |
148 gint ret = 0; | |
149 | |
821 | 150 if (file == NULL) |
151 return -1; | |
152 | |
1997 | 153 if (file->base->vfs_fclose_impl(file) != 0) |
154 ret = -1; | |
0 | 155 |
1999 | 156 if (file->uri != NULL) |
157 g_free(file->uri); | |
158 | |
0 | 159 g_free(file); |
160 | |
161 return ret; | |
162 } | |
163 | |
2032 | 164 /* |
165 * vfs_fread(gpointer ptr, size_t size, size_t nmemb, VFSFile * file) | |
166 * | |
167 * Reads from a VFS stream. | |
168 * | |
169 * Inputs: | |
170 * - pointer to destination buffer | |
171 * - size of each element to read | |
172 * - number of elements to read | |
173 * - VFSFile object that represents the VFS stream | |
174 * | |
175 * Outputs: | |
176 * - on success, the amount of elements successfully read | |
177 * - on failure, -1 | |
178 * | |
179 * Side Effects: | |
180 * - on nonblocking sources, the socket may be unavailable after | |
181 * this call. | |
182 */ | |
0 | 183 size_t |
184 vfs_fread(gpointer ptr, | |
185 size_t size, | |
186 size_t nmemb, | |
187 VFSFile * file) | |
188 { | |
821 | 189 if (file == NULL) |
190 return 0; | |
191 | |
1997 | 192 return file->base->vfs_fread_impl(ptr, size, nmemb, file); |
0 | 193 } |
194 | |
2032 | 195 /* |
196 * vfs_fwrite(gconstpointer ptr, size_t size, size_t nmemb, VFSFile * file) | |
197 * | |
198 * Writes to a VFS stream. | |
199 * | |
200 * Inputs: | |
201 * - const pointer to source buffer | |
202 * - size of each element to write | |
203 * - number of elements to write | |
204 * - VFSFile object that represents the VFS stream | |
205 * | |
206 * Outputs: | |
207 * - on success, the amount of elements successfully written | |
208 * - on failure, -1 | |
209 * | |
210 * Side Effects: | |
211 * - on nonblocking sources, the socket may be unavailable after | |
212 * this call. | |
213 */ | |
0 | 214 size_t |
215 vfs_fwrite(gconstpointer ptr, | |
216 size_t size, | |
217 size_t nmemb, | |
218 VFSFile * file) | |
219 { | |
821 | 220 if (file == NULL) |
221 return 0; | |
222 | |
1997 | 223 return file->base->vfs_fwrite_impl(ptr, size, nmemb, file); |
0 | 224 } |
225 | |
2032 | 226 /* |
227 * vfs_getc(VFSFile *stream) | |
228 * | |
229 * Reads a character from a VFS stream. | |
230 * | |
231 * Inputs: | |
232 * - a VFSFile object representing a VFS stream. | |
233 * | |
234 * Outputs: | |
235 * - on success, a character | |
236 * - on failure, -1 | |
237 * | |
238 * Side Effects: | |
239 * - on nonblocking sources, the socket may be unavailable after | |
240 * this call. | |
241 */ | |
0 | 242 gint |
1683
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
243 vfs_getc(VFSFile *stream) |
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
244 { |
1997 | 245 if (stream == NULL) |
246 return -1; | |
247 | |
248 return stream->base->vfs_getc_impl(stream); | |
1683
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
249 } |
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
250 |
2032 | 251 /* |
252 * vfs_ungetc(gint c, VFSFile *stream) | |
253 * | |
254 * Pushes a character back to the VFS stream. | |
255 * | |
256 * Inputs: | |
257 * - a character to push back | |
258 * - a VFSFile object representing a VFS stream. | |
259 * | |
260 * Outputs: | |
261 * - on success, 0 | |
262 * - on failure, -1 | |
263 * | |
264 * Side Effects: | |
265 * - on nonblocking sources, the socket may be unavailable after | |
266 * this call. | |
267 */ | |
1683
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
268 gint |
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
269 vfs_ungetc(gint c, VFSFile *stream) |
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
270 { |
1997 | 271 if (stream == NULL) |
272 return -1; | |
273 | |
274 return stream->base->vfs_ungetc_impl(c, stream); | |
1683
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
275 } |
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
276 |
2032 | 277 /* |
278 * vfs_fseek(VFSFile * file, gint offset, gint whence) | |
279 * | |
280 * Seeks through a VFS stream. | |
281 * | |
282 * Inputs: | |
283 * - a VFSFile object which represents a VFS stream | |
284 * - the offset to seek | |
285 * - whether or not the seek is absolute or non-absolute | |
286 * | |
287 * Outputs: | |
288 * - on success, 1 | |
289 * - on failure, 0 | |
290 * | |
291 * Side Effects: | |
292 * - on nonblocking sources, this is not guaranteed to work | |
293 */ | |
1683
e9c24e35bd76
[svn] - File stream API for audacious vfs; uses real getc/ungetc functions for vfs_stdio and emulated functions for vfs_gnome
giacomo
parents:
1460
diff
changeset
|
294 gint |
0 | 295 vfs_fseek(VFSFile * file, |
296 glong offset, | |
297 gint whence) | |
298 { | |
821 | 299 if (file == NULL) |
300 return 0; | |
301 | |
1997 | 302 return file->base->vfs_fseek_impl(file, offset, whence); |
0 | 303 } |
304 | |
2032 | 305 /* |
306 * vfs_rewind(VFSFile * file) | |
307 * | |
308 * Rewinds a VFS stream. | |
309 * | |
310 * Inputs: | |
311 * - a VFSFile object which represents a VFS stream | |
312 * | |
313 * Outputs: | |
314 * - nothing | |
315 * | |
316 * Side Effects: | |
317 * - on nonblocking sources, this is not guaranteed to work | |
318 */ | |
0 | 319 void |
320 vfs_rewind(VFSFile * file) | |
321 { | |
821 | 322 if (file == NULL) |
323 return; | |
324 | |
1997 | 325 file->base->vfs_rewind_impl(file); |
0 | 326 } |
327 | |
2032 | 328 /* |
329 * vfs_ftell(VFSFile * file) | |
330 * | |
331 * Returns the position of a VFS stream. | |
332 * | |
333 * Inputs: | |
334 * - a VFSFile object which represents a VFS stream | |
335 * | |
336 * Outputs: | |
337 * - on failure, -1. | |
338 * - on success, the stream's position | |
339 * | |
340 * Side Effects: | |
341 * - on nonblocking sources, this is not guaranteed to work | |
342 */ | |
0 | 343 glong |
344 vfs_ftell(VFSFile * file) | |
345 { | |
821 | 346 if (file == NULL) |
2032 | 347 return -1; |
821 | 348 |
1997 | 349 return file->base->vfs_ftell_impl(file); |
0 | 350 } |
351 | |
2032 | 352 /* |
353 * vfs_feof(VFSFile * file) | |
354 * | |
355 * Returns whether or not the VFS stream has reached EOF. | |
356 * | |
357 * Inputs: | |
358 * - a VFSFile object which represents a VFS stream | |
359 * | |
360 * Outputs: | |
361 * - on failure, FALSE. | |
362 * - on success, whether or not the VFS stream is at EOF. | |
363 * | |
364 * Side Effects: | |
365 * - none | |
366 */ | |
0 | 367 gboolean |
811
86ca43d8a845
[svn] - implement vfs_feof() and vfs_ftell() and update the scrobbler plugin to reflect that,
nenolod
parents:
550
diff
changeset
|
368 vfs_feof(VFSFile * file) |
86ca43d8a845
[svn] - implement vfs_feof() and vfs_ftell() and update the scrobbler plugin to reflect that,
nenolod
parents:
550
diff
changeset
|
369 { |
821 | 370 if (file == NULL) |
371 return FALSE; | |
372 | |
1997 | 373 return (gboolean) file->base->vfs_feof_impl(file); |
811
86ca43d8a845
[svn] - implement vfs_feof() and vfs_ftell() and update the scrobbler plugin to reflect that,
nenolod
parents:
550
diff
changeset
|
374 } |
86ca43d8a845
[svn] - implement vfs_feof() and vfs_ftell() and update the scrobbler plugin to reflect that,
nenolod
parents:
550
diff
changeset
|
375 |
2032 | 376 /* |
377 * vfs_truncate(VFSFile * file, glong size) | |
378 * | |
379 * Truncates a VFS stream to a certain size. | |
380 * | |
381 * Inputs: | |
382 * - a VFS stream to truncate | |
383 * - length to truncate at | |
384 * | |
385 * Outputs: | |
386 * - -1 on failure | |
387 * - 0 on success | |
388 * | |
389 * Side Effects: | |
390 * - this is not guaranteed to work on non-blocking | |
391 * sources | |
392 */ | |
393 gint | |
394 vfs_truncate(VFSFile * file, glong size) | |
395 { | |
396 if (file == NULL) | |
397 return -1; | |
398 | |
399 return file->base->vfs_truncate_impl(file, size); | |
400 } | |
401 | |
402 /* | |
403 * vfs_file_test(const gchar * path, GFileTest test) | |
404 * | |
405 * Wrapper for g_file_test(). | |
406 * | |
407 * Inputs: | |
408 * - a path to test | |
409 * - a GFileTest to run | |
410 * | |
411 * Outputs: | |
412 * - the result of g_file_test(). | |
413 * | |
414 * Side Effects: | |
415 * - g_file_test() is called. | |
416 */ | |
811
86ca43d8a845
[svn] - implement vfs_feof() and vfs_ftell() and update the scrobbler plugin to reflect that,
nenolod
parents:
550
diff
changeset
|
417 gboolean |
0 | 418 vfs_file_test(const gchar * path, GFileTest test) |
419 { | |
420 return g_file_test(path, test); | |
421 } | |
422 | |
2032 | 423 /* |
424 * vfs_is_writable(const gchar * path) | |
425 * | |
426 * Tests if a file is writable. | |
427 * | |
428 * Inputs: | |
429 * - a path to test | |
430 * | |
431 * Outputs: | |
432 * - FALSE if the file is not writable | |
433 * - TRUE if the file is writable | |
434 * | |
435 * Side Effects: | |
436 * - stat() is called. | |
437 * | |
438 * Bugs: | |
439 * - stat() is not considered part of stdio | |
440 */ | |
0 | 441 gboolean |
442 vfs_is_writeable(const gchar * path) | |
443 { | |
444 struct stat info; | |
445 | |
446 if (stat(path, &info) == -1) | |
447 return FALSE; | |
448 | |
449 return (info.st_mode & S_IWUSR); | |
450 } |