libgnomevfs2-mythtv/modules/mythtv-method.c
author rosfran
Mon Nov 27 22:07:59 2006 +0000 (2006-11-27)
branchtrunk
changeset 119 96d4296e4492
parent 111 dfa72795bd32
child 127 a7237ce91c3b
permissions -rwxr-xr-x
[svn r120] Added new constructor to BackendInfo, using the GMythURI.
     1 /*
     2  * @author Hallyson Melo <hallyson.melo@indt.org.br>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU Lesser General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU Lesser General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  */
    18 
    19 #ifdef HAVE_CONFIG_H
    20 #include <config.h>
    21 #endif
    22 
    23 #include <string.h>
    24 #include <glib.h>
    25 #include <math.h>
    26 
    27 #include <libgnomevfs/gnome-vfs-module.h>
    28 #include <libgnomevfs/gnome-vfs-utils.h>
    29 
    30 #include "gmyth_file_transfer.h"
    31 
    32 #define GST_MYTHTV_ID_NUM               1
    33 #define MYTHTV_VERSION_DEFAULT          30
    34 
    35 #define MYTHTV_BUFFER_SIZE		1024*64
    36 
    37 static GnomeVFSResult do_read (GnomeVFSMethod *method,
    38                                GnomeVFSMethodHandle *method_handle,
    39                                gpointer buffer,
    40                                GnomeVFSFileSize num_bytes,
    41                                GnomeVFSFileSize *bytes_read,
    42                                GnomeVFSContext *context);
    43 
    44 typedef struct {
    45     GMythFileTransfer *file_transfer;
    46     
    47     gint mythtv_version;
    48     guint64 content_size;
    49     guint64 bytes_read;
    50 
    51     GByteArray *buffer;
    52     gsize buffer_remain;
    53 } MythtvHandle;
    54 
    55 
    56 
    57 static GnomeVFSResult
    58 do_open (GnomeVFSMethod *method,
    59          GnomeVFSMethodHandle **method_handle,
    60          GnomeVFSURI *uri,
    61          GnomeVFSOpenMode mode,
    62          GnomeVFSContext *context)
    63 {
    64 
    65     const gchar *user, *password, *host, *transfer_uri;
    66     MythtvHandle *myth_handle;
    67 
    68     GString *uri_str;
    69     guint port;
    70     gchar *path;
    71     gboolean ret;
    72 
    73     _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
    74     _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
    75 
    76     g_debug ("[%s] Calling do_open function", __FUNCTION__);
    77 	    
    78     myth_handle = g_new0 (MythtvHandle, 1);
    79 
    80     if (mode & GNOME_VFS_OPEN_WRITE) {
    81         return GNOME_VFS_ERROR_NOT_PERMITTED;
    82     }
    83 
    84     if ((host = gnome_vfs_uri_get_host_name (uri)) == NULL) {
    85 	return GNOME_VFS_ERROR_INVALID_HOST_NAME;
    86     }
    87 
    88     /* Parse URI */
    89     path = gnome_vfs_unescape_string (uri->text, NULL);
    90     port = gnome_vfs_uri_get_host_port (uri);
    91     user = gnome_vfs_uri_get_user_name (uri);
    92     password = gnome_vfs_uri_get_password (uri);
    93 
    94     transfer_uri = gnome_vfs_uri_to_string (uri, 
    95 		    GNOME_VFS_URI_HIDE_USER_NAME | GNOME_VFS_URI_HIDE_PASSWORD);
    96    
    97     /* Initialize mythtv handler*/
    98     myth_handle->file_transfer = NULL;
    99     myth_handle->mythtv_version = MYTHTV_VERSION_DEFAULT;
   100     myth_handle->bytes_read = 0;
   101     myth_handle->content_size = -1;
   102 
   103     /* Connect to the backend */
   104     myth_handle->file_transfer = gmyth_file_transfer_new ();
   105 
   106     g_return_val_if_fail (myth_handle->file_transfer != NULL, GNOME_VFS_ERROR_NOT_OPEN);
   107 
   108     /* sets the Playback monitor connection */
   109     uri_str = g_string_new (transfer_uri);
   110     ret = gmyth_file_transfer_open (myth_handle->file_transfer, uri_str);
   111     if (ret == FALSE) {
   112         g_printerr ("Mythtv FileTransfer open error\n");
   113         return GNOME_VFS_ERROR_NOT_OPEN;
   114     }
   115     g_string_free (uri_str, TRUE);
   116 
   117     // TODO: Verify if file exists in the backend
   118 
   119     myth_handle->content_size = myth_handle->file_transfer->filesize;
   120     
   121     myth_handle->buffer = g_byte_array_sized_new (MYTHTV_BUFFER_SIZE);
   122     myth_handle->buffer_remain = 0;
   123 
   124     *method_handle = (GnomeVFSMethodHandle *) myth_handle;
   125 
   126     return GNOME_VFS_OK;
   127 }
   128 
   129 static GnomeVFSResult
   130 do_read (GnomeVFSMethod *method,
   131          GnomeVFSMethodHandle *method_handle,
   132          gpointer buffer,
   133          GnomeVFSFileSize num_bytes,
   134          GnomeVFSFileSize *bytes_read,
   135          GnomeVFSContext *context)
   136 {
   137     MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
   138     GnomeVFSFileSize bytes_to_read;
   139 
   140     g_debug ("do_read(): file size: %llu, already read: %llu, requested: %llu, buffer_remain: %du", 
   141 		    myth_handle->content_size, myth_handle->bytes_read, num_bytes, 
   142 				myth_handle->buffer_remain);
   143 
   144     *bytes_read = 0;
   145 
   146     if (myth_handle->bytes_read >= myth_handle->content_size)
   147         return GNOME_VFS_ERROR_EOF;
   148 
   149     // fixme: change this to min math function
   150     if (num_bytes > myth_handle->content_size - myth_handle->bytes_read)
   151 	    bytes_to_read = myth_handle->content_size - myth_handle->bytes_read;
   152     else
   153 	    bytes_to_read = num_bytes;
   154 
   155     /* Loop sending the Myth File Transfer request:
   156     * Retry whilst authentication fails and we supply it. */
   157   
   158   if ( bytes_to_read > myth_handle->buffer_remain ) {
   159   	GByteArray *tmp_buffer = g_byte_array_new();
   160 
   161     gint len = gmyth_file_transfer_read( myth_handle->file_transfer,
   162           tmp_buffer, MYTHTV_BUFFER_SIZE - myth_handle->buffer_remain, TRUE );
   163 
   164 		if (len < 0)
   165 		    return GNOME_VFS_ERROR_IO;
   166 
   167     myth_handle->buffer = g_byte_array_append( myth_handle->buffer, 
   168     				g_memdup( tmp_buffer->data, len ), len );
   169 
   170 		myth_handle->buffer_remain += len;
   171 
   172 		g_debug ( "Reading %d data from backend", MYTHTV_BUFFER_SIZE - myth_handle->buffer_remain );
   173 	
   174     if ( tmp_buffer != NULL ) {
   175     	g_byte_array_free( tmp_buffer, TRUE );
   176     	tmp_buffer = NULL;    	
   177     }
   178 
   179   }
   180     
   181     bytes_to_read = (bytes_to_read > myth_handle->buffer_remain) ? myth_handle->buffer_remain : bytes_to_read;
   182 
   183     g_debug ("Returning %du bytes to gnomevfs", (gint) bytes_to_read);
   184 	  /* gets the first buffer_size bytes from the byte array buffer variable */ 
   185 
   186 	  g_memmove( buffer, myth_handle->buffer->data, bytes_to_read );
   187 
   188     myth_handle->bytes_read += bytes_to_read;
   189     myth_handle->buffer_remain -= bytes_to_read;    
   190 
   191   	/* flushs the newly buffer got from byte array */
   192   	myth_handle->buffer = g_byte_array_remove_range( myth_handle->buffer, 0, bytes_to_read );
   193     *bytes_read = bytes_to_read;
   194   
   195     return GNOME_VFS_OK;
   196 }
   197 
   198 static GnomeVFSResult
   199 do_close (GnomeVFSMethod *method,
   200           GnomeVFSMethodHandle *method_handle,
   201           GnomeVFSContext *context)
   202 {
   203 
   204     MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
   205 
   206     if (myth_handle->file_transfer) {
   207 	gmyth_file_transfer_close (myth_handle->file_transfer);
   208         g_object_unref (myth_handle->file_transfer);
   209 	myth_handle->file_transfer = NULL;
   210     }
   211 
   212     g_free (myth_handle);
   213 
   214     return GNOME_VFS_OK;
   215 }
   216 
   217 static GnomeVFSResult
   218 do_get_file_info (GnomeVFSMethod *method,
   219                   GnomeVFSURI *uri,
   220                   GnomeVFSFileInfo *file_info,
   221                   GnomeVFSFileInfoOptions options,
   222                   GnomeVFSContext *context)
   223 {
   224     file_info->name = g_strdup ("fixme.txt");
   225     file_info->valid_fields = file_info->valid_fields
   226         | GNOME_VFS_FILE_INFO_FIELDS_TYPE
   227         | GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
   228         | GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
   229     file_info->type = GNOME_VFS_FILE_TYPE_REGULAR;
   230     // fixme: get from file extension?
   231     file_info->mime_type = g_strdup ("video/x-nuv");
   232     file_info->permissions =
   233         GNOME_VFS_PERM_USER_READ |
   234         GNOME_VFS_PERM_OTHER_READ |
   235         GNOME_VFS_PERM_GROUP_READ;
   236 
   237     return GNOME_VFS_OK;
   238 }
   239 
   240 static gboolean
   241 do_is_local (GnomeVFSMethod *method,
   242              const GnomeVFSURI *uri)
   243 {
   244 	return FALSE;
   245 }
   246 
   247 static GnomeVFSMethod method = {
   248 	sizeof (GnomeVFSMethod),
   249 	do_open,
   250 	NULL,
   251 	do_close,
   252 	do_read,
   253 	NULL,
   254 	NULL,
   255 	NULL,
   256 	NULL,
   257 	NULL,
   258 	NULL,
   259 	NULL,
   260 	do_get_file_info,
   261 	NULL,
   262 	do_is_local,
   263 	NULL,
   264 	NULL,
   265 	NULL,
   266 	NULL,
   267 	NULL,
   268 	NULL,
   269 	NULL,
   270 	NULL,
   271 	NULL,
   272 	NULL,
   273 	NULL,
   274 	NULL,
   275 };
   276 
   277 
   278 GnomeVFSMethod *
   279 vfs_module_init (const char *method_name, const char *args)
   280 {
   281 	return &method;
   282 }
   283 
   284 void
   285 vfs_module_shutdown (GnomeVFSMethod *method)
   286 {
   287 }