[svn r612] Optimizations - doesn't need to call all the time the URI functions to see if is a LiveTV, and if it is a local file URI.
2 * @author Hallyson Melo <hallyson.melo@indt.org.br>
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.
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.
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
25 #include <glib/gprintf.h>
26 #include <glib/gstdio.h>
29 #include <libgnomevfs/gnome-vfs-module.h>
30 #include <libgnomevfs/gnome-vfs-utils.h>
32 #include <gmyth/gmyth_file.h>
33 #include <gmyth/gmyth_file_transfer.h>
34 #include <gmyth/gmyth_file_local.h>
35 #include <gmyth/gmyth_livetv.h>
36 #include <gmyth/gmyth_uri.h>
37 #include <gmyth/gmyth_recorder.h>
38 #include <gmyth/gmyth_backendinfo.h>
39 #include <gmyth/gmyth_util.h>
40 #include <gmyth/gmyth_remote_util.h>
41 #include <gmyth/gmyth_tvchain.h>
42 #include <gmyth/gmyth_programinfo.h>
44 #define GST_MYTHTV_ID_NUM 1
45 #define MYTHTV_VERSION_DEFAULT 30
46 #define MYTHTV_TRANSFER_MAX_WAITS 100
48 /* internal GnomeVFS plug-in buffer size ( 120 Kbytes ) */
49 #define MYTHTV_BUFFER_SIZE 80*1024
50 /* internally sized GnomeVFS plug-in buffer ( 4 Kbytes ) */
51 #define MYTHTV_MAX_VFS_BUFFER_SIZE 4096
52 /* maximum number of bytes to be requested to the MythTV backend ( 64 Kbytes ) */
53 #define MYTHTV_MAX_REQUEST_SIZE 64*1024
58 GMythBackendInfo *backend_info;
60 GMythRecorder *live_recorder;
64 gboolean is_livetv; /* it is, or not a Live TV content transfer */
65 gboolean is_local_file; /* tell if the file is local to the current content transfer */
74 static GnomeVFSResult do_read (GnomeVFSMethod * method,
75 GnomeVFSMethodHandle * method_handle,
77 GnomeVFSFileSize num_bytes,
78 GnomeVFSFileSize * bytes_read,
79 GnomeVFSContext * context);
81 static GnomeVFSResult myth_connection_start (MythtvHandle * method_handle);
82 static void myth_destroy_handle (MythtvHandle * method_handle);
83 static GnomeVFSResult myth_handle_new (GnomeVFSURI * uri,
84 MythtvHandle ** method_handle);
85 static GnomeVFSResult myth_get_file_info (MythtvHandle * myth_handle,
87 GnomeVFSFileInfo * info);
90 myth_handle_new (GnomeVFSURI * uri,
91 MythtvHandle ** method_handle)
96 _GNOME_VFS_METHOD_PARAM_CHECK (*method_handle == NULL);
98 if (gnome_vfs_uri_get_host_name (uri) == NULL) {
99 return GNOME_VFS_ERROR_INVALID_HOST_NAME;
102 *method_handle = g_new0 (MythtvHandle, 1);
103 (*method_handle)->mythtv_version = MYTHTV_VERSION_DEFAULT;
105 (*method_handle)->is_livetv = FALSE;
106 (*method_handle)->is_local_file = FALSE;
108 tmp_str1 = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
109 tmp_str2 = gnome_vfs_unescape_string (tmp_str1, "");
111 (*method_handle)->backend_info = gmyth_backend_info_new_with_uri (tmp_str2);
112 (*method_handle)->gmyth_uri = gmyth_uri_new_with_value (tmp_str2);
120 myth_destroy_handle (MythtvHandle * method_handle)
122 //TODO: abort if in tranfer state
124 if (method_handle->backend_info != NULL) {
125 g_object_unref (method_handle->backend_info);
126 method_handle->backend_info = NULL;
129 if (method_handle->channel_name != NULL) {
130 g_free (method_handle->channel_name);
131 method_handle->channel_name = NULL;
134 if (method_handle->livetv != NULL) {
135 g_object_unref (method_handle->livetv);
136 method_handle->livetv = NULL;
139 if (method_handle->file != NULL) {
140 g_object_unref (method_handle->file);
141 method_handle->file = NULL;
144 if (method_handle->gmyth_uri != NULL) {
145 g_object_unref (method_handle->gmyth_uri);
146 method_handle->gmyth_uri = NULL;
149 g_free (method_handle);
152 static GnomeVFSResult
153 myth_get_file_info (MythtvHandle * myth_handle,
155 GnomeVFSFileInfo * info)
158 GMythBackendInfo *backend_info;
160 _GNOME_VFS_METHOD_PARAM_CHECK (info != NULL);
163 if (myth_handle == NULL) {
167 tmp_str1 = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
168 tmp_str2 = gnome_vfs_unescape_string (tmp_str1, "");
170 backend_info = gmyth_backend_info_new_with_uri (tmp_str2);
171 gmyth_uri = gmyth_uri_new_with_value (tmp_str2);
176 backend_info = g_object_ref (myth_handle->backend_info);
177 gmyth_uri = g_object_ref (myth_handle->gmyth_uri);
180 info->valid_fields = 0;
181 info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
182 GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE |
183 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
185 info->type = GNOME_VFS_FILE_TYPE_REGULAR;
187 /* fixme: get from file extension? */
188 info->mime_type = g_strdup ("video/x-nuv");
189 info->permissions = GNOME_VFS_PERM_USER_READ |
190 GNOME_VFS_PERM_OTHER_READ |
191 GNOME_VFS_PERM_GROUP_READ;
194 info->name = g_strdup (gmyth_uri_get_path (gmyth_uri));
196 /* file size for remote files */
197 if ( ( myth_handle->is_livetv = gmyth_uri_is_livetv (gmyth_uri) ) == FALSE) {
198 GMythFile *file = NULL;
199 gboolean ret = FALSE;
201 /* Verifies if the file exists */
202 if (!gmyth_util_file_exists (backend_info,
203 gmyth_uri_get_path (gmyth_uri))) {
204 g_object_unref (file);
205 g_object_unref (backend_info);
206 g_debug ("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
207 return GNOME_VFS_ERROR_NOT_FOUND;
210 if ( ( myth_handle->is_local_file = gmyth_uri_is_local_file(gmyth_uri) ) == TRUE )
212 file = GMYTH_FILE( gmyth_file_local_new(backend_info) );
213 ret = gmyth_file_local_open ( GMYTH_FILE_LOCAL( file ) );
215 file = GMYTH_FILE( gmyth_file_transfer_new(backend_info) );
216 ret = gmyth_file_transfer_open ( GMYTH_FILE_TRANSFER(file), gmyth_uri_get_path (gmyth_uri));
220 g_object_unref (file);
221 g_object_unref (backend_info);
222 g_debug ("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
223 return GNOME_VFS_ERROR_NOT_FOUND;
226 info->size = gmyth_file_get_filesize (file);
227 info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE;
228 g_object_unref (file);
231 g_object_unref (backend_info);
232 g_object_unref (gmyth_uri);
237 static GnomeVFSResult
238 myth_connection_start (MythtvHandle * method_handle)
240 GnomeVFSResult result = GNOME_VFS_OK;
242 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
243 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle->backend_info != NULL);
245 /* Connect to the backend */
246 if ( ( method_handle->is_livetv = gmyth_uri_is_livetv (method_handle->gmyth_uri) ) == TRUE) {
247 method_handle->livetv = gmyth_livetv_new (method_handle->backend_info);
248 method_handle->channel_name = gmyth_uri_get_channel_name (method_handle->gmyth_uri);
250 if (method_handle->channel_name != NULL) {
251 if (gmyth_livetv_channel_name_setup (method_handle->livetv,
252 method_handle->channel_name) == FALSE) {
253 result = GNOME_VFS_ERROR_INVALID_URI;
256 } else if (gmyth_livetv_setup (method_handle->livetv) == FALSE) {
257 result = GNOME_VFS_ERROR_INVALID_URI;
262 method_handle->file =
263 GMYTH_FILE( gmyth_livetv_create_file_transfer (method_handle->livetv) );
265 if (method_handle->file == NULL) {
266 result = GNOME_VFS_ERROR_INVALID_URI;
267 g_debug ("MythTV FileTransfer is NULL!\n");
271 if (!gmyth_file_transfer_open ( GMYTH_FILE_TRANSFER(method_handle->file),
272 method_handle->livetv->uri != NULL ?
273 gmyth_uri_get_path (method_handle->livetv->uri) :
274 method_handle->livetv->proginfo->pathname->str)) {
276 g_debug ("Couldn't open MythTV FileTransfer is NULL!\n");
277 result = GNOME_VFS_ERROR_NOT_OPEN;
283 /* Verifies if the file exists */
284 if (!gmyth_util_file_exists (method_handle->backend_info,
285 gmyth_uri_get_path (method_handle->gmyth_uri))) {
287 g_debug ("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
291 if ( ( method_handle->is_local_file = gmyth_uri_is_local_file(method_handle->gmyth_uri) ) == TRUE )
293 method_handle->file = GMYTH_FILE( gmyth_file_local_new(method_handle->backend_info) );
294 ret = gmyth_file_local_open ( GMYTH_FILE_LOCAL( method_handle->file ) );
296 method_handle->file = GMYTH_FILE( gmyth_file_transfer_new(method_handle->backend_info) );
297 ret = gmyth_file_transfer_open ( GMYTH_FILE_TRANSFER(method_handle->file),
298 gmyth_uri_get_path (method_handle->gmyth_uri));
301 /* sets the Playback monitor connection */
304 g_debug ("NOT FOUND %s/%d", __FUNCTION__, __LINE__);
305 result = GNOME_VFS_ERROR_NOT_FOUND;
308 } /* if - LiveTV or not? */
310 method_handle->configured = TRUE;
312 if (method_handle->file == NULL) {
313 result = GNOME_VFS_ERROR_NOT_OPEN;
321 static GnomeVFSResult
322 do_open (GnomeVFSMethod * method,
323 GnomeVFSMethodHandle ** method_handle,
325 GnomeVFSOpenMode mode, GnomeVFSContext * context)
327 MythtvHandle *myth_handle = NULL;
328 GnomeVFSResult result = GNOME_VFS_OK;
330 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
331 _GNOME_VFS_METHOD_PARAM_CHECK (uri != NULL);
333 if (mode & GNOME_VFS_OPEN_WRITE) {
334 return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
337 result = myth_handle_new (uri, &myth_handle);
338 if (result != GNOME_VFS_OK)
341 result = myth_connection_start (myth_handle);
342 if (result != GNOME_VFS_OK) {
343 myth_destroy_handle (myth_handle);
348 *method_handle = (GnomeVFSMethodHandle *) myth_handle;
353 static GnomeVFSResult
354 do_create (GnomeVFSMethod *method,
355 GnomeVFSMethodHandle **method_handle,
357 GnomeVFSOpenMode mode,
360 GnomeVFSContext *context)
362 return GNOME_VFS_ERROR_NOT_SUPPORTED;
365 static GnomeVFSResult
366 do_close (GnomeVFSMethod * method,
367 GnomeVFSMethodHandle * method_handle,
368 GnomeVFSContext * context)
370 MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
372 myth_destroy_handle (myth_handle);
378 static GnomeVFSResult
379 do_read (GnomeVFSMethod * method,
380 GnomeVFSMethodHandle * method_handle,
382 GnomeVFSFileSize num_bytes,
383 GnomeVFSFileSize * bytes_read,
384 GnomeVFSContext * context)
386 GnomeVFSResult retval = GNOME_VFS_OK;
387 MythtvHandle *myth_handle;
388 GMythFileReadResult result;
389 GByteArray *myth_buffer = g_byte_array_new ();
391 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
393 myth_handle = (MythtvHandle *) method_handle;
394 if ( myth_handle->is_local_file )
395 result = gmyth_file_local_read ( GMYTH_FILE_LOCAL(myth_handle->file),
397 num_bytes, myth_handle->is_livetv );
399 result = gmyth_file_transfer_read ( GMYTH_FILE_TRANSFER(myth_handle->file),
401 num_bytes, myth_handle->is_livetv );
403 if (result == GMYTH_FILE_READ_ERROR) {
404 retval = GNOME_VFS_ERROR_IO;
407 if (result == GMYTH_FILE_READ_EOF) {
408 retval = GNOME_VFS_ERROR_EOF;
411 if (myth_buffer->len > 0) {
412 g_memmove (buffer, myth_buffer->data, myth_buffer->len);
413 *bytes_read = (GnomeVFSFileSize) myth_buffer->len;
414 myth_handle->offset += myth_buffer->len;
415 g_byte_array_free (myth_buffer, TRUE);
421 static GnomeVFSResult
422 do_write (GnomeVFSMethod *method,
423 GnomeVFSMethodHandle *method_handle,
424 gconstpointer buffer,
425 GnomeVFSFileSize num_bytes,
426 GnomeVFSFileSize *bytes_written,
427 GnomeVFSContext *context)
429 return GNOME_VFS_ERROR_NOT_SUPPORTED;
432 static GnomeVFSResult
433 do_seek (GnomeVFSMethod *method,
434 GnomeVFSMethodHandle *method_handle,
435 GnomeVFSSeekPosition whence,
436 GnomeVFSFileOffset offset,
437 GnomeVFSContext *context)
439 MythtvHandle *myth_handle;
440 //guint64 whence_p = 0;
441 //gint64 new_offset =0;
443 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
445 myth_handle = (MythtvHandle *) method_handle;
447 g_debug ("seek offset%"G_GINT64_FORMAT" whence %d", offset, whence);
449 return GNOME_VFS_ERROR_NOT_SUPPORTED;
451 if (gmyth_uri_is_livetv (myth_handle->gmyth_uri))
455 case GNOME_VFS_SEEK_START:
458 case GNOME_VFS_SEEK_CURRENT:
459 whence_p = myth_handle->offset;
461 case GNOME_VFS_SEEK_END:
462 return GNOME_VFS_ERROR_NOT_SUPPORTED;
465 new_offset = gmyth_file_transfer_seek (myth_handle->file, offset, whence_p);
466 if (new_offset != 0) {
467 myth_handle->offset = new_offset;
471 return GNOME_VFS_ERROR_NOT_SUPPORTED;
475 static GnomeVFSResult
476 do_tell (GnomeVFSMethod *method,
477 GnomeVFSMethodHandle *method_handle,
478 GnomeVFSFileSize *offset_return)
480 MythtvHandle *myth_handle = NULL;
482 _GNOME_VFS_METHOD_PARAM_CHECK (method_handle != NULL);
484 myth_handle = (MythtvHandle *) method_handle;
485 *offset_return = myth_handle->offset;
490 static GnomeVFSResult
491 do_truncate_handle (GnomeVFSMethod *method,
492 GnomeVFSMethodHandle *method_handle,
493 GnomeVFSFileSize where,
494 GnomeVFSContext *context)
496 return GNOME_VFS_ERROR_READ_ONLY;
499 static GnomeVFSResult
500 do_open_directory (GnomeVFSMethod *method,
501 GnomeVFSMethodHandle **method_handle,
503 GnomeVFSFileInfoOptions options,
504 GnomeVFSContext *context)
506 return GNOME_VFS_ERROR_NOT_SUPPORTED;
509 static GnomeVFSResult
510 do_close_directory (GnomeVFSMethod *method,
511 GnomeVFSMethodHandle *method_handle,
512 GnomeVFSContext *context)
514 return GNOME_VFS_ERROR_NOT_SUPPORTED;
517 static GnomeVFSResult
518 do_read_directory (GnomeVFSMethod *method,
519 GnomeVFSMethodHandle *method_handle,
520 GnomeVFSFileInfo *file_info,
521 GnomeVFSContext *context)
523 return GNOME_VFS_ERROR_NOT_SUPPORTED;
527 static GnomeVFSResult
528 do_get_file_info (GnomeVFSMethod * method,
530 GnomeVFSFileInfo * file_info,
531 GnomeVFSFileInfoOptions options,
532 GnomeVFSContext * context)
534 return myth_get_file_info (NULL, uri, file_info);
537 static GnomeVFSResult
538 do_get_file_info_from_handle (GnomeVFSMethod *method,
539 GnomeVFSMethodHandle *method_handle,
540 GnomeVFSFileInfo *file_info,
541 GnomeVFSFileInfoOptions options,
542 GnomeVFSContext *context)
544 MythtvHandle *myth_handle = (MythtvHandle *) method_handle;
546 return myth_get_file_info (myth_handle, NULL, file_info);
550 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)
555 static GnomeVFSResult
556 do_make_directory (GnomeVFSMethod *method,
559 GnomeVFSContext *context)
561 return GNOME_VFS_ERROR_READ_ONLY;
564 static GnomeVFSResult
565 do_remove_directory (GnomeVFSMethod *method,
567 GnomeVFSContext *context)
569 return GNOME_VFS_ERROR_READ_ONLY;
572 static GnomeVFSResult
573 do_move (GnomeVFSMethod *method,
574 GnomeVFSURI *old_uri,
575 GnomeVFSURI *new_uri,
576 gboolean force_replace,
577 GnomeVFSContext *context)
579 return GNOME_VFS_ERROR_READ_ONLY;
582 static GnomeVFSResult
583 do_unlink (GnomeVFSMethod *method,
585 GnomeVFSContext *context)
587 return GNOME_VFS_ERROR_READ_ONLY;
590 static GnomeVFSResult
591 do_check_same_fs (GnomeVFSMethod *method,
594 gboolean *same_fs_return,
595 GnomeVFSContext *context)
597 return GNOME_VFS_ERROR_NOT_SUPPORTED;
600 static GnomeVFSResult
601 do_set_file_info (GnomeVFSMethod *method,
603 const GnomeVFSFileInfo *info,
604 GnomeVFSSetFileInfoMask mask,
605 GnomeVFSContext *context)
607 return GNOME_VFS_ERROR_READ_ONLY;
610 static GnomeVFSResult
611 do_truncate (GnomeVFSMethod *method,
613 GnomeVFSFileSize where,
614 GnomeVFSContext *context)
616 return GNOME_VFS_ERROR_READ_ONLY;
619 static GnomeVFSResult
620 do_find_directory (GnomeVFSMethod *method,
621 GnomeVFSURI *near_uri,
622 GnomeVFSFindDirectoryKind kind,
623 GnomeVFSURI **result_uri,
624 gboolean create_if_needed,
625 gboolean find_if_needed,
627 GnomeVFSContext *context)
629 return GNOME_VFS_ERROR_NOT_SUPPORTED;
632 static GnomeVFSResult
633 do_create_symbolic_link (GnomeVFSMethod *method,
635 const char *target_reference,
636 GnomeVFSContext *context)
638 return GNOME_VFS_ERROR_READ_ONLY;
641 static GnomeVFSResult
642 do_monitor_add (GnomeVFSMethod *method,
643 GnomeVFSMethodHandle **method_handle_return,
645 GnomeVFSMonitorType monitor_type)
647 return GNOME_VFS_ERROR_NOT_SUPPORTED;
650 static GnomeVFSResult
651 do_monitor_cancel (GnomeVFSMethod *method,
652 GnomeVFSMethodHandle *method_handle)
654 return GNOME_VFS_ERROR_NOT_SUPPORTED;
657 static GnomeVFSResult
658 do_file_control (GnomeVFSMethod *method,
659 GnomeVFSMethodHandle *method_handle,
660 const char *operation,
661 gpointer operation_data,
662 GnomeVFSContext *context)
664 return GNOME_VFS_ERROR_NOT_SUPPORTED;
667 static GnomeVFSMethod method = {
668 sizeof (GnomeVFSMethod),
681 do_get_file_info_from_handle,
691 do_create_symbolic_link,
699 vfs_module_init (const char *method_name, const char *args)
705 vfs_module_shutdown (GnomeVFSMethod * method)