gstreamer_core/gst/gsturi.c
changeset 16 8e837d1bf446
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
15:4b0c6ed43234 16:8e837d1bf446
    62 
    62 
    63 
    63 
    64 GType
    64 GType
    65 gst_uri_handler_get_type (void)
    65 gst_uri_handler_get_type (void)
    66 {
    66 {
    67   static GType urihandler_type = 0;
    67   static volatile gsize urihandler_type = 0;
    68 
    68 
    69   if (G_UNLIKELY (urihandler_type == 0)) {
    69   if (g_once_init_enter (&urihandler_type)) {
       
    70     GType _type;
    70     static const GTypeInfo urihandler_info = {
    71     static const GTypeInfo urihandler_info = {
    71       sizeof (GstURIHandlerInterface),
    72       sizeof (GstURIHandlerInterface),
    72       gst_uri_handler_base_init,
    73       gst_uri_handler_base_init,
    73       NULL,
    74       NULL,
    74       NULL,
    75       NULL,
    78       0,
    79       0,
    79       NULL,
    80       NULL,
    80       NULL
    81       NULL
    81     };
    82     };
    82 
    83 
    83     urihandler_type = g_type_register_static (G_TYPE_INTERFACE,
    84     _type = g_type_register_static (G_TYPE_INTERFACE,
    84         "GstURIHandler", &urihandler_info, 0);
    85         "GstURIHandler", &urihandler_info, 0);
    85 
    86 
    86     GST_DEBUG_CATEGORY_INIT (gst_uri_handler_debug, "GST_URI", GST_DEBUG_BOLD,
    87     GST_DEBUG_CATEGORY_INIT (gst_uri_handler_debug, "GST_URI", GST_DEBUG_BOLD,
    87         "handling of URIs");
    88         "handling of URIs");
       
    89     g_once_init_leave (&urihandler_type, _type);
    88   }
    90   }
    89   return urihandler_type;
    91   return urihandler_type;
    90 }
    92 }
       
    93 
    91 static void
    94 static void
    92 gst_uri_handler_base_init (gpointer g_class)
    95 gst_uri_handler_base_init (gpointer g_class)
    93 {
    96 {
    94   static gboolean initialized = FALSE;
    97   static gboolean initialized = FALSE;
    95 
    98 
   237   first_digit = hex_to_int (*scanner++);
   240   first_digit = hex_to_int (*scanner++);
   238   if (first_digit < 0) {
   241   if (first_digit < 0) {
   239     return -1;
   242     return -1;
   240   }
   243   }
   241 
   244 
   242   second_digit = hex_to_int (*scanner++);
   245   second_digit = hex_to_int (*scanner);
   243   if (second_digit < 0) {
   246   if (second_digit < 0) {
   244     return -1;
   247     return -1;
   245   }
   248   }
   246 
   249 
   247   return (first_digit << 4) | second_digit;
   250   return (first_digit << 4) | second_digit;
   307   g_assert (uri != NULL);
   310   g_assert (uri != NULL);
   308   g_assert (endptr != NULL);
   311   g_assert (endptr != NULL);
   309 
   312 
   310   if (g_ascii_isalpha (*check)) {
   313   if (g_ascii_isalpha (*check)) {
   311     check++;
   314     check++;
   312     while (g_ascii_isalnum (*check))
   315     while (g_ascii_isalnum (*check) || *check == '+'
       
   316         || *check == '-' || *check == '.')
   313       check++;
   317       check++;
   314   }
   318   }
   315 
   319 
   316   *endptr = check;
   320   *endptr = check;
   317 }
   321 }
   319 /**
   323 /**
   320  * gst_uri_protocol_is_valid:
   324  * gst_uri_protocol_is_valid:
   321  * @protocol: A string
   325  * @protocol: A string
   322  *
   326  *
   323  * Tests if the given string is a valid protocol identifier. Protocols
   327  * Tests if the given string is a valid protocol identifier. Protocols
   324  * must consist of alphanumeric characters and not start with a number.
   328  * must consist of alphanumeric characters, '+', '-' and '.' and must
       
   329  * start with a alphabetic character. See RFC 3986 Section 3.1.
   325  *
   330  *
   326  * Returns: TRUE if the string is a valid protocol identifier, FALSE otherwise.
   331  * Returns: TRUE if the string is a valid protocol identifier, FALSE otherwise.
   327  */
   332  */
   328 #ifdef __SYMBIAN32__
   333 #ifdef __SYMBIAN32__
   329 EXPORT_C
   334 EXPORT_C
   344 /**
   349 /**
   345  * gst_uri_is_valid:
   350  * gst_uri_is_valid:
   346  * @uri: A URI string
   351  * @uri: A URI string
   347  *
   352  *
   348  * Tests if the given string is a valid URI identifier. URIs start with a valid
   353  * Tests if the given string is a valid URI identifier. URIs start with a valid
   349  * protocol followed by "://" and maybe a string identifying the location.
   354  * scheme followed by ":" and maybe a string identifying the location.
   350  *
   355  *
   351  * Returns: TRUE if the string is a valid URI
   356  * Returns: TRUE if the string is a valid URI
   352  */
   357  */
   353 #ifdef __SYMBIAN32__
   358 #ifdef __SYMBIAN32__
   354 EXPORT_C
   359 EXPORT_C
   361 
   366 
   362   g_return_val_if_fail (uri != NULL, FALSE);
   367   g_return_val_if_fail (uri != NULL, FALSE);
   363 
   368 
   364   gst_uri_protocol_check_internal (uri, &endptr);
   369   gst_uri_protocol_check_internal (uri, &endptr);
   365 
   370 
   366   return (*endptr == ':' && *(endptr + 1) == '/' && *(endptr + 2) == '/');
   371   return *endptr == ':';
   367 }
   372 }
   368 
   373 
   369 /**
   374 /**
   370  * gst_uri_get_protocol:
   375  * gst_uri_get_protocol:
   371  * @uri: A URI string
   376  * @uri: A URI string
   385   gchar *colon;
   390   gchar *colon;
   386 
   391 
   387   g_return_val_if_fail (uri != NULL, NULL);
   392   g_return_val_if_fail (uri != NULL, NULL);
   388   g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
   393   g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
   389 
   394 
   390   colon = strstr (uri, "://");
   395   colon = strstr (uri, ":");
   391 
   396 
   392   return g_strdown (g_strndup (uri, colon - uri));
   397   return g_ascii_strdown (uri, colon - uri);
   393 }
   398 }
   394 
   399 
   395 /**
   400 /**
   396  * gst_uri_has_protocol:
   401  * gst_uri_has_protocol:
   397  * @uri: an URI string
   402  * @uri: an URI string
   414 
   419 
   415   g_return_val_if_fail (uri != NULL, FALSE);
   420   g_return_val_if_fail (uri != NULL, FALSE);
   416   g_return_val_if_fail (protocol != NULL, FALSE);
   421   g_return_val_if_fail (protocol != NULL, FALSE);
   417   g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
   422   g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
   418 
   423 
   419   colon = strstr (uri, "://");
   424   colon = strstr (uri, ":");
   420 
   425 
   421   if (colon == NULL)
   426   if (colon == NULL)
   422     return FALSE;
   427     return FALSE;
   423 
   428 
   424   return (strncmp (uri, protocol, (gsize) (colon - uri)) == 0);
   429   return (g_ascii_strncasecmp (uri, protocol, (gsize) (colon - uri)) == 0);
   425 }
   430 }
   426 
   431 
   427 /**
   432 /**
   428  * gst_uri_get_location:
   433  * gst_uri_get_location:
   429  * @uri: A URI string
   434  * @uri: A URI string
   448 
   453 
   449   g_return_val_if_fail (uri != NULL, NULL);
   454   g_return_val_if_fail (uri != NULL, NULL);
   450   g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
   455   g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
   451 
   456 
   452   colon = strstr (uri, "://");
   457   colon = strstr (uri, "://");
       
   458   if (!colon)
       
   459     return NULL;
   453 
   460 
   454   unescaped = unescape_string (colon + 3, "/");
   461   unescaped = unescape_string (colon + 3, "/");
   455 
   462 
   456   /* On Windows an URI might look like file:///c:/foo/bar.txt or
   463   /* On Windows an URI might look like file:///c:/foo/bar.txt or
   457    * file:///c|/foo/bar.txt (some Netscape versions) and we want to
   464    * file:///c|/foo/bar.txt (some Netscape versions) and we want to
   466     g_memmove (unescaped, unescaped + 1, strlen (unescaped + 1) + 1);
   473     g_memmove (unescaped, unescaped + 1, strlen (unescaped + 1) + 1);
   467   }
   474   }
   468 #endif
   475 #endif
   469 
   476 
   470   GST_LOG ("extracted location '%s' from URI '%s'", GST_STR_NULL (unescaped),
   477   GST_LOG ("extracted location '%s' from URI '%s'", GST_STR_NULL (unescaped),
   471       uri);;
   478       uri);
   472   return unescaped;
   479   return unescaped;
   473 }
   480 }
   474 
   481 
   475 /**
   482 /**
   476  * gst_uri_construct:
   483  * gst_uri_construct:
   487 #endif
   494 #endif
   488 
   495 
   489 gchar *
   496 gchar *
   490 gst_uri_construct (const gchar * protocol, const gchar * location)
   497 gst_uri_construct (const gchar * protocol, const gchar * location)
   491 {
   498 {
   492   char *escaped;
   499   char *escaped, *proto_lowercase;
   493   char *retval;
   500   char *retval;
   494 
   501 
   495   g_return_val_if_fail (gst_uri_protocol_is_valid (protocol), NULL);
   502   g_return_val_if_fail (gst_uri_protocol_is_valid (protocol), NULL);
   496   g_return_val_if_fail (location != NULL, NULL);
   503   g_return_val_if_fail (location != NULL, NULL);
   497 
   504 
       
   505   proto_lowercase = g_ascii_strdown (protocol, -1);
   498   escaped = escape_string (location);
   506   escaped = escape_string (location);
   499   retval = g_strdup_printf ("%s://%s", protocol, escaped);
   507   retval = g_strdup_printf ("%s://%s", proto_lowercase, escaped);
   500   g_free (escaped);
   508   g_free (escaped);
       
   509   g_free (proto_lowercase);
   501 
   510 
   502   return retval;
   511   return retval;
   503 }
   512 }
   504 
   513 
   505 typedef struct
   514 typedef struct
   676 
   685 
   677   g_return_val_if_fail (GST_IS_URI_HANDLER (handler), GST_URI_UNKNOWN);
   686   g_return_val_if_fail (GST_IS_URI_HANDLER (handler), GST_URI_UNKNOWN);
   678 
   687 
   679   iface = GST_URI_HANDLER_GET_INTERFACE (handler);
   688   iface = GST_URI_HANDLER_GET_INTERFACE (handler);
   680   g_return_val_if_fail (iface != NULL, GST_URI_UNKNOWN);
   689   g_return_val_if_fail (iface != NULL, GST_URI_UNKNOWN);
   681   g_return_val_if_fail (iface->get_type != NULL, GST_URI_UNKNOWN);
   690   g_return_val_if_fail (iface->get_type != NULL
   682   ret = iface->get_type ();
   691       || iface->get_type_full != NULL, GST_URI_UNKNOWN);
       
   692 
       
   693   if (iface->get_type != NULL)
       
   694     ret = iface->get_type ();
       
   695   else
       
   696     ret = iface->get_type_full (G_OBJECT_TYPE (handler));
   683   g_return_val_if_fail (GST_URI_TYPE_IS_VALID (ret), GST_URI_UNKNOWN);
   697   g_return_val_if_fail (GST_URI_TYPE_IS_VALID (ret), GST_URI_UNKNOWN);
   684 
   698 
   685   return ret;
   699   return ret;
   686 }
   700 }
   687 
   701 
   770 
   784 
   771 gboolean
   785 gboolean
   772 gst_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri)
   786 gst_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri)
   773 {
   787 {
   774   GstURIHandlerInterface *iface;
   788   GstURIHandlerInterface *iface;
       
   789   gboolean ret;
       
   790   gchar *new_uri, *protocol, *location, *colon;
   775 
   791 
   776   g_return_val_if_fail (GST_IS_URI_HANDLER (handler), FALSE);
   792   g_return_val_if_fail (GST_IS_URI_HANDLER (handler), FALSE);
   777   g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
   793   g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
   778 
   794 
   779   iface = GST_URI_HANDLER_GET_INTERFACE (handler);
   795   iface = GST_URI_HANDLER_GET_INTERFACE (handler);
   780   g_return_val_if_fail (iface != NULL, FALSE);
   796   g_return_val_if_fail (iface != NULL, FALSE);
   781   g_return_val_if_fail (iface->set_uri != NULL, FALSE);
   797   g_return_val_if_fail (iface->set_uri != NULL, FALSE);
   782   return iface->set_uri (handler, uri);
   798 
       
   799   protocol = gst_uri_get_protocol (uri);
       
   800 
       
   801   colon = strstr (uri, ":");
       
   802   location = g_strdup (colon);
       
   803 
       
   804   new_uri = g_strdup_printf ("%s%s", protocol, location);
       
   805 
       
   806   ret = iface->set_uri (handler, uri);
       
   807 
       
   808   g_free (new_uri);
       
   809   g_free (location);
       
   810   g_free (protocol);
       
   811 
       
   812   return ret;
   783 }
   813 }
   784 
   814 
   785 /**
   815 /**
   786  * gst_uri_handler_new_uri:
   816  * gst_uri_handler_new_uri:
   787  * @handler: A #GstURIHandler
   817  * @handler: A #GstURIHandler