Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
vfs_buffer.c
Go to the documentation of this file.
00001 /*  Audacious
00002  *  Copyright (c) 2006-2007 William Pitcock
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; under version 3 of the License.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program.  If not, see <http://www.gnu.org/licenses>.
00015  *
00016  *  The Audacious team does not consider modular code linking to
00017  *  Audacious or using our public API to be a derived work.
00018  */
00019 
00020 #include <glib.h>
00021 #include <string.h>
00022 #include "vfs.h"
00023 #include "vfs_buffer.h"
00024 
00025 
00026 static VFSFile *
00027 buffer_vfs_fopen_impl(const gchar * path,
00028           const gchar * mode)
00029 {
00030     return NULL;
00031 }
00032 
00033 static gint
00034 buffer_vfs_fclose_impl(VFSFile * file)
00035 {
00036     g_return_val_if_fail(file != NULL, -1);
00037 
00038     g_free(file->handle);
00039 
00040     return 0;
00041 }
00042 
00043 static gint64 buffer_vfs_fread_impl (void * i_ptr, gint64 size, gint64 nmemb,
00044  VFSFile * file)
00045 {
00046     VFSBuffer *handle;
00047     guchar *i;
00048     gsize read = 0;
00049     guchar *ptr = (guchar *) i_ptr;
00050 
00051     if (file == NULL)
00052         return 0;
00053 
00054     handle = (VFSBuffer *) file->handle;
00055 
00056     for (i = ptr; (gsize) (i - ptr) < nmemb * size &&
00057          (gsize) (i - ptr) <= handle->size;
00058          i++, handle->iter++)
00059     {
00060        *i = *handle->iter;
00061        read++;
00062     }
00063 
00064     return (read / size);
00065 }
00066 
00067 static gint64 buffer_vfs_fwrite_impl (const void * i_ptr, gint64 size, gint64
00068  nmemb, VFSFile * file)
00069 {
00070     VFSBuffer *handle;
00071     const guchar *i;
00072     gsize written = 0;
00073     const guchar *ptr = (const guchar *) i_ptr;
00074 
00075     if (file == NULL)
00076         return 0;
00077 
00078     handle = (VFSBuffer *) file->handle;
00079 
00080     for (i = ptr; (gsize) (i - ptr) < nmemb * size &&
00081          (gsize) (i - ptr) <= handle->size;
00082          i++, handle->iter++)
00083     {
00084        *handle->iter = *i;
00085        written++;
00086     }
00087 
00088     return (written / size);
00089 }
00090 
00091 static gint
00092 buffer_vfs_getc_impl(VFSFile *stream)
00093 {
00094     VFSBuffer *handle = (VFSBuffer *) stream->handle;
00095     gint c;
00096 
00097     c = *handle->iter;
00098     handle->iter++;
00099 
00100     return c;
00101 }
00102 
00103 static gint
00104 buffer_vfs_ungetc_impl(gint c, VFSFile *stream)
00105 {
00106     return -1;
00107 }
00108 
00109 static gint
00110 buffer_vfs_fseek_impl(VFSFile * file,
00111           gint64 offset,
00112           gint whence)
00113 {
00114     VFSBuffer *handle;
00115 
00116     if (file == NULL)
00117         return 0;
00118 
00119     handle = (VFSBuffer *) file->handle;
00120 
00121     switch(whence)
00122     {
00123        case SEEK_CUR:
00124           handle->iter = handle->iter + offset;
00125           break;
00126        case SEEK_END:
00127           handle->iter = handle->end;
00128           break;
00129        case SEEK_SET:
00130        default:
00131           handle->iter = handle->data + offset;
00132           break;
00133     }
00134 
00135     return 0;
00136 }
00137 
00138 static void
00139 buffer_vfs_rewind_impl(VFSFile * file)
00140 {
00141     VFSBuffer *handle;
00142 
00143     if (file == NULL)
00144         return;
00145 
00146     handle = (VFSBuffer *) file->handle;
00147 
00148     handle->iter = handle->data;
00149 }
00150 
00151 static gint64
00152 buffer_vfs_ftell_impl(VFSFile * file)
00153 {
00154     VFSBuffer *handle;
00155 
00156     if (file == NULL)
00157         return 0;
00158 
00159     handle = (VFSBuffer *) file->handle;
00160 
00161     return handle->iter - handle->data;
00162 }
00163 
00164 static gboolean
00165 buffer_vfs_feof_impl(VFSFile * file)
00166 {
00167     VFSBuffer *handle;
00168 
00169     if (file == NULL)
00170         return FALSE;
00171 
00172     handle = (VFSBuffer *) file->handle;
00173 
00174     return (gboolean) (handle->iter == handle->end);
00175 }
00176 
00177 static gint
00178 buffer_vfs_truncate_impl (VFSFile * file, gint64 size)
00179 {
00180     return 0;
00181 }
00182 
00183 static gint64
00184 buffer_vfs_fsize_impl(VFSFile * file)
00185 {
00186     VFSBuffer *handle;
00187 
00188     if (file == NULL)
00189         return -1;
00190 
00191     handle = (VFSBuffer *) file->handle;
00192 
00193     return (off_t) (handle->end - handle->data);
00194 }
00195 
00196 static VFSConstructor buffer_const = {
00197         NULL,                   // not a normal VFS class
00198         buffer_vfs_fopen_impl,
00199         buffer_vfs_fclose_impl,
00200         buffer_vfs_fread_impl,
00201         buffer_vfs_fwrite_impl,
00202         buffer_vfs_getc_impl,
00203         buffer_vfs_ungetc_impl,
00204         buffer_vfs_fseek_impl,
00205         buffer_vfs_rewind_impl,
00206         buffer_vfs_ftell_impl,
00207         buffer_vfs_feof_impl,
00208         buffer_vfs_truncate_impl,
00209         buffer_vfs_fsize_impl,
00210         NULL
00211 };
00212 
00213 VFSFile *
00214 vfs_buffer_new(gpointer data, gsize size)
00215 {
00216     VFSFile *handle;
00217     VFSBuffer *buffer;
00218 
00219     g_return_val_if_fail(data != NULL, NULL);
00220     g_return_val_if_fail(size > 0, NULL);
00221 
00222     if ((handle = g_new0(VFSFile, 1)) == NULL)
00223         return NULL;
00224 
00225     if ((buffer = g_new0(VFSBuffer, 1)) == NULL)
00226     {
00227         g_free(handle);
00228         return NULL;
00229     }
00230 
00231     buffer->data = data;
00232     buffer->iter = data;
00233     buffer->end = (guchar *) data + size;
00234     buffer->size = size;
00235 
00236     handle->handle = buffer;
00237     handle->base = &buffer_const;
00238     handle->ref = 1;
00239 
00240     return handle;
00241 }
00242 
00243 VFSFile *
00244 vfs_buffer_new_from_string(gchar *str)
00245 {
00246     g_return_val_if_fail(str != NULL, NULL);
00247 
00248     return vfs_buffer_new(str, strlen(str));
00249 }