xurl.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * xurl.c: URL manipulation functions
  3.  *****************************************************************************
  4.  * Copyright (C) 2003-2004 Commonwealth Scientific and Industrial Research
  5.  *                         Organisation (CSIRO) Australia
  6.  * Copyright (C) 2004-2008 the VideoLAN team
  7.  *
  8.  * $Id: ec4ad75da6bb295d50af821d7dabd4f19cc32e3e $
  9.  *
  10.  * Authors: Andre Pang <Andre.Pang@csiro.au>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <stdio.h>
  30. #include "xurl.h"
  31. static char *streallocat( char *psz_string, const char *psz_to_append );
  32. char        *XURL_FindQuery             ( char *psz_url );
  33. static char *XURL_FindHostname          ( char *psz_url );
  34. static char *XURL_FindPath              ( char *psz_url );
  35. static char *XURL_FindFragment          ( char *psz_url );
  36. char *XURL_Join( char *psz_url1, char *psz_url2 )
  37. {
  38.     if( XURL_IsAbsolute( psz_url1 ) )
  39.         return XURL_Concat( psz_url1, psz_url2 );
  40.     else
  41.         return XURL_Concat( psz_url2, psz_url1 );
  42. }
  43. /* TODO: replace XURL_Concat's rel/absolute calculation with the one
  44.  * specified by RFC2396, and also test it on their test suite :) */
  45. char *XURL_Concat( char *psz_url, char *psz_append )
  46. {
  47.     char *psz_return_value = NULL;
  48.     if( XURL_IsAbsolute( psz_append ) )
  49.         return strdup( psz_append );
  50.     if( XURL_IsAbsolute( psz_url ) )
  51.     {
  52.         if( XURL_HasAbsolutePath( psz_append ) )
  53.         {
  54.             char *psz_concat_url;
  55.             psz_concat_url = XURL_GetSchemeAndHostname( psz_url );
  56.             psz_concat_url = streallocat( psz_concat_url, psz_append );
  57. #ifdef XURL_DEBUG
  58.             fprintf( stderr, "XURL_Concat: concat is "%s"n",
  59.                      psz_concat_url );
  60. #endif
  61.             psz_return_value = psz_concat_url;
  62.         }
  63.         else
  64.         {
  65.             /* psz_append is a relative URL */
  66.             char *psz_new_url;
  67.  
  68.             /* strip off last path component */
  69.             psz_new_url = XURL_GetHead( psz_url );
  70.             psz_new_url = streallocat( psz_new_url, psz_append );
  71.             psz_return_value = psz_new_url;
  72.         }
  73.     }
  74.     else
  75.     {
  76.         /* not an absolute URL */
  77.         if( XURL_HasAbsolutePath( psz_append ) == false )
  78.         {
  79.             char *psz_new_url = XURL_GetHead( psz_url );
  80.             psz_new_url = streallocat( psz_new_url, psz_append );
  81.             psz_return_value = psz_new_url;
  82.         }
  83.         else
  84.         {
  85.             /* URL to append has an absolute path -- just use that instead */
  86.             psz_return_value = strdup( psz_append );
  87.         }
  88.     }
  89.     return psz_return_value;
  90. }
  91. bool XURL_IsAbsolute( char *psz_url )
  92. {
  93.     if( XURL_FindHostname( psz_url ) == NULL )
  94.     {
  95. #ifdef XURL_DEBUG
  96.         fprintf( stderr, "XURL_IsAbsolute(%s) returning falsen", psz_url );
  97. #endif
  98.         return false;
  99.     }
  100.     else
  101.     {
  102. #ifdef XURL_DEBUG
  103.         fprintf( stderr, "XURL_IsAbsolute(%s) returning truen", psz_url );
  104. #endif
  105.         return true;
  106.     }
  107. }
  108. bool XURL_HasFragment( char *psz_url )
  109. {
  110.     if( XURL_FindFragment( psz_url ) == NULL )
  111.         return false;
  112.     else
  113.         return true;
  114. }
  115. char *XURL_FindHostname( char *psz_url )
  116. {
  117.     char *psz_return_value = NULL;
  118.     char *psz_scheme_separator = strstr( psz_url, "://" );
  119.     if( psz_scheme_separator != NULL)
  120.     {
  121.         char *psz_hostname = psz_scheme_separator + strlen( "://" );
  122.         if( *psz_hostname != '')
  123.             psz_return_value = psz_hostname;
  124. #ifdef XURL_DEBUG
  125.         fprintf( stderr, "XURL_FindHostname(%s): returning "%s"n",
  126.                  psz_url, psz_return_value );
  127. #endif
  128.     }
  129.     return psz_return_value;
  130. }
  131. bool XURL_HasAbsolutePath( char *psz_url )
  132. {
  133. #ifdef XURL_WIN32_PATHING
  134.     if( psz_url[0] == '/' || psz_url[0] == '\' )
  135. #else
  136.     if( psz_url[0] == '/' )
  137. #endif
  138.         return true;
  139.     else
  140.         return false;
  141. }
  142. char *XURL_GetHostname( char *psz_url )
  143. {
  144.     char *psz_return_value = NULL;
  145.     char *psz_hostname = XURL_FindHostname( psz_url );
  146.     if( psz_hostname != NULL )
  147.     {
  148.         char *psz_new_hostname;
  149.         size_t i_hostname_length;
  150.         char *psz_one_past_end_of_hostname = strchr( psz_hostname, '/' );
  151.         if( psz_one_past_end_of_hostname != NULL)
  152.         {
  153.             /* Found a '/' after the hostname, so copy characters between
  154.              * the hostname and the '/' to a new string */
  155.             i_hostname_length = psz_one_past_end_of_hostname -
  156.                 psz_hostname;
  157.         }
  158.         else
  159.         {
  160.             /* Didn't find a '/', so copy from the start of the hostname
  161.              * until the end of the string */
  162.             i_hostname_length = strlen( psz_url ) - ( psz_hostname - psz_url );
  163.         }
  164.         /* Copy hostname to a new string */
  165.         psz_new_hostname = malloc( i_hostname_length );
  166.         if( psz_new_hostname == NULL )
  167.             return NULL;
  168.         strncpy( psz_new_hostname, psz_hostname, i_hostname_length );
  169. #ifdef XURL_DEBUG
  170.         fprintf (stderr, "XURL_GetHostname: psz_new_hostname is "%s"n",
  171.                  psz_new_hostname );
  172. #endif
  173.         psz_return_value = psz_new_hostname;
  174.     }
  175.     else
  176.     {
  177.         /* Didn't find a hostname */
  178.         return NULL;
  179.     }
  180.     return psz_return_value;
  181. }
  182. char *XURL_GetSchemeAndHostname( char *psz_url )
  183. {
  184.     char *psz_scheme = NULL,
  185.          *psz_hostname = NULL,
  186.          *psz_scheme_and_hostname = NULL;
  187.     psz_scheme = XURL_GetScheme( psz_url );
  188.     psz_hostname = XURL_GetHostname( psz_url );
  189.     if( psz_hostname && psz_scheme )
  190.     {
  191.         if( asprintf( &psz_scheme_and_hostname, "%s://%s", psz_scheme, psz_hostname ) == -1)
  192.             psz_scheme_and_hostname = NULL;
  193.     }
  194.     free( psz_hostname );
  195.     free( psz_scheme );
  196.     return psz_scheme_and_hostname;
  197. }
  198. static char *XURL_FindFragment( char *psz_url )
  199. {
  200.     char *pc_hash = NULL;
  201.     char *pc_return_value = NULL;
  202.  
  203.     pc_hash = strchr( psz_url, '#' );
  204.     if( pc_hash != NULL )
  205.         pc_return_value = pc_hash;
  206.     return pc_return_value;
  207. }
  208. char *XURL_FindQuery( char *psz_url )
  209. {
  210.     char *pc_question_mark = NULL;
  211.     char *pc_return_value = NULL;
  212.  
  213.     pc_question_mark = strchr( psz_url, '?' );
  214.     if( pc_question_mark != NULL )
  215.         pc_return_value = pc_question_mark;
  216.     return pc_return_value;
  217. }
  218. char *XURL_GetScheme( char *psz_url )
  219. {
  220.     char *psz_colon;
  221.     size_t i_scheme_length;
  222.     char *new_scheme;
  223.     if( XURL_IsAbsolute( psz_url ) == false )
  224.         return strdup( "file" );
  225.     /* this strchr will always succeed since we have an absolute URL, and thus
  226.      * a scheme */
  227.     psz_colon = strchr( psz_url, ':' );
  228.     i_scheme_length = psz_colon - psz_url;
  229.     new_scheme = malloc( i_scheme_length );
  230.     if( new_scheme == NULL )
  231.         return NULL;
  232.     strncpy( new_scheme, psz_url, i_scheme_length );
  233.     return new_scheme;
  234. }
  235. bool XURL_IsFileURL( char *psz_url )
  236. {
  237.     bool b_return_value;
  238.     char *psz_scheme = XURL_GetScheme( psz_url );
  239.     if( strcasecmp( psz_scheme, "file" ) == 0 )
  240.         b_return_value = true;
  241.     else
  242.         b_return_value = false;
  243.     free( psz_scheme );
  244.     return b_return_value;
  245. }
  246. static char *XURL_FindPath( char *psz_url )
  247. {
  248.     if( XURL_IsAbsolute( psz_url ) )
  249.     {
  250.         char *psz_start_of_hostname = XURL_FindHostname( psz_url );
  251.         if( psz_start_of_hostname != NULL )
  252.             return strchr( psz_start_of_hostname, '/' );
  253.         else
  254.            return NULL;
  255.     }
  256.     else
  257.     {
  258.         if( XURL_HasAbsolutePath( psz_url ) == true )
  259.             return psz_url;
  260.         else
  261.             return strdup (".");
  262.     }
  263. }
  264. char *XURL_GetPath( char *psz_url )
  265. {
  266.     char *psz_return_value = NULL;
  267.     char *psz_path = NULL;
  268.     char *pc_question_mark = NULL;
  269.     char *pc_fragment = NULL;
  270.     psz_path = strdup( XURL_FindPath( psz_url ) );
  271. #ifdef XURL_DEBUG
  272.     fprintf( stderr, "XURL_GetPath: XURL_FindPath returning "%s"n",
  273.              psz_path );
  274. #endif
  275.     psz_return_value = psz_path;
  276.     pc_question_mark = XURL_FindQuery( psz_path );
  277.     if( pc_question_mark != NULL )
  278.     {
  279.         int i_path_length = pc_question_mark - psz_path;
  280.         *( psz_path + i_path_length ) = '';
  281.     }
  282.     pc_fragment = XURL_FindFragment( psz_path );
  283.     if( pc_fragment != NULL )
  284.     {
  285. #ifdef XURL_DEBUG
  286.         fprintf( stderr, "XURL_GetPath: XURL_FindFragment returned "%s"n",
  287.                  pc_fragment );
  288. #endif
  289.         int i_path_length = pc_fragment - psz_path;
  290.         *( psz_path + i_path_length ) = '';
  291.     }
  292. #ifdef XURL_DEBUG
  293.     fprintf( stderr, "XURL_GetPath returning "%s"n", psz_return_value );
  294. #endif
  295.     return psz_return_value;
  296. }
  297. char *XURL_GetHead( const char *psz_path )
  298. {
  299.     char *psz_path_head;
  300.     char *pc_last_slash;
  301.     /* kill everything up to the last / (including the /) */
  302. #ifdef XURL_WIN32_PATHING
  303.     /* Windows: Try looking for a  first; if we don't find one, look for / */
  304.     pc_last_slash = strrchr( psz_path, '\' );
  305.     if( pc_last_slash == NULL )
  306.         pc_last_slash = strrchr( psz_path, '/' );
  307. #else
  308.     pc_last_slash = strrchr( psz_path, '/' );
  309. #endif
  310.     if( pc_last_slash == NULL )
  311.     {
  312.         psz_path_head = strdup( psz_path );
  313.     }
  314.     else
  315.     {
  316.         size_t i_characters_until_last_slash;
  317.         i_characters_until_last_slash = pc_last_slash - psz_path;
  318.         psz_path_head = malloc( i_characters_until_last_slash + 1 );
  319.         strncpy( psz_path_head, psz_path, i_characters_until_last_slash + 1 );
  320.         /* terminate the resulting string with '' */
  321.         *(psz_path_head +
  322.                 i_characters_until_last_slash) = '';
  323.     }
  324.     /* append a trailing / */
  325.     streallocat( psz_path_head, "/" );
  326.     return psz_path_head;
  327. }
  328. char *XURL_GetWithoutFragment( char *psz_url )
  329. {
  330.     char *psz_return_value = NULL;
  331.     char *psz_fragment;
  332.     psz_fragment = XURL_FindFragment( psz_url );
  333.     if( psz_fragment == NULL )
  334.     {
  335.         psz_return_value = strdup( psz_url );
  336.     }
  337.     else
  338.     {
  339.         size_t i_pre_fragment_length;
  340.         char *psz_without_fragment;
  341.         i_pre_fragment_length = psz_fragment - psz_url;
  342.         psz_without_fragment = malloc( i_pre_fragment_length + 1 );
  343.         if( psz_without_fragment == NULL )
  344.         {
  345.             psz_return_value = NULL;
  346.         }
  347.         else
  348.         {
  349.             memcpy( psz_without_fragment, psz_url, i_pre_fragment_length );
  350.             *( psz_without_fragment + i_pre_fragment_length ) = '';
  351.             psz_return_value = psz_without_fragment;
  352.         }
  353.     }
  354.  
  355.     return psz_return_value;
  356. }
  357. static char *streallocat( char *psz_string, const char *psz_to_append )
  358. {
  359.     size_t i_new_string_length = strlen( psz_string ) +
  360.         strlen( psz_to_append ) + 1;
  361.     psz_string = (char *) realloc( psz_string, i_new_string_length );
  362.  
  363.     return strcat( psz_string, psz_to_append );
  364. }