diff src/audacious/vfs.c @ 2313:3149d4b1a9a9 trunk

[svn] - objective-make autodepend fixes - move all sourcecode into src/ and adjust Makefiles accordingly
author nenolod
date Fri, 12 Jan 2007 11:43:40 -0800
parents
children e80c9dfc93aa
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audacious/vfs.c	Fri Jan 12 11:43:40 2007 -0800
@@ -0,0 +1,351 @@
+/*  Audacious
+ *  Copyright (c) 2006-2007 William Pitcock
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "vfs.h"
+#include <stdio.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "libaudacious/urldecode.h"
+
+static GList *vfs_transports = NULL;
+
+#ifdef VFS_DEBUG
+# define DBG(x, args...) g_print(x, ## args);
+#else
+# define DBG(x, args...)
+#endif
+
+/**
+ * vfs_register_transport:
+ * @vtable: The #VFSConstructor vtable to register.
+ *
+ * Registers a #VFSConstructor vtable with the VFS system.
+ *
+ * Return value: TRUE on success, FALSE on failure.
+ **/
+gboolean
+vfs_register_transport(VFSConstructor *vtable)
+{
+    vfs_transports = g_list_append(vfs_transports, vtable);
+
+    return TRUE;
+}
+
+/**
+ * vfs_fopen:
+ * @path: The path or URI to open.
+ * @mode: The preferred access privileges (not guaranteed).
+ *
+ * Opens a stream from a VFS transport using a #VFSConstructor.
+ *
+ * Return value: On success, a #VFSFile object representing the stream.
+ **/
+VFSFile *
+vfs_fopen(const gchar * path,
+          const gchar * mode)
+{
+    VFSFile *file;
+    gchar **vec;
+    VFSConstructor *vtable = NULL;
+    GList *node;
+    gchar *decpath;
+
+    if (!path || !mode)
+	return NULL;
+
+    decpath = xmms_urldecode_plain(path);
+
+    vec = g_strsplit(decpath, "://", 2);
+
+    /* special case: no transport specified, look for the "/" transport */
+    if (vec[1] == NULL)
+    {
+        for (node = vfs_transports; node != NULL; node = g_list_next(node))
+        {
+            vtable = (VFSConstructor *) node->data;
+
+            if (*vtable->uri_id == '/')
+                break;
+        }
+    }
+    else
+    {
+        for (node = vfs_transports; node != NULL; node = g_list_next(node))
+        {
+            vtable = (VFSConstructor *) node->data;
+
+            if (!g_strcasecmp(vec[0], vtable->uri_id))
+                break;
+        }
+    }
+
+    /* no transport vtable has been registered, bail. */
+    if (vtable == NULL)
+    {
+        g_strfreev(vec);
+        return NULL;
+    }
+
+    file = vtable->vfs_fopen_impl(vec[1] ? vec[1] : vec[0], mode);
+
+    if (file == NULL)
+    {
+        g_strfreev(vec);
+        return NULL;
+    }
+
+    file->uri = g_strdup(path);
+    file->base = vtable;
+
+    g_strfreev(vec);
+    g_free(decpath);
+
+    return file;
+}
+
+/**
+ * vfs_fclose:
+ * @file: A #VFSFile object to destroy.
+ *
+ * Closes a VFS stream and destroys a #VFSFile object.
+ *
+ * Return value: -1 on failure, 0 on success.
+ **/
+gint
+vfs_fclose(VFSFile * file)
+{
+    gint ret = 0;
+
+    if (file == NULL)
+        return -1;
+
+    if (file->base->vfs_fclose_impl(file) != 0)
+        ret = -1;
+
+    if (file->uri != NULL)
+        g_free(file->uri);
+
+    g_free(file);
+
+    return ret;
+}
+
+/**
+ * vfs_fread:
+ * @ptr: A pointer to the destination buffer.
+ * @size: The size of each element to read.
+ * @nmemb: The number of elements to read.
+ * @file: #VFSFile object that represents the VFS stream.
+ *
+ * Reads from a VFS stream.
+ *
+ * Return value: The amount of elements succesfully read.
+ **/
+size_t
+vfs_fread(gpointer ptr,
+          size_t size,
+          size_t nmemb,
+          VFSFile * file)
+{
+    if (file == NULL)
+        return 0;
+
+    return file->base->vfs_fread_impl(ptr, size, nmemb, file);
+}
+
+/**
+ * vfs_fwrite:
+ * @ptr: A const pointer to the source buffer.
+ * @size: The size of each element to write.
+ * @nmemb: The number of elements to write.
+ * @file: #VFSFile object that represents the VFS stream.
+ *
+ * Writes to a VFS stream.
+ *
+ * Return value: The amount of elements succesfully written.
+ **/
+size_t
+vfs_fwrite(gconstpointer ptr,
+           size_t size,
+           size_t nmemb,
+           VFSFile * file)
+{
+    if (file == NULL)
+        return 0;
+
+    return file->base->vfs_fwrite_impl(ptr, size, nmemb, file);
+}
+
+/**
+ * vfs_getc:
+ * @stream: #VFSFile object that represents the VFS stream.
+ *
+ * Reads a character from a VFS stream.
+ *
+ * Return value: On success, a character. Otherwise, -1.
+ **/
+gint
+vfs_getc(VFSFile *stream)
+{
+    if (stream == NULL)
+        return -1;
+
+    return stream->base->vfs_getc_impl(stream);
+}
+
+/**
+ * vfs_ungetc:
+ * @c: The character to push back.
+ * @stream: #VFSFile object that represents the VFS stream.
+ *
+ * Pushes a character back to the VFS stream.
+ *
+ * Return value: On success, 0. Otherwise, -1.
+ **/
+gint
+vfs_ungetc(gint c, VFSFile *stream)
+{
+    if (stream == NULL)
+        return -1;
+
+    return stream->base->vfs_ungetc_impl(c, stream);
+}
+
+/**
+ * vfs_fseek:
+ * @file: #VFSFile object that represents the VFS stream.
+ * @offset: The offset to seek to.
+ * @whence: Whether or not the seek is absolute or not.
+ *
+ * Seeks through a VFS stream.
+ *
+ * Return value: On success, 1. Otherwise, 0.
+ **/
+gint
+vfs_fseek(VFSFile * file,
+          glong offset,
+          gint whence)
+{
+    if (file == NULL)
+        return 0;
+
+    return file->base->vfs_fseek_impl(file, offset, whence);
+}
+
+/**
+ * vfs_rewind:
+ * @file: #VFSFile object that represents the VFS stream.
+ *
+ * Rewinds a VFS stream.
+ **/
+void
+vfs_rewind(VFSFile * file)
+{
+    if (file == NULL)
+        return;
+
+    file->base->vfs_rewind_impl(file);
+}
+
+/**
+ * vfs_ftell:
+ * @file: #VFSFile object that represents the VFS stream.
+ *
+ * Returns the current position in the VFS stream's buffer.
+ *
+ * Return value: On success, the current position. Otherwise, -1.
+ **/
+glong
+vfs_ftell(VFSFile * file)
+{
+    if (file == NULL)
+        return -1;
+
+    return file->base->vfs_ftell_impl(file);
+}
+
+/**
+ * vfs_feof:
+ * @file: #VFSFile object that represents the VFS stream.
+ *
+ * Returns whether or not the VFS stream has reached EOF.
+ *
+ * Return value: On success, whether or not the VFS stream is at EOF. Otherwise, FALSE.
+ **/
+gboolean
+vfs_feof(VFSFile * file)
+{
+    if (file == NULL)
+        return FALSE;
+
+    return (gboolean) file->base->vfs_feof_impl(file);
+}
+
+/**
+ * vfs_truncate:
+ * @file: #VFSFile object that represents the VFS stream.
+ * @length: The length to truncate at.
+ *
+ * Truncates a VFS stream to a certain size.
+ *
+ * Return value: On success, 0. Otherwise, -1.
+ **/
+gint
+vfs_truncate(VFSFile * file, glong length)
+{
+    if (file == NULL)
+        return -1;
+
+    return file->base->vfs_truncate_impl(file, length);
+}
+
+/**
+ * vfs_file_test:
+ * @path: A path to test.
+ * @test: A GFileTest to run.
+ *
+ * Wrapper for g_file_test().
+ *
+ * Return value: The result of g_file_test().
+ **/
+gboolean
+vfs_file_test(const gchar * path, GFileTest test)
+{
+    return g_file_test(path, test);
+}
+
+/**
+ * vfs_is_writeable:
+ * @path: A path to test.
+ *
+ * Tests if a file is writeable.
+ *
+ * Return value: TRUE if the file is writeable, otherwise FALSE.
+ **/
+gboolean
+vfs_is_writeable(const gchar * path)
+{
+    struct stat info;
+
+    if (stat(path, &info) == -1)
+        return FALSE;
+
+    return (info.st_mode & S_IWUSR);
+}