gmyth-stream/libgnomevfs2/modules/gmythstream-method.c
author renatofilho
Thu Apr 12 22:34:28 2007 +0100 (2007-04-12)
branchtrunk
changeset 540 d6f9b0417346
parent 539 c67cec9e6073
child 541 0bf798c3f17e
permissions -rw-r--r--
[svn r545] fixed parse
     1 /*
     2  * @author Artur Duque de Souza <souza.artur@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  m * 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 <sys/socket.h> /* for socket(), connect(), send(), and recv() */
    24 #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
    25 #include <stdlib.h>     /* for atoi() and exit() */
    26 #include <string.h>     /* for memset() */
    27 #include <unistd.h>     /* for close() */
    28 #include <errno.h>
    29 
    30 #include <glib.h>
    31 #include <glib/gprintf.h>
    32 #include <glib/gstdio.h>
    33 #include <gmyth-stream-client.h>
    34 
    35 #include <libgnomevfs/gnome-vfs-module.h>
    36 #include <libgnomevfs/gnome-vfs-utils.h>
    37 
    38 #define BUFFER_SIZE 4096
    39 
    40 typedef struct {
    41     gint port;
    42     gchar* hostname;
    43 
    44     GMythStreamClient *stream;
    45     gint fd;
    46 } gmsHandle;
    47 
    48 typedef struct {
    49     gchar *file_name;
    50     gchar *mux;
    51     gchar *vcodec;
    52     guint vbitrate;
    53     gdouble fps;
    54     gchar *acodec;
    55     guint abitrate;
    56     guint width;
    57     guint height;
    58     guint port;
    59     gchar *opt;
    60 } UriArgs;
    61 
    62 
    63 static gmsHandle* gmsHandle_new(GnomeVFSURI *uri);
    64 
    65 static GnomeVFSResult
    66 do_open (GnomeVFSMethod        *method,
    67 	 GnomeVFSMethodHandle **method_handle,
    68 	 GnomeVFSURI           *uri,
    69 	 GnomeVFSOpenMode       mode,
    70 	 GnomeVFSContext       *context);
    71 
    72 static GnomeVFSResult
    73 do_read (GnomeVFSMethod       *method,
    74 	 GnomeVFSMethodHandle *method_handle,
    75 	 gpointer              buffer,
    76 	 GnomeVFSFileSize      bytes,
    77 	 GnomeVFSFileSize     *bytes_read,
    78 	 GnomeVFSContext      *context);
    79 
    80 static GnomeVFSResult
    81 do_close (GnomeVFSMethod * method,
    82           GnomeVFSMethodHandle * method_handle,
    83           GnomeVFSContext * context);
    84 
    85 static GnomeVFSResult
    86 do_get_file_info (GnomeVFSMethod * method,
    87 		  GnomeVFSURI * uri,
    88 		  GnomeVFSFileInfo * file_info,
    89 		  GnomeVFSFileInfoOptions options,
    90 		  GnomeVFSContext * context);
    91 
    92 
    93 static GnomeVFSResult
    94 do_get_file_info_from_handle (GnomeVFSMethod 		*method,
    95                               GnomeVFSMethodHandle 	*method_handle,
    96                               GnomeVFSFileInfo 		*file_info,
    97                               GnomeVFSFileInfoOptions    options,
    98                               GnomeVFSContext 		*context);
    99 
   100 
   101 static gboolean
   102 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri);
   103 
   104 
   105 static gmsHandle* gmsHandle_new(GnomeVFSURI *uri)
   106 {
   107     gmsHandle* handler = (gmsHandle*)g_malloc0(sizeof(gmsHandle));
   108 
   109     handler->hostname = (gchar*)gnome_vfs_uri_get_host_name(uri);
   110     handler->port = gnome_vfs_uri_get_host_port(uri);
   111     handler->stream = gmyth_stream_client_new ();
   112 
   113     return handler;
   114 }
   115 
   116 static GnomeVFSMethod method = {
   117     sizeof (GnomeVFSMethod),
   118     do_open,                       /* open */
   119     NULL,                          /* create */
   120     do_close,                      /* close */
   121     do_read,                       /* read */
   122     NULL,                          /* write */
   123     NULL,                          /* seek */
   124     NULL,                          /* tell */
   125     NULL,                          /* truncate_handle */
   126     NULL,                          /* open_directory */
   127     NULL,                          /* close_directory */
   128     NULL,                          /* read_directory */
   129     do_get_file_info,              /* get_file_info */
   130     do_get_file_info_from_handle,  /* get_file_info_from_handle */
   131     do_is_local,                   /* is_local */
   132     NULL,                          /* make_directory */
   133     NULL,                          /* remove_directory */
   134     NULL,                          /* move */
   135     NULL,                          /* unlink */
   136     NULL,                          /* check_same_fs */
   137     NULL,                          /* set_file_info */
   138     NULL,                          /* truncate */
   139     NULL,                          /* find_directory */
   140     NULL,                          /* create_symbolic_link */
   141     NULL,                          /* monitor_add */
   142     NULL,                          /* monitor_cancel */
   143     NULL                           /* file_control */
   144 };
   145 
   146 GnomeVFSMethod *
   147 vfs_module_init (const char *method_name, const char *args)
   148 {
   149     return &method;
   150 }
   151 
   152 void
   153 vfs_module_shutdown (GnomeVFSMethod* method)
   154 {
   155     return;
   156 }
   157 
   158 static UriArgs *
   159 _uri_parse_args (const GnomeVFSURI *uri)
   160 {
   161 
   162     gchar *file;
   163     UriArgs *info = g_new0 (UriArgs, 1);
   164 	GSList *args = NULL;
   165 	gchar *c;
   166 	GString *entry;
   167 	gboolean open = FALSE;
   168 	gchar **prop;
   169     GSList* walk;
   170 	gchar *uri_str = gnome_vfs_uri_to_string (uri,
   171 			GNOME_VFS_URI_HIDE_USER_NAME |
   172 			GNOME_VFS_URI_HIDE_PASSWORD |
   173 			GNOME_VFS_URI_HIDE_HOST_NAME |
   174 			GNOME_VFS_URI_HIDE_HOST_PORT |
   175 			GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD);
   176 
   177 	file = gnome_vfs_unescape_string (uri_str, "");
   178 	c = file;
   179 	entry = g_string_new ("");
   180 	c = c + 1;
   181 	do {
   182 		if ((*c == '\"') || (*c == '\'')) {
   183 			open = !open;
   184 		}
   185 
   186 		if (((*c == '?') || (c[1] == '\0')) && !open) {
   187 			if (*c != '?')
   188 				g_string_append_c (entry, *c);
   189 
   190 			args = g_slist_append (args, g_strdup (entry->str));
   191 			entry = g_string_assign (entry, "");
   192 		} else {
   193 			g_string_append_c (entry, *c);
   194 		}
   195 		c = c + 1;
   196 	} while (*c != '\0');
   197 
   198 	g_string_free (entry, TRUE);
   199 
   200     for (walk = args; walk != NULL; walk = walk->next)
   201     {
   202 		gchar *arg = (gchar *) walk->data;
   203         prop = g_strsplit(arg, "=", 2);
   204 		g_debug ("arg = %s", arg);
   205 
   206         if (g_strv_length (prop) == 2) {
   207 			if (strcmp (prop[0], "file") == 0) {
   208 				info->file_name = g_strdup (prop[1]);
   209 			} else if (strcmp (prop[0], "mux") == 0) {
   210                 info->mux = g_strdup (prop[1]);
   211             } else if (strcmp (prop[0], "vcodec") == 0) {
   212                 info->vcodec = g_strdup (prop[1]);
   213             } else if (strcmp (prop[0], "vbitrate") == 0) {
   214                 info->vbitrate = atoi (prop[1]);
   215             } else if (strcmp (prop[0], "fps") == 0) {
   216                 info->fps = g_strtod (prop[1], NULL);
   217             } else if (strcmp (prop[0], "acodec") == 0) {
   218                 info->acodec = g_strdup (prop[1]);
   219             } else if (strcmp (prop[0], "abitrate") == 0) {
   220                 info->abitrate = atoi (prop[1]);
   221             } else if (strcmp (prop[0], "width") == 0) {
   222                 info->width = atoi (prop[1]);
   223             } else if (strcmp (prop[0], "height") == 0) {
   224                 info->height = atoi (prop[1]);
   225             } else if (strcmp (prop[0], "opt") == 0) {
   226                 g_debug("DENTRO DE OPT: %s", arg);
   227                 //char* v = _parse_opt(walk);
   228                 info->opt = g_strdup (arg);
   229             }
   230         }
   231         g_strfreev (prop);
   232 		g_free (arg);
   233     }
   234     g_free (file);
   235 	g_slist_free (args);
   236     return info;
   237 }
   238 
   239 static GnomeVFSResult
   240 do_open (GnomeVFSMethod        *method,
   241 	 GnomeVFSMethodHandle **method_handle,
   242 	 GnomeVFSURI           *uri,
   243 	 GnomeVFSOpenMode       mode,
   244 	 GnomeVFSContext       *context)
   245 {
   246     gmsHandle *handle = gmsHandle_new(uri);
   247     UriArgs *args;
   248 
   249     args = _uri_parse_args (uri);
   250 
   251     if (!gmyth_stream_client_connect (handle->stream,
   252                                       gnome_vfs_uri_get_host_name  (uri),
   253                                       gnome_vfs_uri_get_host_port  (uri))) {
   254 
   255         return GNOME_VFS_ERROR_INVALID_FILENAME;
   256     }
   257 
   258     args = _uri_parse_args (uri);
   259 
   260     gint ret = gmyth_stream_client_open_stream (handle->stream,
   261                                                 args->file_name,
   262                                                 args->mux,
   263                                                 args->vcodec,
   264                                                 args->vbitrate,
   265                                                 args->fps,
   266                                                 args->acodec,
   267                                                 args->abitrate,
   268                                                 args->width,
   269                                                 args->height,
   270                                                 args->opt);
   271 
   272     g_free (args);
   273 
   274     if (ret == -1) {
   275         gmyth_stream_client_disconnect (handle->stream);
   276         return GNOME_VFS_ERROR_INVALID_FILENAME;
   277     }
   278 
   279     handle->fd = gmyth_stream_client_play_stream (handle->stream);
   280 
   281     if (handle->fd == -1) {
   282         gmyth_stream_client_disconnect (handle->stream);
   283         return GNOME_VFS_ERROR_INVALID_FILENAME;
   284     }
   285 
   286     *method_handle = (GnomeVFSMethodHandle *) handle;
   287     return GNOME_VFS_OK;
   288 }
   289 
   290 static GnomeVFSResult
   291 do_read (GnomeVFSMethod       *method,
   292 	 GnomeVFSMethodHandle *method_handle,
   293 	 gpointer              buffer,
   294 	 GnomeVFSFileSize      bytes,
   295 	 GnomeVFSFileSize     *bytes_read,
   296 	 GnomeVFSContext      *context)
   297 {
   298 
   299     gint64 total_read = 0;
   300     gmsHandle *handle = (gmsHandle *) method_handle;
   301 
   302     total_read = recv(handle->fd, buffer, BUFFER_SIZE, 0);
   303     *bytes_read = (GnomeVFSFileSize) total_read;
   304 
   305     if (total_read < 0) return GNOME_VFS_ERROR_INTERNAL;
   306     else return GNOME_VFS_OK;
   307 
   308 }
   309 
   310 static GnomeVFSResult
   311 do_close (GnomeVFSMethod * method,
   312           GnomeVFSMethodHandle * method_handle,
   313           GnomeVFSContext * context)
   314 {
   315     gmsHandle *handle = (gmsHandle *) method_handle;
   316 
   317     gmyth_stream_client_close_stream (handle->stream);
   318     gmyth_stream_client_disconnect (handle->stream);
   319 
   320     g_free(handle);
   321     return GNOME_VFS_OK;
   322 }
   323 
   324 
   325 static GnomeVFSResult
   326 do_get_file_info (GnomeVFSMethod * method,
   327 		  GnomeVFSURI * uri,
   328 		  GnomeVFSFileInfo * file_info,
   329 		  GnomeVFSFileInfoOptions options,
   330 		  GnomeVFSContext * context)
   331 {
   332     file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
   333         GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
   334 
   335     file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
   336 
   337     file_info->permissions = GNOME_VFS_PERM_USER_READ |
   338         GNOME_VFS_PERM_OTHER_READ |
   339         GNOME_VFS_PERM_GROUP_READ;
   340 
   341     return GNOME_VFS_OK;
   342 }
   343 
   344 
   345 static GnomeVFSResult
   346 do_get_file_info_from_handle (GnomeVFSMethod 		*method,
   347                               GnomeVFSMethodHandle 	*method_handle,
   348                               GnomeVFSFileInfo 		*file_info,
   349                               GnomeVFSFileInfoOptions    options,
   350                               GnomeVFSContext 		*context)
   351 {
   352     file_info->valid_fields = GNOME_VFS_FILE_INFO_FIELDS_TYPE |
   353         GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
   354 
   355     file_info->type = GNOME_VFS_FILE_TYPE_SOCKET;
   356 
   357     file_info->permissions = GNOME_VFS_PERM_USER_READ |
   358         GNOME_VFS_PERM_OTHER_READ |
   359         GNOME_VFS_PERM_GROUP_READ;
   360 
   361     return GNOME_VFS_OK;
   362 }
   363 
   364 
   365 static gboolean
   366 do_is_local (GnomeVFSMethod * method, const GnomeVFSURI * uri)
   367 {
   368     return FALSE;
   369 }