[svn r362] Some fixes in the GIOWatcher clean-ups, and changed the API version number.
4 * @file gmyth/gmyth_uri.c
6 * @brief <p> GMythURI utils
7 * - Extracts and parses a URI char string, in according with the RFC 2396
8 * [http://www.ietf.org/rfc/rfc2396.txt]
10 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
11 * @author Rosfran Borges <rosfran.borges@indt.org.br>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "gmyth_uri.h"
40 #include "gmyth_debug.h"
42 static void gmyth_uri_class_init (GMythURIClass *klass);
43 static void gmyth_uri_init (GMythURI *object);
45 static void gmyth_uri_dispose (GObject *object);
46 static void gmyth_uri_finalize (GObject *object);
48 G_DEFINE_TYPE(GMythURI, gmyth_uri, G_TYPE_OBJECT)
51 gmyth_uri_parser_setup_and_new( GMythURI *uri, const gchar *value );
54 gmyth_uri_class_init (GMythURIClass *klass)
56 GObjectClass *gobject_class;
58 gobject_class = (GObjectClass *) klass;
60 gobject_class->dispose = gmyth_uri_dispose;
61 gobject_class->finalize = gmyth_uri_finalize;
65 gmyth_uri_init (GMythURI *gmyth_uri)
70 gmyth_uri_dispose (GObject *object)
72 GMythURI *gmyth_uri = GMYTH_URI(object);
74 if ( gmyth_uri->host != NULL ) {
75 g_string_free( gmyth_uri->host, TRUE );
76 gmyth_uri->host = NULL;
79 if ( gmyth_uri->protocol != NULL ) {
80 g_string_free( gmyth_uri->protocol, TRUE );
81 gmyth_uri->protocol = NULL;
84 if ( gmyth_uri->path != NULL ) {
85 g_string_free( gmyth_uri->path, TRUE );
86 gmyth_uri->path = NULL;
89 if ( gmyth_uri->fragment != NULL ) {
90 g_string_free( gmyth_uri->fragment, TRUE );
91 gmyth_uri->fragment = NULL;
94 if ( gmyth_uri->user != NULL ) {
95 g_string_free( gmyth_uri->user, TRUE );
96 gmyth_uri->user = NULL;
99 if ( gmyth_uri->password != NULL ) {
100 g_string_free( gmyth_uri->password, TRUE );
101 gmyth_uri->password = NULL;
104 if ( gmyth_uri->query != NULL ) {
105 g_string_free( gmyth_uri->query, TRUE );
106 gmyth_uri->query = NULL;
109 G_OBJECT_CLASS (gmyth_uri_parent_class)->dispose (object);
113 gmyth_uri_finalize (GObject *object)
115 //GMythURI *gmyth_uri = GMYTH_URI(object);
117 g_signal_handlers_destroy (object);
119 G_OBJECT_CLASS (gmyth_uri_parent_class)->finalize (object);
122 /** Creates a new instance of GMythURI.
124 * @return a new instance of GMythURI.
129 GMythURI *gmyth_uri = GMYTH_URI (g_object_new (GMYTH_URI_TYPE, NULL));
134 /** Creates a new instance of GMythURI.
136 * @return a new instance of GMythURI.
139 gmyth_uri_new_with_value (const gchar *value)
141 GMythURI *gmyth_uri = GMYTH_URI (g_object_new (GMYTH_URI_TYPE, NULL));
143 gmyth_uri_parser_setup_and_new (gmyth_uri, value);
149 gmyth_strstr (const gchar *haystack, const gchar *needle)
154 if (haystack == NULL || needle == NULL)
156 strPos = strstr(haystack, needle);
160 return (strPos - haystack);
165 gmyth_uri_isabsolute (const GMythURI *uri)
167 gboolean ret = FALSE;
169 g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->protocol != NULL, FALSE );
171 if ( gmyth_strstr( uri->uri->str, GMYTH_URI_PROTOCOL_DELIM ) == 0 || strlen(uri->protocol->str) > 0 )
178 gmyth_strrchr( const gchar *str, const gchar *chars, const gint nchars )
184 if ( str == NULL || chars == NULL )
187 strLen = strlen( str );
188 for ( i= (strLen-1); 0 <= i; i-- ) {
189 for ( j=0; j<nchars; j++ ) {
190 if ( str[i] == chars[j] )
200 gmyth_uri_print_field( const GString* field )
202 if ( field != NULL && field->str != NULL && strlen(field->str) > 0 )
209 gmyth_uri_parser_setup_and_new( GMythURI *uri, const gchar *value )
228 uriLen = strlen(value);
229 uri->uri = g_string_new( value );
234 protoIdx = gmyth_strstr (value, GMYTH_URI_PROTOCOL_DELIM);
236 uri->protocol = g_string_new_len (value, protoIdx);
237 currIdx += protoIdx + strlen( GMYTH_URI_PROTOCOL_DELIM );
240 /*** User (Password) ****/
241 atIdx = gmyth_strstr( value+currIdx, GMYTH_URI_USER_DELIM );
243 colonIdx = gmyth_strstr( value+currIdx, GMYTH_URI_COLON_DELIM );
245 if (0 < colonIdx && colonIdx < atIdx) {
246 uri->user = g_string_new_len (value+currIdx, colonIdx);
247 uri->password = g_string_new_len (value+currIdx+colonIdx+1, atIdx - (colonIdx+1));
250 uri->user = g_string_new_len (value+currIdx, atIdx - currIdx);
251 currIdx += atIdx + 1;
254 /*** Host (Port) ****/
255 shashIdx = gmyth_strstr( value+currIdx, GMYTH_URI_SLASH_DELIM );
257 uri->host = g_string_new_len (value+currIdx, shashIdx);
258 else if ( gmyth_uri_isabsolute(uri) == TRUE )
259 uri->host = g_string_new_len (value+currIdx, strlen (value) - currIdx);
261 host = gmyth_uri_get_host(uri);
262 colonIdx = gmyth_strrchr (host, GMYTH_URI_COLON_DELIM, 1);
263 eblacketIdx = gmyth_strrchr (host, GMYTH_URI_EBLACET_DELIM, 1);
264 if ( ( 0 < colonIdx ) && ( eblacketIdx < colonIdx ) ) {
265 GString *portStr = NULL;
266 GString *hostStr = g_string_new (host != NULL ? host : "");
268 hostLen = hostStr->len;
270 uri->host = g_string_erase (uri->host, 0, hostLen);
271 uri->host = g_string_insert_len (uri->host, 0, hostStr->str, colonIdx);
273 if (host[0] == '[' && host[hostLen-1] == ']')
274 uri->host = g_string_new_len (hostStr->str+1, colonIdx-2);
277 portStr = g_string_new_len (hostStr->str+colonIdx+1, hostLen-colonIdx-1);
278 uri->port = (gint)g_ascii_strtoull( portStr->str, NULL, 10 );
279 g_string_free (portStr, TRUE);
280 g_string_free (hostStr, TRUE);
283 const gchar* protocol = gmyth_uri_get_protocol(uri);
284 uri->port = GMYTH_URI_KNKOWN_PORT;
285 if ( strcmp(protocol, GMYTH_URI_PROTOCOL_HTTP) == 0 )
286 uri->port = GMYTH_URI_DEFAULT_HTTP_PORT;
287 if ( strcmp(protocol, GMYTH_URI_PROTOCOL_FTP) == 0 )
288 uri->port = GMYTH_URI_DEFAULT_FTP_PORT;
291 if (shashIdx > 0) currIdx += shashIdx;
296 if (gmyth_uri_isabsolute(uri) == FALSE)
301 /* Add slash delimiter at the beginning of the URL,
304 uri->path = g_string_new( GMYTH_URI_SLASH_DELIM );
306 uri->path = g_string_append( uri->path, value );
309 /* First set path simply to the rest of URI */
310 uri->path = g_string_new_len (value+currIdx, uriLen-currIdx );
313 gmyth_debug( "uri value: %s", value );
314 uri->query = g_string_new ( g_strstr_len( value, strlen(value), GMYTH_URI_E_DELIM ) );
316 eIdx = gmyth_strstr( value+currIdx, GMYTH_URI_E_DELIM );
319 uri->query = g_string_new ( g_strstr_len( value, strlen(value), GMYTH_URI_E_DELIM ) );
320 gmyth_debug( "query = %s", uri->query->str );
323 /**** Path (Query/Fragment) ****/
324 sharpIdx = gmyth_strstr(value+currIdx, GMYTH_URI_SHARP_DELIM);
326 uri->path = g_string_append_len( uri->path, value+currIdx, sharpIdx);
327 uri->fragment = g_string_new_len (value+currIdx+sharpIdx+1, uriLen-(currIdx+sharpIdx+1));
330 gmyth_debug( "[%s] GMythURI: host = %s, port = %d, path = %s, query = %s, fragment = %s, "\
331 "user = %s, password = %s.\n", __FUNCTION__, gmyth_uri_print_field( uri->host ), uri->port,
332 gmyth_uri_print_field( uri->path ), gmyth_uri_print_field( uri->query ), gmyth_uri_print_field( uri->fragment ),
333 gmyth_uri_print_field ( uri->user ), gmyth_uri_print_field( uri->password ) );
338 gmyth_uri_is_equals( GMythURI* uri1, GMythURI* uri2 )
340 return ( g_ascii_strcasecmp( gmyth_uri_get_host( uri1 ), gmyth_uri_get_host( uri2 ) ) == 0 &&
341 gmyth_uri_get_port( uri1 ) == gmyth_uri_get_port( uri2 ) );
345 gmyth_uri_is_livetv( GMythURI* uri )
347 gboolean ret = FALSE;
349 g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->uri->str != NULL, FALSE );
351 ret = ( g_strstr_len( uri->uri->str, strlen( uri->uri->str ), "/?" ) != NULL );
354 gmyth_debug( "This URI is a LiveTV recording..." );
361 gmyth_uri_get_channel_name( GMythURI* uri )
363 gchar* channel = NULL;
365 g_return_val_if_fail( uri != NULL && uri->uri != NULL && uri->uri->str != NULL, FALSE );
367 gchar *channel_query = g_strstr_len( gmyth_uri_get_query( uri ), strlen( gmyth_uri_get_query( uri ) ), "channel" );
369 if ( channel_query != NULL )
371 gmyth_debug( "TV Channel is in the following URI segment: %s", channel_query );
373 gchar **chan_key_value = g_strsplit( gmyth_uri_get_query( uri ), "=", 2 );
375 /* gmyth_debug( "Channel tuple is [ %s, %s ]", chan_key_value[0], chan_key_value[1] ); */
377 if ( chan_key_value[1] != NULL )
379 channel = g_strdup( chan_key_value[1] );
382 if ( chan_key_value != NULL )
383 g_strfreev( chan_key_value );
386 gmyth_debug( "Got channel decimal value from the URI: %s", channel );
393 gmyth_uri_get_channel_num( GMythURI* uri )
395 gchar *channel_name = gmyth_uri_get_channel_name( uri );
397 if ( channel_name != NULL )
399 return g_ascii_strtoull( channel_name, NULL, 10 );