+
+VlcPlugin::~VlcPlugin()
+{
+ delete psz_baseURL;
+ delete psz_target;
+ if( libvlc_log )
+ libvlc_log_close(libvlc_log, NULL);
+ if( libvlc_instance )
+ libvlc_destroy(libvlc_instance, NULL );
+}
+
+/*****************************************************************************
+ * VlcPlugin methods
+ *****************************************************************************/
+
+char *VlcPlugin::getAbsoluteURL(const char *url)
+{
+ if( NULL != url )
+ {
+ // check whether URL is already absolute
+ const char *end=strchr(url, ':');
+ if( (NULL != end) && (end != url) )
+ {
+ // validate protocol header
+ const char *start = url;
+ char c = *start;
+ if( isalpha(c) )
+ {
+ ++start;
+ while( start != end )
+ {
+ c = *start;
+ if( ! (isalnum(c)
+ || ('-' == c)
+ || ('+' == c)
+ || ('.' == c)
+ || ('/' == c)) ) /* VLC uses / to allow user to specify a demuxer */
+ // not valid protocol header, assume relative URL
+ goto relativeurl;
+ ++start;
+ }
+ /* we have a protocol header, therefore URL is absolute */
+ return strdup(url);
+ }
+ // not a valid protocol header, assume relative URL
+ }
+
+relativeurl:
+
+ if( psz_baseURL )
+ {
+ size_t baseLen = strlen(psz_baseURL);
+ char *href = new char[baseLen+strlen(url)+1];
+ if( href )
+ {
+ /* prepend base URL */
+ strcpy(href, psz_baseURL);
+
+ /*
+ ** relative url could be empty,
+ ** in which case return base URL
+ */
+ if( '\0' == *url )
+ return href;
+
+ /*
+ ** locate pathname part of base URL
+ */
+
+ /* skip over protocol part */
+ char *pathstart = strchr(href, ':');
+ char *pathend;
+ if( pathstart )
+ {
+ if( '/' == *(++pathstart) )
+ {
+ if( '/' == *(++pathstart) )
+ {
+ ++pathstart;
+ }
+ }
+ /* skip over host part */
+ pathstart = strchr(pathstart, '/');
+ pathend = href+baseLen;
+ if( ! pathstart )
+ {
+ // no path, add a / past end of url (over '\0')
+ pathstart = pathend;
+ *pathstart = '/';
+ }
+ }
+ else
+ {
+ /* baseURL is just a UNIX path */
+ if( '/' != *href )
+ {
+ /* baseURL is not an absolute path */
+ return NULL;
+ }
+ pathstart = href;
+ pathend = href+baseLen;
+ }
+
+ /* relative URL made of an absolute path ? */
+ if( '/' == *url )
+ {
+ /* replace path completely */
+ strcpy(pathstart, url);
+ return href;
+ }
+
+ /* find last path component and replace it */
+ while( '/' != *pathend)
+ --pathend;
+
+ /*
+ ** if relative url path starts with one or more '../',
+ ** factor them out of href so that we return a
+ ** normalized URL
+ */
+ while( pathend != pathstart )
+ {
+ const char *p = url;
+ if( '.' != *p )
+ break;
+ ++p;
+ if( '\0' == *p )
+ {
+ /* relative url is just '.' */
+ url = p;
+ break;
+ }
+ if( '/' == *p )
+ {
+ /* relative url starts with './' */
+ url = ++p;
+ continue;
+ }
+ if( '.' != *p )
+ break;
+ ++p;
+ if( '\0' == *p )
+ {
+ /* relative url is '..' */
+ }
+ else
+ {
+ if( '/' != *p )
+ break;
+ /* relative url starts with '../' */
+ ++p;
+ }
+ url = p;
+ do
+ {
+ --pathend;
+ }
+ while( '/' != *pathend );
+ }
+ /* skip over '/' separator */
+ ++pathend;
+ /* concatenate remaining base URL and relative URL */
+ strcpy(pathend, url);
+ }
+ return href;
+ }
+ }
+ return NULL;