changeset 1410:93c0af9bb521 trunk

[svn] Add more files from libmms CVS.
author chainsaw
date Sat, 15 Jul 2006 16:55:29 -0700
parents 0f6573c34500
children bf7fe0421354
files ChangeLog Plugins/Input/wma/libffwma/asfheader.h Plugins/Input/wma/libffwma/uri.c Plugins/Input/wma/libffwma/uri.h
diffstat 4 files changed, 1219 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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 <nenolod@nenolod.net>
+  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 <nenolod@nenolod.net>
   revision [1730]
   - bump to version 1.1.1
--- /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
--- /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 <glib.h>
+#include <string.h>
+#include <malloc.h>
+#include <ctype.h>
+
+#include "uri.h"
+#include <string.h>
+
+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);
+}
--- /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 <glib.h>
+
+#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 */