diff -r 000000000000 -r 7a654d6de88f libgnomevfs2-mythtv/modules/mythtv-method.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgnomevfs2-mythtv/modules/mythtv-method.c Mon Oct 23 22:28:02 2006 +0100 @@ -0,0 +1,268 @@ +/* + * @author Hallyson Melo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include + +#include "myth_file_transfer.h" + +#define GST_MYTHTV_ID_NUM 1 +#define MYTHTV_VERSION_DEFAULT 30 + +static GnomeVFSResult do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context); + +typedef struct { + MythFileTransfer *file_transfer; + + gint mythtv_version; + guint64 content_size; + guint64 bytes_read; + guint64 read_offset; + gboolean live_tv; +} MythtvHandle; + + + +static GnomeVFSResult +do_open (GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle, + GnomeVFSURI *uri, + GnomeVFSOpenMode mode, + GnomeVFSContext *context) +{ + MythtvHandle *myth_handle = g_new0 (MythtvHandle, 1); + + const gchar *user, *password, *host, *transfer_uri; + guint port; + gchar *path; + gboolean ret; + + _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL); + _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL); + + if (mode & GNOME_VFS_OPEN_WRITE) { + return GNOME_VFS_ERROR_NOT_PERMITTED; + } + + if ((host = gnome_vfs_uri_get_host_name (uri)) == NULL) { + return GNOME_VFS_ERROR_INVALID_HOST_NAME; + } + + /* Parse URI */ + path = gnome_vfs_unescape_string (uri->text, NULL); + port = gnome_vfs_uri_get_host_port (uri); + user = gnome_vfs_uri_get_user_name (uri); + password = gnome_vfs_uri_get_password (uri); + + transfer_uri = gnome_vfs_uri_to_string (uri, + GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD); + + /* Initialize mythtv handler*/ + myth_handle->file_transfer = NULL; + myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT; + myth_handle->bytes_read = 0; + myth_handle->content_size = -1; + myth_handle->read_offset = 0; + myth_handle->live_tv = FALSE; + + /* Connect to the backend */ + myth_handle->file_transfer = myth_file_transfer_new ( GST_MYTHTV_ID_NUM /*mythtv->live_tv_id*/, + g_string_new( transfer_uri ), -1, myth_handle->mythtv_version ); + + if ( myth_handle->file_transfer == NULL ) { + return GNOME_VFS_ERROR_NOT_OPEN; + } + + /* sets the Playback monitor connection */ + ret = myth_file_transfer_playback_setup( &(myth_handle->file_transfer), myth_handle->live_tv ); + if (ret == FALSE) { + g_printerr ("Mythtv FileTransfer playback setup error\n"); + return GNOME_VFS_ERROR_NOT_OPEN; + } + + /* sets the FileTransfer instance connection (video/audio download) */ + ret = myth_file_transfer_setup( &(myth_handle->file_transfer), myth_handle->live_tv ); + + if ( ret == FALSE ) { + g_printerr ("MythTV FileTransfer request failed when setting up socket connection!\n" ); + return GNOME_VFS_ERROR_NOT_OPEN; + } + + // TODO: Verify if file exists in the backend + + myth_handle->content_size = myth_handle->file_transfer->filesize; + + *method_handle = (GnomeVFSMethodHandle *) myth_handle; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_read (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + gpointer buffer, + GnomeVFSFileSize num_bytes, + GnomeVFSFileSize *bytes_read, + GnomeVFSContext *context) +{ + MythtvHandle *myth_handle = (MythtvHandle *) method_handle; + guint len = 0, offset = 0; + GnomeVFSFileSize bytes_to_read; + + g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu", myth_handle->content_size, + myth_handle->bytes_read, num_bytes); + + *bytes_read = 0; + + if (myth_handle->bytes_read >= myth_handle->content_size) + return GNOME_VFS_ERROR_EOF; + + // fixme: change this to min math function + if (num_bytes > myth_handle->content_size - myth_handle->bytes_read) + bytes_to_read = myth_handle->content_size - myth_handle->bytes_read; + else + bytes_to_read = num_bytes; + + /* Loop sending the Myth File Transfer request: + * Retry whilst authentication fails and we supply it. */ + + // lock here ??? + while ( bytes_to_read > 0 ) { + len = myth_file_transfer_read( myth_handle->file_transfer, + buffer + offset, bytes_to_read, TRUE ); + + if ( len > 0 ) { + offset += len; + bytes_to_read -= len; + } else { + break; + } + + if ( offset == num_bytes ) + break; + } + + if (( offset <= 0 ) && !myth_handle->live_tv ) + return GNOME_VFS_ERROR_EOF; + + myth_handle->read_offset += offset; + myth_handle->bytes_read += offset; + *bytes_read = offset; + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_close (GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle, + GnomeVFSContext *context) +{ + MythtvHandle *myth_handle = (MythtvHandle *) method_handle; + + if (myth_handle->file_transfer) + g_object_unref (myth_handle->file_transfer); + + g_free (myth_handle); + + return GNOME_VFS_OK; +} + +static GnomeVFSResult +do_get_file_info (GnomeVFSMethod *method, + GnomeVFSURI *uri, + GnomeVFSFileInfo *file_info, + GnomeVFSFileInfoOptions options, + GnomeVFSContext *context) +{ + GString *name = g_string_new ("hallyson"); + file_info->name = g_string_free (name, FALSE);//"hallyson.txt";//get_base_from_uri (uri); + file_info->valid_fields = file_info->valid_fields + | GNOME_VFS_FILE_INFO_FIELDS_TYPE + | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE + | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS; + file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; + file_info->mime_type = "video/x-nuv"; //g_strdup (gnome_vfs_mime_type_from_name (file_info->name)); + file_info->permissions = + GNOME_VFS_PERM_USER_READ | + GNOME_VFS_PERM_OTHER_READ | + GNOME_VFS_PERM_GROUP_READ; + + return GNOME_VFS_OK; +} + +static gboolean +do_is_local (GnomeVFSMethod *method, + const GnomeVFSURI *uri) +{ + return FALSE; +} + +static GnomeVFSMethod method = { + sizeof (GnomeVFSMethod), + do_open, + NULL, + do_close, + do_read, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + do_get_file_info, + NULL, + do_is_local, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + + +GnomeVFSMethod * +vfs_module_init (const char *method_name, const char *args) +{ + return &method; +} + +void +vfs_module_shutdown (GnomeVFSMethod *method) +{ +}