Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * probe-buffer.c 00003 * Copyright 2010-2011 John Lindgren 00004 * 00005 * This file is part of Audacious. 00006 * 00007 * Audacious is free software: you can redistribute it and/or modify it under 00008 * the terms of the GNU General Public License as published by the Free Software 00009 * Foundation, version 2 or version 3 of the License. 00010 * 00011 * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00013 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * Audacious. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * The Audacious team does not consider modular code linking to Audacious or 00019 * using our public API to be a derived work. 00020 */ 00021 00022 #include <glib.h> 00023 #include <stdlib.h> 00024 #include <string.h> 00025 00026 #include "debug.h" 00027 #include "probe-buffer.h" 00028 00029 typedef struct 00030 { 00031 VFSFile * file; 00032 unsigned char buffer[16384]; 00033 int filled, at; 00034 } 00035 ProbeBuffer; 00036 00037 static int probe_buffer_fclose (VFSFile * file) 00038 { 00039 ProbeBuffer * p = vfs_get_handle (file); 00040 00041 int ret = vfs_fclose (p->file); 00042 g_slice_free (ProbeBuffer, p); 00043 return ret; 00044 } 00045 00046 static void increase_buffer (ProbeBuffer * p, int64_t size) 00047 { 00048 size = (size + 0xFF) & ~0xFF; 00049 00050 if (size > sizeof p->buffer) 00051 size = sizeof p->buffer; 00052 00053 if (p->filled < size) 00054 p->filled += vfs_fread (p->buffer + p->filled, 1, size - p->filled, 00055 p->file); 00056 } 00057 00058 static int64_t probe_buffer_fread (void * buffer, int64_t size, int64_t count, 00059 VFSFile * file) 00060 { 00061 ProbeBuffer * p = vfs_get_handle (file); 00062 00063 increase_buffer (p, p->at + size * count); 00064 int readed = (size > 0) ? MIN (count, (p->filled - p->at) / size) : 0; 00065 memcpy (buffer, p->buffer + p->at, size * readed); 00066 00067 p->at += size * readed; 00068 return readed; 00069 } 00070 00071 static int64_t probe_buffer_fwrite (const void * data, int64_t size, int64_t count, 00072 VFSFile * file) 00073 { 00074 /* not implemented */ 00075 return 0; 00076 } 00077 00078 static int probe_buffer_getc (VFSFile * file) 00079 { 00080 unsigned char c; 00081 return (probe_buffer_fread (& c, 1, 1, file) == 1) ? c : EOF; 00082 } 00083 00084 static int probe_buffer_fseek (VFSFile * file, int64_t offset, int whence) 00085 { 00086 ProbeBuffer * p = vfs_get_handle (file); 00087 00088 if (whence == SEEK_END) 00089 return -1; 00090 00091 if (whence == SEEK_CUR) 00092 offset += p->at; 00093 00094 g_return_val_if_fail (offset >= 0, -1); 00095 increase_buffer (p, offset); 00096 00097 if (offset > p->filled) 00098 return -1; 00099 00100 p->at = offset; 00101 return 0; 00102 } 00103 00104 static int probe_buffer_ungetc (int c, VFSFile * file) 00105 { 00106 return (! probe_buffer_fseek (file, -1, SEEK_CUR)) ? c : EOF; 00107 } 00108 00109 static void probe_buffer_rewind (VFSFile * file) 00110 { 00111 probe_buffer_fseek (file, 0, SEEK_SET); 00112 } 00113 00114 static int64_t probe_buffer_ftell (VFSFile * file) 00115 { 00116 return ((ProbeBuffer *) vfs_get_handle (file))->at; 00117 } 00118 00119 static bool_t probe_buffer_feof (VFSFile * file) 00120 { 00121 ProbeBuffer * p = vfs_get_handle (file); 00122 return (p->at < p->filled) ? FALSE : vfs_feof (p->file); 00123 } 00124 00125 static int probe_buffer_ftruncate (VFSFile * file, int64_t size) 00126 { 00127 /* not implemented */ 00128 return -1; 00129 } 00130 00131 static int64_t probe_buffer_fsize (VFSFile * file) 00132 { 00133 return vfs_fsize (((ProbeBuffer *) vfs_get_handle (file))->file); 00134 } 00135 00136 static char * probe_buffer_get_metadata (VFSFile * file, const char * field) 00137 { 00138 return vfs_get_metadata (((ProbeBuffer *) vfs_get_handle (file))->file, field); 00139 } 00140 00141 static VFSConstructor probe_buffer_table = 00142 { 00143 .vfs_fopen_impl = NULL, 00144 .vfs_fclose_impl = probe_buffer_fclose, 00145 .vfs_fread_impl = probe_buffer_fread, 00146 .vfs_fwrite_impl = probe_buffer_fwrite, 00147 .vfs_getc_impl = probe_buffer_getc, 00148 .vfs_ungetc_impl = probe_buffer_ungetc, 00149 .vfs_fseek_impl = probe_buffer_fseek, 00150 .vfs_rewind_impl = probe_buffer_rewind, 00151 .vfs_ftell_impl = probe_buffer_ftell, 00152 .vfs_feof_impl = probe_buffer_feof, 00153 .vfs_ftruncate_impl = probe_buffer_ftruncate, 00154 .vfs_fsize_impl = probe_buffer_fsize, 00155 .vfs_get_metadata_impl = probe_buffer_get_metadata, 00156 }; 00157 00158 VFSFile * probe_buffer_new (const char * filename) 00159 { 00160 VFSFile * file = vfs_fopen (filename, "r"); 00161 00162 if (! file) 00163 return NULL; 00164 00165 ProbeBuffer * p = g_slice_new (ProbeBuffer); 00166 p->file = file; 00167 p->filled = 0; 00168 p->at = 0; 00169 00170 return vfs_new (filename, & probe_buffer_table, p); 00171 }