# HG changeset patch # User chainsaw # Date 1153007729 25200 # Node ID 93c0af9bb52132bb1c123bbc1de020b15bf7bdde # Parent 0f6573c345008cd8dcd2cc1fe71cc191cceffcd8 [svn] Add more files from libmms CVS. diff -r 0f6573c34500 -r 93c0af9bb521 ChangeLog --- a/ChangeLog Sat Jul 15 16:52:52 2006 -0700 +++ b/ChangeLog Sat Jul 15 16:55:29 2006 -0700 @@ -1,3 +1,12 @@ +2006-07-15 23:52:52 +0000 William Pitcock + revision [1732] + - properly hook up mms + + + Changes: Modified: + +2 -2 trunk/Plugins/Input/wma/libffwma/file.c + + 2006-07-15 23:47:58 +0000 William Pitcock revision [1730] - bump to version 1.1.1 diff -r 0f6573c34500 -r 93c0af9bb521 Plugins/Input/wma/libffwma/asfheader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/wma/libffwma/asfheader.h Sat Jul 15 16:55:29 2006 -0700 @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2000-2003 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: asfheader.h,v 1.2 2005/12/12 09:24:19 theuraeus Exp $ + * + * demultiplexer for asf streams + * + * based on ffmpeg's + * ASF compatible encoder and decoder. + * Copyright (c) 2000, 2001 Gerard Lantau. + * + * GUID list from avifile + * some other ideas from MPlayer + */ + +#ifndef ASFHEADER_H +#define ASFHEADER_H + +/* + * define asf GUIDs (list from avifile) + */ +#define GUID_ERROR 0 + + /* base ASF objects */ +#define GUID_ASF_HEADER 1 +#define GUID_ASF_DATA 2 +#define GUID_ASF_SIMPLE_INDEX 3 +#define GUID_INDEX 4 +#define GUID_MEDIA_OBJECT_INDEX 5 +#define GUID_TIMECODE_INDEX 6 + + /* header ASF objects */ +#define GUID_ASF_FILE_PROPERTIES 7 +#define GUID_ASF_STREAM_PROPERTIES 8 +#define GUID_ASF_HEADER_EXTENSION 9 +#define GUID_ASF_CODEC_LIST 10 +#define GUID_ASF_SCRIPT_COMMAND 11 +#define GUID_ASF_MARKER 12 +#define GUID_ASF_BITRATE_MUTUAL_EXCLUSION 13 +#define GUID_ASF_ERROR_CORRECTION 14 +#define GUID_ASF_CONTENT_DESCRIPTION 15 +#define GUID_ASF_EXTENDED_CONTENT_DESCRIPTION 16 +#define GUID_ASF_STREAM_BITRATE_PROPERTIES 17 +#define GUID_ASF_EXTENDED_CONTENT_ENCRYPTION 18 +#define GUID_ASF_PADDING 19 + + /* stream properties object stream type */ +#define GUID_ASF_AUDIO_MEDIA 20 +#define GUID_ASF_VIDEO_MEDIA 21 +#define GUID_ASF_COMMAND_MEDIA 22 +#define GUID_ASF_JFIF_MEDIA 23 +#define GUID_ASF_DEGRADABLE_JPEG_MEDIA 24 +#define GUID_ASF_FILE_TRANSFER_MEDIA 25 +#define GUID_ASF_BINARY_MEDIA 26 + + /* stream properties object error correction type */ +#define GUID_ASF_NO_ERROR_CORRECTION 27 +#define GUID_ASF_AUDIO_SPREAD 28 + + /* mutual exclusion object exlusion type */ +#define GUID_ASF_MUTEX_BITRATE 29 +#define GUID_ASF_MUTEX_UKNOWN 30 + + /* header extension */ +#define GUID_ASF_RESERVED_1 31 + + /* script command */ +#define GUID_ASF_RESERVED_SCRIPT_COMMNAND 32 + + /* marker object */ +#define GUID_ASF_RESERVED_MARKER 33 + + /* various */ +/* +#define GUID_ASF_HEAD2 27 +*/ +#define GUID_ASF_AUDIO_CONCEAL_NONE 34 +#define GUID_ASF_CODEC_COMMENT1_HEADER 35 +#define GUID_ASF_2_0_HEADER 36 + +#define GUID_END 37 + + +/* asf stream types */ +#define ASF_STREAM_TYPE_UNKNOWN 0 +#define ASF_STREAM_TYPE_AUDIO 1 +#define ASF_STREAM_TYPE_VIDEO 2 +#define ASF_STREAM_TYPE_CONTROL 3 +#define ASF_STREAM_TYPE_JFIF 4 +#define ASF_STREAM_TYPE_DEGRADABLE_JPEG 5 +#define ASF_STREAM_TYPE_FILE_TRANSFER 6 +#define ASF_STREAM_TYPE_BINARY 7 + +#define ASF_MAX_NUM_STREAMS 23 + +#ifndef GUID_DEFINED +#define GUID_DEFINED + +typedef struct _GUID { /* size is 16 */ + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} GUID; + +#endif /* !GUID_DEFINED */ + +static const struct +{ + const char* name; + const GUID guid; +} guids[] = +{ + { "error", + { 0x0,} }, + + + /* base ASF objects */ + { "header", + { 0x75b22630, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, + + { "data", + { 0x75b22636, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, + + { "simple index", + { 0x33000890, 0xe5b1, 0x11cf, { 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb }} }, + + { "index", + { 0xd6e229d3, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, + + { "media object index", + { 0xfeb103f8, 0x12ad, 0x4c64, { 0x84, 0x0f, 0x2a, 0x1d, 0x2f, 0x7a, 0xd4, 0x8c }} }, + + { "timecode index", + { 0x3cb73fd0, 0x0c4a, 0x4803, { 0x95, 0x3d, 0xed, 0xf7, 0xb6, 0x22, 0x8f, 0x0c }} }, + + /* header ASF objects */ + { "file properties", + { 0x8cabdca1, 0xa947, 0x11cf, { 0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, + + { "stream header", + { 0xb7dc0791, 0xa9b7, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, + + { "header extension", + { 0x5fbf03b5, 0xa92e, 0x11cf, { 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, + + { "codec list", + { 0x86d15240, 0x311d, 0x11d0, { 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, + + { "script command", + { 0x1efb1a30, 0x0b62, 0x11d0, { 0xa3, 0x9b, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, + + { "marker", + { 0xf487cd01, 0xa951, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, + + { "bitrate mutual exclusion", + { 0xd6e229dc, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, + + { "error correction", + { 0x75b22635, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, + + { "content description", + { 0x75b22633, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, + + { "extended content description", + { 0xd2d0a440, 0xe307, 0x11d2, { 0x97, 0xf0, 0x00, 0xa0, 0xc9, 0x5e, 0xa8, 0x50 }} }, + + { "stream bitrate properties", /* (http://get.to/sdp) */ + { 0x7bf875ce, 0x468d, 0x11d1, { 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2 }} }, + + { "extended content encryption", + { 0x298ae614, 0x2622, 0x4c17, { 0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c }} }, + + { "padding", + { 0x1806d474, 0xcadf, 0x4509, { 0xa4, 0xba, 0x9a, 0xab, 0xcb, 0x96, 0xaa, 0xe8 }} }, + + + /* stream properties object stream type */ + { "audio media", + { 0xf8699e40, 0x5b4d, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, + + { "video media", + { 0xbc19efc0, 0x5b4d, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, + + { "command media", + { 0x59dacfc0, 0x59e6, 0x11d0, { 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, + + { "JFIF media (JPEG)", + { 0xb61be100, 0x5b4e, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, + + { "Degradable JPEG media", + { 0x35907de0, 0xe415, 0x11cf, { 0xa9, 0x17, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, + + { "File Transfer media", + { 0x91bd222c, 0xf21c, 0x497a, { 0x8b, 0x6d, 0x5a, 0xa8, 0x6b, 0xfc, 0x01, 0x85 }} }, + + { "Binary media", + { 0x3afb65e2, 0x47ef, 0x40f2, { 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43 }} }, + + /* stream properties object error correction */ + { "no error correction", + { 0x20fb5700, 0x5b55, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, + + { "audio spread", + { 0xbfc3cd50, 0x618f, 0x11cf, { 0x8b, 0xb2, 0x00, 0xaa, 0x00, 0xb4, 0xe2, 0x20 }} }, + + + /* mutual exclusion object exlusion type */ + { "mutex bitrate", + { 0xd6e22a01, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, + + { "mutex unknown", + { 0xd6e22a02, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, + + + /* header extension */ + { "reserved_1", + { 0xabd3d211, 0xa9ba, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, + + + /* script command */ + { "reserved script command", + { 0x4B1ACBE3, 0x100B, 0x11D0, { 0xA3, 0x9B, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }} }, + + /* marker object */ + { "reserved marker", + { 0x4CFEDB20, 0x75F6, 0x11CF, { 0x9C, 0x0F, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB }} }, + + /* various */ + /* Already defined (reserved_1) + { "head2", + { 0xabd3d211, 0xa9ba, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, + */ + { "audio conceal none", + { 0x49f1a440, 0x4ece, 0x11d0, { 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, + + { "codec comment1 header", + { 0x86d15241, 0x311d, 0x11d0, { 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, + + { "asf 2.0 header", + { 0xd6e229d1, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, + +}; + +#endif diff -r 0f6573c34500 -r 93c0af9bb521 Plugins/Input/wma/libffwma/uri.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/wma/libffwma/uri.c Sat Jul 15 16:55:29 2006 -0700 @@ -0,0 +1,857 @@ +/* GNet - Networking library + * Copyright (C) 2000-2003 David Helder, David Bolcsfoldi, Eric Williams + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* FIXME: #include "gnet-private.h" */ +#include +#include +#include +#include + +#include "uri.h" +#include + +static void field_unescape (char *str); +static char* field_escape (char* str, unsigned char mask); + +#define USERINFO_ESCAPE_MASK 0x01 +#define PATH_ESCAPE_MASK 0x02 +#define QUERY_ESCAPE_MASK 0x04 +#define FRAGMENT_ESCAPE_MASK 0x08 + +/* #define FALSE 0 */ +/* #define TRUE (!FALSE) */ + +static unsigned char neednt_escape_table[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x0c, + 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, + 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +/* +Perl code to generate above table: + +#!/usr/bin/perl + +$ok = "abcdefghijklmnopqrstuvwxyz" . + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" . + "0123456789" . + "-_.!~*'()"; +$userinfo_ok = ';:&=+\$,'; +$path_ok = ':\@&=+\$,;/'; +$query_ok = ';/?:\@&=+\$,'; +$fragment_ok = ';/?:\@&=+\$,'; + +for ($i = 0; $i < 32; $i++) +{ + print " "; + for ($j = 0; $j < 8; $j++) + { + $num = 0; + $letter = chr(($i * 8) + $j); + + $num |= 0b0001 if (index($userinfo_ok, $letter) != -1); + $num |= 0b0010 if (index($path_ok, $letter) != -1); + $num |= 0b0100 if (index($query_ok, $letter) != -1); + $num |= 0b1000 if (index($fragment_ok, $letter) != -1); + $num |= 0b1111 if (index($ok, $letter) != -1); + + printf "0x%02x, ", $num; + } + print "\n"; +} +*/ + + +/* our own ISSPACE. ANSI isspace is local dependent */ +#define ISSPACE(C) (((C) >= 9 && (C) <= 13) || (C) == ' ') + + +static int split_user_passwd(const char* in, char** user, char** passwd) +{ + char *tmp = strdup(in); + + if(!tmp) + return 0; + *passwd = strchr(tmp, ':'); + if(!(*passwd)) + { + free(tmp); + return 0; + } + *((*passwd)++) = '\0'; // don't you love C? :) + + *user = strdup(tmp); + if(!*user) + return 0; + *passwd = strdup(*passwd); + if(!*passwd) + return 0; + + free(tmp); + return 1; +} + +/** + * gnet_uri_new + * @uri: URI string + * + * Creates a #GURI from a string. Empty fields are set to NULL. The + * parser does not validate the URI -- it will accept some malformed + * URI. URIs are usually in the form + * scheme://userinfo@hostname:port/path?query#fragment + * + * URIs created from user input are typically unescaped. URIs + * created from machine input (e.g. received over the internet) are + * typically escaped. + * + * Returns: a new #GURI, or NULL if there was a failure. + * + **/ +GURI* +gnet_uri_new (const char* uri) +{ + GURI* guri = NULL; + const char* p; + const char* temp; + + g_return_val_if_fail (uri, NULL); + + /* Skip initial whitespace */ + p = uri; + while (*p && ISSPACE((int)*p)) + ++p; + if (!*p) /* Error if it's just a string of space */ + return NULL; + + guri = g_new0 (GURI, 1); + + /* Scheme */ + temp = p; + while (*p && *p != ':' && *p != '/' && *p != '?' && *p != '#') + ++p; + if (*p == ':') + { + guri->scheme = g_strndup (temp, p - temp); + ++p; + } + else /* This char is NUL, /, ?, or # */ + p = temp; + + /* Authority */ + if (*p == '/' && p[1] == '/') + { + char *userinfo; + p += 2; + + /* Userinfo */ + temp = p; + while (*p && *p != '@' && *p != '/' ) /* Look for @ or / */ + ++p; + if (*p == '@') /* Found userinfo */ + { + userinfo = g_strndup (temp, p - temp); + if(!split_user_passwd(userinfo, &guri->user, &guri->passwd)) + { + free(userinfo); + goto error; + } + free(userinfo); + ++p; + } + else + p = temp; + + /* Hostname */ + + /* Check for IPv6 canonical hostname in brackets */ + if (*p == '[') + { + p++; /* Skip [ */ + temp = p; + while (*p && *p != ']') ++p; + if ((p - temp) == 0) + goto error; + guri->hostname = g_strndup (temp, p - temp); + if (*p) + p++; /* Skip ] (if there) */ + } + else + { + temp = p; + while (*p && *p != '/' && *p != '?' && *p != '#' && *p != ':') ++p; + if ((p - temp) == 0) + goto error; + guri->hostname = g_strndup (temp, p - temp); + } + + /* Port */ + if (*p == ':') + { + for (++p; isdigit((int)*p); ++p) + guri->port = guri->port * 10 + (*p - '0'); + } + + } + + /* Path (we are liberal and won't check if it starts with /) */ + temp = p; + while (*p && *p != '?' && *p != '#') + ++p; + if (p != temp) + guri->path = g_strndup(temp, p - temp); + + /* Query */ + if (*p == '?') + { + temp = p + 1; + while (*p && *p != '#') + ++p; + guri->query = g_strndup (temp, p - temp); + } + + /* Fragment */ + if (*p == '#') + { + ++p; + guri->fragment = g_strdup (p); + } + + return guri; + + error: + gnet_uri_delete (guri); + return NULL; +} + + +/** + * gnet_uri_new_fields + * @scheme: scheme + * @hostname: host name + * @port: port + * @path: path + * + * Creates a #GURI from the fields. This function uses the most + * common fields. Use gnet_uri_new_fields_all() to specify all + * fields. + * + * Returns: a new #GURI. + * + **/ +GURI* +gnet_uri_new_fields (const char* scheme, const char* hostname, + const gint port, const char* path) +{ + GURI* uri = NULL; + + uri = g_new0 (GURI, 1); + if (scheme) uri->scheme = g_strdup (scheme); + if (hostname) uri->hostname = g_strdup (hostname); + uri->port = port; + if (path) uri->path = g_strdup (path); + + return uri; +} + + +/** + * gnet_uri_new_fields_all + * @scheme: scheme + * @userinfo: user info + * @hostname: host name + * @port: port + * @path: path + * @query: query + * @fragment: fragment + * + * Creates a #GURI from all fields. + * + * Returns: a new #GURI. + * + **/ +GURI* +gnet_uri_new_fields_all (const char* scheme, const char* user, + const char* passwd, const char* hostname, + const gint port, const char* path, + const char* query, const char* fragment) +{ + GURI* uri = NULL; + + uri = g_new0 (GURI, 1); + if (scheme) uri->scheme = g_strdup (scheme); + if (user) uri->user = g_strdup (user); + if (passwd) uri->passwd = g_strdup (passwd); + if (hostname) uri->hostname = g_strdup (hostname); + uri->port = port; + if (path) uri->path = g_strdup (path); + if (query) uri->query = g_strdup (query); + if (fragment) uri->fragment = g_strdup (fragment); + + return uri; +} + + +/** + * gnet_uri_clone: + * @uri: a #GURI + * + * Copies a #GURI. + * + * Returns: a copy of @uri. + * + **/ +GURI* +gnet_uri_clone (const GURI* uri) +{ + GURI* uri2; + + g_return_val_if_fail (uri, NULL); + + uri2 = g_new0 (GURI, 1); + uri2->scheme = g_strdup (uri->scheme); + uri2->user = g_strdup (uri->user); + uri2->passwd = g_strdup (uri->passwd); + uri2->hostname = g_strdup (uri->hostname); + uri2->port = uri->port; + uri2->path = g_strdup (uri->path); + uri2->query = g_strdup (uri->query); + uri2->fragment = g_strdup (uri->fragment); + + return uri2; +} + + +/** + * gnet_uri_delete: + * @uri: a #GURI + * + * Deletes a #GURI. + * + **/ +void +gnet_uri_delete (GURI* uri) +{ + if (uri) + { + g_free (uri->scheme); + g_free (uri->user); + g_free (uri->passwd); + g_free (uri->hostname); + g_free (uri->path); + g_free (uri->query); + g_free (uri->fragment); + g_free (uri); + } +} + + + + +#define SAFESTRCMP(A,B) (((A)&&(B))?(strcmp((A),(B))):((A)||(B))) + +/** + * gnet_uri_equal + * @p1: a #GURI + * @p2: another #GURI + * + * Compares two #GURI's for equality. + * + * Returns: TRUE if they are equal; FALSE otherwise. + * + **/ +int +gnet_uri_equal (gconstpointer p1, gconstpointer p2) +{ + const GURI* uri1 = (const GURI*) p1; + const GURI* uri2 = (const GURI*) p2; + + g_return_val_if_fail (uri1, FALSE); + g_return_val_if_fail (uri2, FALSE); + + if (uri1->port == uri2->port && + !SAFESTRCMP(uri1->scheme, uri2->scheme) && + !SAFESTRCMP(uri1->user, uri2->user) && + !SAFESTRCMP(uri1->passwd, uri2->passwd) && + !SAFESTRCMP(uri1->hostname, uri2->hostname) && + !SAFESTRCMP(uri1->path, uri2->path) && + !SAFESTRCMP(uri1->query, uri2->query) && + !SAFESTRCMP(uri1->fragment, uri2->fragment)) + return TRUE; + + return FALSE; +} + + +/** + * gnet_uri_hash + * @p: a #GURI + * + * Creates a hash code for @p for use with GHashTable. + * + * Returns: hash code for @p. + * + **/ +guint +gnet_uri_hash (gconstpointer p) +{ + const GURI* uri = (const GURI*) p; + guint h = 0; + + g_return_val_if_fail (uri, 0); + + if (uri->scheme) h = g_str_hash (uri->scheme); + if (uri->user) h ^= g_str_hash (uri->user); + if (uri->passwd) h ^= g_str_hash (uri->passwd); + if (uri->hostname) h ^= g_str_hash (uri->hostname); + h ^= uri->port; + if (uri->path) h ^= g_str_hash (uri->path); + if (uri->query) h ^= g_str_hash (uri->query); + if (uri->fragment) h ^= g_str_hash (uri->fragment); + + return h; +} + + +/** + * gnet_uri_escape + * @uri: a #GURI + * + * Escapes the fields in a #GURI. Network protocols use escaped + * URIs. People use unescaped URIs. + * + **/ +void +gnet_uri_escape (GURI* uri) +{ + g_return_if_fail (uri); + + uri->user = field_escape (uri->user, USERINFO_ESCAPE_MASK); + uri->passwd = field_escape (uri->passwd, USERINFO_ESCAPE_MASK); + uri->path = field_escape (uri->path, PATH_ESCAPE_MASK); + uri->query = field_escape (uri->query, QUERY_ESCAPE_MASK); + uri->fragment = field_escape (uri->fragment, FRAGMENT_ESCAPE_MASK); +} + + +/** + * gnet_uri_unescape + * @uri: a #GURI + * + * Unescapes the fields in the URI. Network protocols use escaped + * URIs. People use unescaped URIs. + * + **/ +void +gnet_uri_unescape (GURI* uri) +{ + g_return_if_fail (uri); + + if (uri->user) + field_unescape (uri->user); + if (uri->passwd) + field_unescape (uri->passwd); + if (uri->path) + field_unescape (uri->path); + if (uri->query) + field_unescape (uri->query); + if (uri->fragment) + field_unescape (uri->fragment); +} + + +static char* +field_escape (char* str, unsigned char mask) +{ + gint len; + gint i; + int must_escape = FALSE; + char* dst; + gint j; + + if (str == NULL) + return NULL; + + /* Roughly calculate buffer size */ + len = 0; + for (i = 0; str[i]; i++) + { + if (neednt_escape_table[(guint) str[i]] & mask) + len++; + else + { + len += 3; + must_escape = TRUE; + } + } + + /* Don't escape if unnecessary */ + if (must_escape == FALSE) + return str; + + /* Allocate buffer */ + dst = (char*) g_malloc(len + 1); + + /* Copy */ + for (i = j = 0; str[i]; i++, j++) + { + /* Unescaped character */ + if (neednt_escape_table[(guint) str[i]] & mask) + { + dst[j] = str[i]; + } + + /* Escaped character */ + else + { + dst[j] = '%'; + + if (((str[i] & 0xf0) >> 4) < 10) + dst[j+1] = ((str[i] & 0xf0) >> 4) + '0'; + else + dst[j+1] = ((str[i] & 0xf0) >> 4) + 'a' - 10; + + if ((str[i] & 0x0f) < 10) + dst[j+2] = (str[i] & 0x0f) + '0'; + else + dst[j+2] = (str[i] & 0x0f) + 'a' - 10; + + j += 2; /* and j is incremented in loop too */ + } + } + dst[j] = '\0'; + + g_free (str); + return dst; +} + + + +static void +field_unescape (char* s) +{ + char* src; + char* dst; + + for (src = dst = s; *src; ++src, ++dst) + { + if (src[0] == '%' && src[1] != '\0' && src[2] != '\0') + { + gint high, low; + + if ('a' <= src[1] && src[1] <= 'f') + high = src[1] - 'a' + 10; + else if ('A' <= src[1] && src[1] <= 'F') + high = src[1] - 'A' + 10; + else if ('0' <= src[1] && src[1] <= '9') + high = src[1] - '0'; + else /* malformed */ + goto regular_copy; + + if ('a' <= src[2] && src[2] <= 'f') + low = src[2] - 'a' + 10; + else if ('A' <= src[2] && src[2] <= 'F') + low = src[2] - 'A' + 10; + else if ('0' <= src[2] && src[2] <= '9') + low = src[2] - '0'; + else /* malformed */ + goto regular_copy; + + *dst = (char)((high << 4) + low); + src += 2; + } + else + { + regular_copy: + *dst = *src; + } + } + + *dst = '\0'; +} + + + +/** + * gnet_uri_get_string + * @uri: a #GURI + * + * Gets a string representation of a #GURI. This function does not + * escape or unescape the fields first. Call gnet_uri_escape() or + * gnet_uri_unescape first if necessary. + * + * Returns: a string. + * + **/ +char* +gnet_uri_get_string (const GURI* uri) +{ + char* rv = NULL; + GString* buffer = NULL; + + g_return_val_if_fail (uri, NULL); + + buffer = g_string_sized_new (16); + + if (uri->scheme) + g_string_sprintfa (buffer, "%s:", uri->scheme); + + if (uri->user || uri->passwd || uri->hostname || uri->port) + g_string_append (buffer, "//"); + + if (uri->user) + { + buffer = g_string_append (buffer, uri->user); + buffer = g_string_append_c (buffer, '@'); + } + if (uri->passwd) + { + buffer = g_string_append (buffer, uri->passwd); + buffer = g_string_append_c (buffer, '@'); + } + + /* Add brackets around the hostname if it's IPv6 */ + if (uri->hostname) + { + if (strchr(uri->hostname, ':') == NULL) + buffer = g_string_append (buffer, uri->hostname); + else + g_string_sprintfa (buffer, "[%s]", uri->hostname); + } + + if (uri->port) + g_string_sprintfa (buffer, ":%d", uri->port); + + if (uri->path) + { + if (*uri->path == '/' || + !(uri->user || uri->passwd || uri->hostname || uri->port)) + g_string_append (buffer, uri->path); + else + g_string_sprintfa (buffer, "/%s", uri->path); + } + + if (uri->query) + g_string_sprintfa (buffer, "?%s", uri->query); + + if (uri->fragment) + g_string_sprintfa (buffer, "#%s", uri->fragment); + + /* Free only GString not data contained, return the data instead */ + rv = buffer->str; + g_string_free (buffer, FALSE); + return rv; +} + + +/** + * gnet_uri_set_scheme + * @uri: a #GURI + * @scheme: scheme + * + * Sets a #GURI's scheme. + * + **/ +void +gnet_uri_set_scheme (GURI* uri, const char* scheme) +{ + g_return_if_fail (uri); + + if (uri->scheme) + { + g_free (uri->scheme); + uri->scheme = NULL; + } + + if (scheme) + uri->scheme = g_strdup (scheme); +} + + +/** + * gnet_uri_set_userinfo + * @uri: a #GURI + * @userinfo: user info + * + * Sets a #GURI's user info. + * + **/ +void +gnet_uri_set_userinfo (GURI* uri, const char* user, const char* passwd) +{ + g_return_if_fail (uri); + + if (uri->user) + { + g_free (uri->user); + uri->user = NULL; + } + if (uri->passwd) + { + g_free (uri->passwd); + uri->passwd = NULL; + } + + if (user) + uri->user = g_strdup (user); + if (passwd) + uri->passwd = g_strdup (passwd); +} + + +/** + * gnet_uri_set_hostname + * @uri: a #GURI + * @hostname: host name + * + * Sets a #GURI's host name. + * + **/ +void +gnet_uri_set_hostname (GURI* uri, const char* hostname) +{ + g_return_if_fail (uri); + + if (uri->hostname) + { + g_free (uri->hostname); + uri->hostname = NULL; + } + + if (hostname) + uri->hostname = g_strdup (hostname); +} + + +/** + * gnet_uri_set_port + * @uri: a #GURI + * @port: port + * + * Set a #GURI's port. + * + **/ +void +gnet_uri_set_port (GURI* uri, gint port) +{ + uri->port = port; +} + + +/** + * gnet_uri_set_path + * @uri: a #GURI + * @path: path + * + * Set a #GURI's path. + * + **/ +void +gnet_uri_set_path (GURI* uri, const char* path) +{ + g_return_if_fail (uri); + + if (uri->path) + { + g_free (uri->path); + uri->path = NULL; + } + + if (path) + uri->path = g_strdup (path); +} + + + +/** + * gnet_uri_set_query + * @uri: a #GURI + * @query: query + * + * Set a #GURI's query. + * + **/ +void +gnet_uri_set_query (GURI* uri, const char* query) +{ + g_return_if_fail (uri); + + if (uri->query) + { + g_free (uri->query); + uri->query = NULL; + } + + if (query) + uri->query = g_strdup (query); +} + + +/** + * gnet_uri_set_fragment + * @uri: a #GURI + * @fragment: fragment + * + * Set a #GURI's fragment. + * + **/ +void +gnet_uri_set_fragment (GURI* uri, const char* fragment) +{ + g_return_if_fail (uri); + + if (uri->fragment) + { + g_free (uri->fragment); + uri->fragment = NULL; + } + + if (fragment) + uri->fragment = g_strdup (fragment); +} diff -r 0f6573c34500 -r 93c0af9bb521 Plugins/Input/wma/libffwma/uri.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Plugins/Input/wma/libffwma/uri.h Sat Jul 15 16:55:29 2006 -0700 @@ -0,0 +1,92 @@ +/* GNet - Networking library + * Copyright (C) 2000-2001 David Helder, David Bolcsfoldi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef _GNET_URI_H +#define _GNET_URI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * GURI: + * @scheme: Scheme (or protocol) + * @userinfo: User info + * @hostname: Host name + * @port: Port number + * @path: Path + * @query: Query + * @fragment: Fragment + * + * The #GURI structure represents a URI. All fields in this + * structure are publicly readable. + * + **/ +typedef struct _GURI GURI; + +struct _GURI +{ + char* scheme; + char* user; + char* passwd; + char* hostname; + gint port; + char* path; + char* query; + char* fragment; +}; + + + +GURI* gnet_uri_new (const char* uri); +GURI* gnet_uri_new_fields (const char* scheme, const char* hostname, + const gint port, const char* path); +GURI* +gnet_uri_new_fields_all (const char* scheme, const char* user, + const char* passwd, const char* hostname, + const gint port, const char* path, + const char* query, const char* fragment); +GURI* gnet_uri_clone (const GURI* uri); +void gnet_uri_delete (GURI* uri); + +gboolean gnet_uri_equal (gconstpointer p1, gconstpointer p2); +guint gnet_uri_hash (gconstpointer p); + +void gnet_uri_escape (GURI* uri); +void gnet_uri_unescape (GURI* uri); + +char* gnet_uri_get_string (const GURI* uri); + +void gnet_uri_set_scheme (GURI* uri, const char* scheme); +void gnet_uri_set_userinfo (GURI* uri, const char* user, const char* passwd); +void gnet_uri_set_hostname (GURI* uri, const char* hostname); +void gnet_uri_set_port (GURI* uri, gint port); +void gnet_uri_set_path (GURI* uri, const char* path); +void gnet_uri_set_query (GURI* uri, const char* query); +void gnet_uri_set_fragment (GURI* uri, const char* fragment); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GNET_URI_H */