Mercurial > audlegacy
diff src/audlegacy/vfs_buffered_file.c @ 4811:7bf7f83a217e
rename src/audacious src/audlegacy so that both audlegacy and audacious can coexist.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Wed, 26 Nov 2008 00:44:56 +0900 |
parents | src/audacious/vfs_buffered_file.c@4eeb4c36867c |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audlegacy/vfs_buffered_file.c Wed Nov 26 00:44:56 2008 +0900 @@ -0,0 +1,273 @@ +/* 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 3 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, see <http://www.gnu.org/licenses>. + * + * The Audacious team does not consider modular code linking to + * Audacious or using our public API to be a derived work. + */ + +#include <glib.h> +#include <string.h> +#include "vfs.h" +#include "vfs_buffer.h" +#include "vfs_buffered_file.h" + +VFSFile * +buffered_file_vfs_fopen_impl(const gchar * path, + const gchar * mode) +{ + return NULL; +} + +gint +buffered_file_vfs_fclose_impl(VFSFile * file) +{ + g_return_val_if_fail(file != NULL, -1); + + if (file->handle) + { + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + if (handle->fd != NULL) + vfs_fclose(handle->fd); + + vfs_fclose(handle->buffer); + g_free(handle->mem); + g_free(handle); + } + + return 0; +} + +size_t +buffered_file_vfs_fread_impl(gpointer i_ptr, + size_t size, + size_t nmemb, + VFSFile * file) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + /* is this request within the buffered area, or should we switch to + * an FD? --nenolod + */ + if (handle->which == FALSE && + (vfs_ftell(handle->buffer)) + (size * nmemb) > + ((VFSBuffer *) handle->buffer->handle)->size) + { + vfs_fseek(handle->fd, vfs_ftell(handle->buffer), SEEK_SET); + handle->which = TRUE; + } + + return vfs_fread(i_ptr, size, nmemb, handle->which == TRUE ? handle->fd : handle->buffer); +} + +size_t +buffered_file_vfs_fwrite_impl(gconstpointer i_ptr, + size_t size, + size_t nmemb, + VFSFile * file) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + return vfs_fwrite(i_ptr, size, nmemb, handle->fd); +} + +gint +buffered_file_vfs_getc_impl(VFSFile *stream) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) stream->handle; + + /* is this request within the buffered area, or should we switch to + * an FD? --nenolod + */ + if ((vfs_ftell(handle->buffer)) + 1 > + ((VFSBuffer *) handle->buffer->handle)->size) + { + vfs_fseek(handle->fd, vfs_ftell(handle->buffer), SEEK_SET); + handle->which = TRUE; + } + + return vfs_getc(handle->which == TRUE ? handle->fd : handle->buffer); +} + +gint +buffered_file_vfs_ungetc_impl(gint c, VFSFile *stream) +{ + return -1; +} + +gint +buffered_file_vfs_fseek_impl(VFSFile * file, + glong offset, + gint whence) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + vfs_fseek(handle->buffer, offset, whence); + + switch(whence) + { + case SEEK_END: + handle->which = TRUE; + vfs_fseek(handle->fd, offset, whence); + break; + case SEEK_CUR: + if (vfs_ftell(handle->buffer) + offset > ((VFSBuffer *) handle->buffer->handle)->size) + { + handle->which = TRUE; + vfs_fseek(handle->fd, offset, whence); + } + break; + case SEEK_SET: + default: + if (offset > ((VFSBuffer *) handle->buffer->handle)->size) + { + handle->which = TRUE; + vfs_fseek(handle->fd, offset, whence); + } + else + { + handle->which = FALSE; + vfs_fseek(handle->buffer, offset, whence); + } + break; + } + return 0; +} + +void +buffered_file_vfs_rewind_impl(VFSFile * file) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + vfs_rewind(handle->buffer); + handle->which = FALSE; +} + +glong +buffered_file_vfs_ftell_impl(VFSFile * file) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + return vfs_ftell(handle->which == TRUE ? handle->fd : handle->buffer); +} + +gboolean +buffered_file_vfs_feof_impl(VFSFile * file) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + return vfs_feof(handle->which == TRUE ? handle->fd : handle->buffer); +} + +gint +buffered_file_vfs_truncate_impl(VFSFile * file, glong size) +{ + return 0; +} + +off_t +buffered_file_vfs_fsize_impl(VFSFile * file) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + return vfs_fsize(handle->fd); +} + +gchar * +buffered_file_vfs_metadata_impl(VFSFile * file, const gchar * field) +{ + VFSBufferedFile *handle = (VFSBufferedFile *) file->handle; + + return vfs_get_metadata(handle->fd, field); +} + +VFSConstructor buffered_file_const = { + NULL, // not a normal VFS class + buffered_file_vfs_fopen_impl, + buffered_file_vfs_fclose_impl, + buffered_file_vfs_fread_impl, + buffered_file_vfs_fwrite_impl, + buffered_file_vfs_getc_impl, + buffered_file_vfs_ungetc_impl, + buffered_file_vfs_fseek_impl, + buffered_file_vfs_rewind_impl, + buffered_file_vfs_ftell_impl, + buffered_file_vfs_feof_impl, + buffered_file_vfs_truncate_impl, + buffered_file_vfs_fsize_impl, + buffered_file_vfs_metadata_impl +}; + +VFSFile * +vfs_buffered_file_new_from_uri(const gchar *uri) +{ + VFSFile *handle; + VFSBufferedFile *fd; + gsize sz; + + g_return_val_if_fail(uri != NULL, NULL); + + handle = g_new0(VFSFile, 1); + fd = g_new0(VFSBufferedFile, 1); + fd->mem = g_malloc0(128000); + fd->fd = vfs_fopen(uri, "rb"); + + if (fd->fd == NULL) + { + g_free(fd->mem); + g_free(fd); + g_free(handle); + + return NULL; + } + + sz = vfs_fread(fd->mem, 1, 128000, fd->fd); + vfs_rewind(fd->fd); + + if (!sz) + { + vfs_fclose(fd->fd); + g_free(fd->mem); + g_free(fd); + g_free(handle); + + return NULL; + } + + fd->buffer = vfs_buffer_new(fd->mem, sz); + + handle->handle = fd; + handle->base = &buffered_file_const; + handle->uri = g_strdup(uri); + handle->ref = 1; + + return handle; +} + +VFSFile * +vfs_buffered_file_release_live_fd(VFSFile *fd) +{ + VFSBufferedFile *file = (VFSBufferedFile *) fd; + VFSFile *out; + + g_return_val_if_fail(file != NULL, NULL); + + out = file->fd; + file->fd = NULL; + + vfs_fclose(fd); + + return out; +}