summaryrefslogtreecommitdiffstats
path: root/src/dom/uri.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dom/uri.cpp')
-rwxr-xr-xsrc/dom/uri.cpp454
1 files changed, 454 insertions, 0 deletions
diff --git a/src/dom/uri.cpp b/src/dom/uri.cpp
new file mode 100755
index 000000000..38cdbb688
--- /dev/null
+++ b/src/dom/uri.cpp
@@ -0,0 +1,454 @@
+/**
+ * Phoebe DOM Implementation.
+ *
+ * This is a C++ approximation of the W3C DOM model, which follows
+ * fairly closely the specifications in the various .idl files, copies of
+ * which are provided for reference. Most important is this one:
+ *
+ * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
+ *
+ * Authors:
+ * Bob Jamison
+ *
+ * Copyright (C) 2005 Bob Jamison
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+
+
+#include "uri.h"
+
+#include <stdarg.h>
+
+
+
+namespace org
+{
+namespace w3c
+{
+namespace dom
+{
+
+
+typedef struct
+{
+ int ival;
+ char *sval;
+} LookupEntry;
+
+LookupEntry schemes[] =
+{
+ { URI::SCHEME_DATA, "data:" },
+ { URI::SCHEME_HTTP, "http:" },
+ { URI::SCHEME_FTP, "ftp" },
+ { URI::SCHEME_FILE, "file:" },
+ { URI::SCHEME_LDAP, "ldap:" },
+ { URI::SCHEME_MAILTO, "mailto:" },
+ { URI::SCHEME_NEWS, "news:" },
+ { URI::SCHEME_TELNET, "telnet:" },
+ { 0, NULL }
+};
+
+
+
+//#########################################################################
+//# C O N S T R U C T O R
+//#########################################################################
+
+/**
+ *
+ */
+URI::URI()
+{
+ init();
+}
+
+/**
+ *
+ */
+URI::URI(const DOMString &str)
+{
+ init();
+ parse(str);
+}
+
+
+/**
+ *
+ */
+URI::URI(const char *str)
+{
+ init();
+ DOMString domStr = str;
+ parse(domStr);
+}
+
+
+/**
+ *
+ */
+URI::URI(const URI &other)
+{
+ init();
+ scheme = other.scheme;
+ schemeStr = other.schemeStr;
+ authority = other.authority;
+ path = other.path;
+ absolute = other.absolute;
+ query = other.query;
+ fragment = other.fragment;
+}
+
+
+/**
+ *
+ */
+URI::~URI()
+{
+}
+
+
+
+
+
+/**
+ *
+ */
+void URI::init()
+{
+ parsebuf = NULL;
+ parselen = 0;
+ scheme = SCHEME_NONE;
+ schemeStr = "";
+ authority = "";
+ path = "";
+ absolute = false;
+ query = "";
+ fragment = "";
+}
+
+
+
+//#########################################################################
+//#A T T R I B U T E S
+//#########################################################################
+
+DOMString URI::toString()
+{
+ DOMString str = schemeStr;
+ if (authority.size()>0)
+ {
+ str.append("//");
+ str.append(authority);
+ }
+ str.append(path);
+ if (query.size() > 0)
+ {
+ str.append("?");
+ str.append(query);
+ }
+ if (fragment.size() > 0)
+ {
+ str.append("#");
+ str.append(fragment);
+ }
+ return str;
+}
+
+
+int URI::getScheme()
+{
+ return scheme;
+}
+
+DOMString URI::getSchemeStr()
+{
+ return schemeStr;
+}
+
+
+DOMString URI::getAuthority()
+{
+ return authority;
+}
+
+
+DOMString URI::getPath()
+{
+ return path;
+}
+
+
+bool URI::getIsAbsolute()
+{
+ return absolute;
+}
+
+
+DOMString URI::getQuery()
+{
+ return query;
+}
+
+
+DOMString URI::getFragment()
+{
+ return fragment;
+}
+
+
+
+//#########################################################################
+//# M E S S A G E S
+//#########################################################################
+
+void URI::error(const char *fmt, ...)
+{
+ va_list args;
+ fprintf(stderr, "URI error: ");
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+}
+
+void URI::trace(const char *fmt, ...)
+{
+ va_list args;
+ fprintf(stdout, "URI: ");
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+ fprintf(stdout, "\n");
+}
+
+
+
+//#########################################################################
+//# P A R S I N G
+//#########################################################################
+
+
+
+int URI::peek(int p)
+{
+ if (p<0 || p>=parselen)
+ return -1;
+ return parsebuf[p];
+}
+
+
+
+int URI::match(int p0, char *key)
+{
+ int p = p0;
+ while (p < parselen)
+ {
+ if (*key != parsebuf[p])
+ break;
+ p++; key++;
+ }
+ return p;
+}
+
+//#########################################################################
+//# Parsing is performed according to:
+//# http://www.gbiv.com/protocols/uri/rfc/rfc3986.html#components
+//#########################################################################
+
+int URI::parseScheme(int p0)
+{
+ int p = p0;
+ for (LookupEntry *entry = schemes; entry->sval ; entry++)
+ {
+ int p2 = match(p, entry->sval);
+ if (p2 > p)
+ {
+ schemeStr = entry->sval;
+ scheme = entry->ival;
+ p = p2;
+ return p;
+ }
+ }
+
+ return p;
+}
+
+
+int URI::parseHierarchicalPart(int p0)
+{
+ int p = p0;
+ int ch;
+
+ //# Authority field (host and port, for example)
+ int p2 = match(p, "//");
+ if (p2 > p)
+ {
+ p = p2;
+ while (p < parselen)
+ {
+ ch = peek(p);
+ if (ch == '/')
+ break;
+ authority.push_back(ch);
+ p++;
+ }
+ }
+
+ //# Are we absolute?
+ ch = peek(p);
+ if (ch == '/')
+ {
+ absolute = true;
+ path.push_back(ch);
+ p++;
+ }
+
+ while (p < parselen)
+ {
+ ch = peek(p);
+ if (ch == '?' || ch == '#')
+ break;
+ path.push_back(ch);
+ p++;
+ }
+
+ return p;
+}
+
+int URI::parseQuery(int p0)
+{
+ int p = p0;
+ int ch = peek(p);
+ if (ch != '?')
+ return p0;
+
+ p++;
+ while (p < parselen)
+ {
+ ch = peek(p);
+ if (ch == '#')
+ break;
+ query.push_back(ch);
+ p++;
+ }
+
+
+ return p;
+}
+
+int URI::parseFragment(int p0)
+{
+
+ int p = p0;
+ int ch = peek(p);
+ if (ch != '#')
+ return p0;
+
+ p++;
+ while (p < parselen)
+ {
+ ch = peek(p);
+ if (ch == '?')
+ break;
+ fragment.push_back(ch);
+ p++;
+ }
+
+
+ return p;
+}
+
+
+int URI::parse(int p0)
+{
+
+ int p = p0;
+
+ int p2 = parseScheme(p);
+ if (p2 < 0)
+ {
+ error("Scheme");
+ return -1;
+ }
+ p = p2;
+
+
+ p2 = parseHierarchicalPart(p);
+ if (p2 < 0)
+ {
+ error("Hierarchical part");
+ return -1;
+ }
+ p = p2;
+
+ p2 = parseQuery(p);
+ if (p2 < 0)
+ {
+ error("Query");
+ return -1;
+ }
+ p = p2;
+
+
+ p2 = parseFragment(p);
+ if (p2 < 0)
+ {
+ error("Fragment");
+ return -1;
+ }
+ p = p2;
+
+ return p;
+
+}
+
+
+
+bool URI::parse(const DOMString &str)
+{
+
+ parselen = str.size();
+ DOMString tmp = str;
+ parsebuf = (char *) tmp.c_str();
+
+
+ int p = parse(0);
+
+ if (p < 0)
+ {
+ error("Syntax error");
+ return false;
+ }
+
+ return true;
+
+}
+
+
+
+
+
+} //namespace dom
+} //namespace w3c
+} //namespace org
+//#########################################################################
+//# E N D O F F I L E
+//#########################################################################
+
+
+