[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: [PATCH] URI, URL, FOO, URN
From:       Frans Englich <frans.englich () telia ! com>
Date:       2005-03-16 12:43:32
Message-ID: 200503161243.32476.frans.englich () telia ! com
[Download RAW message or body]

Then I'll commit the class to kdecore/ later today or tomorrow, something like 
that.


			Frans

PS. Attached update includes some small fixes.

["kurn.diff" (text/x-diff)]

Index: Makefile.am
===================================================================
RCS file: /home/kde/kdelibs/kdecore/Makefile.am,v
retrieving revision 1.360
diff -u -3 -p -r1.360 Makefile.am
--- Makefile.am	7 Jan 2005 23:09:18 -0000	1.360
+++ Makefile.am	16 Mar 2005 12:34:25 -0000
@@ -59,7 +59,7 @@ include_HEADERS = kconfig.h kconfigskele
 	kcalendarsystem.h kcalendarsystemfactory.h kmacroexpander.h \
 	kmanagerselection.h kmountpoint.h kuser.h klockfile.h \
 	kidna.h ktempdir.h kshell.h fixx11h.h kxerrorhandler.h kdelibs_export.h \
-	kdemacros.h kde_file.h kswap.h
+	kdemacros.h kde_file.h kswap.h kurn.h
 
 libkdefakes_la_SOURCES = fakes.c vsnprintf.c
 libkdefakes_la_LDFLAGS = -version-info 6:0:2
@@ -100,7 +100,7 @@ libkdecore_la_SOURCES = libintl.cpp kapp
 	kcmdlineargs.cpp kaboutdata.cpp kcompletionbase.cpp knotifyclient.cpp \
 	kaudioplayer.cpp kdcoppropertyproxy.cpp \
 	ksockaddr.cpp kextsock.cpp netsupp.cpp kprocio.cpp kbufferedio.cpp \
-	kpixmapprovider.cpp kurldrag.cpp \
+	kpixmapprovider.cpp kurldrag.cpp kurn.cpp \
 	kmdcodec.cpp ksocks.cpp fakes.c vsnprintf.c \
 	ksycoca.cpp ksycocadict.cpp ksycocafactory.cpp ksycoca.skel \
 	kxmessages.cpp kstartupinfo.cpp kcatalogue.cpp kasyncio.cpp \
Index: kurn.cpp
===================================================================
RCS file: kurn.cpp
diff -N kurn.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ kurn.cpp	16 Mar 2005 12:34:25 -0000
@@ -0,0 +1,290 @@
+/* This file is part of the KDE libraries
+ *
+ * Copyright (C) 2005 Frans Englich 	<frans.englich@telia.com>
+ *
+ * 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; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ **/
+
+#include <qstring.h>
+
+#include "kurn.h"
+
+/**
+ * Case insensitive QString-comparision.
+ */
+#define isInsCaseEqual(a, b) (a.length() == b.length() && (b.find(a, 0, false) != -1))
+
+/*
+ * Related documentation:
+ *
+ * + RFC 3151 -- URN Syntax
+ * + RFC 2141 -- A URN Namespace for Public Identifiers
+ * + OASIS XML Catalogs, section 6.4 - "URN 'Unwrapping'"
+ */
+
+/*
+ * TODO:
+ * + Perform lexical validation in isValidNSS() and isValidNID().
+ */
+
+class KURN::Private
+{
+public:
+	Private():
+		isURN(false),
+		hasValidNSS(false),
+		hasValidNID(false),
+		hasPublicID(false)
+	{ }
+
+	bool isURN :1;
+	bool hasValidNSS :1;
+	bool hasValidNID :1;
+	bool hasPublicID :1;
+	QString nid;
+	QString nss;
+	QString publicID; /* Un-encoded version of nss */
+};
+
+KURN::KURN(): KURL(), d(new Private())
+{
+	init();
+}
+
+KURN::KURN(const QString& uri): KURL(uri.stripWhiteSpace()), d(new Private())
+{
+	init();
+}
+
+KURN::KURN(const KURL& uri): KURL(uri.url().stripWhiteSpace()), d(new Private())
+{
+	init();
+}
+
+KURN::KURN( const char* urn): KURL(QString(urn).stripWhiteSpace()), d(new Private())
+{
+	init();
+}
+
+KURN::~KURN()
+{
+	delete d;
+}
+
+bool KURN::isValidNID(const QString& nid) const
+{
+	if(isInsCaseEqual(nid, QString("urn"))) /* Reserved */
+		return false;
+	else
+		return true;
+}
+
+bool KURN::isValidNSS(const QString& /*nss*/) const
+{
+	return true;
+}
+
+bool KURN::operator==(const KURN &urn)
+{
+	if(namespaceSpecific() == urn.namespaceSpecific() &&
+			isInsCaseEqual(urn.namespaceID(), namespaceID()) &&
+			urn.isValid() &&
+			isValid())
+		return true;
+	else
+		return false;
+}
+
+KURN& KURN::operator=(const QString &uri)
+{
+	KURL::operator=(uri.simplifyWhiteSpace());
+	init();
+	return *this;
+}
+
+KURN& KURN::operator=(const char * uri)
+{
+	KURL::operator=(QString(uri).simplifyWhiteSpace());
+	init();
+	return *this;
+}
+
+KURN& KURN::operator=(const KURN& urn)
+{
+	*d = *(urn.d);
+	return *this;
+}
+
+void KURN::setNamespaceID(const QString& nid)
+{
+	d->nid = nid;
+
+	d->hasValidNID = isValidNID(nid);
+
+	if(d->nid == "publicid")
+		d->hasPublicID = true;
+	else
+	{
+		d->publicID = QString::null;
+		d->hasPublicID = false;
+	}
+}
+
+void KURN::setNamespaceSpecific(const QString& nss)
+{
+	d->nss = nss;
+	d->hasValidNSS = isValidNSS(nss);
+	d->publicID = QString::null;
+
+	/* Normalize %-encoding */
+	const uint length = d->nss.length();
+	for(uint i = 0; i < length; i++)
+		if(d->nss.at(i) == '%')
+		{
+			d->nss.replace(i + 1, 2, d->nss.mid(i + 1, 2).upper());
+			i += 2;
+		}
+
+	if(hasPublicID())
+	{
+		/* Decode the URN into a XML Public ID */
+		const uint length = d->nss.length();
+		for(uint i = 0; i < length; i++)
+		{
+			const QChar c = d->nss.at(i);
+			if(c == '+')
+				d->publicID += " ";
+
+			else if(c == ':')
+				d->publicID += "//";
+
+			else if(c == ';')
+				d->publicID += "::";
+			else if(c == '%')
+			{
+				const QString hex = d->nss.mid(i+1, 2);
+
+				if(hex == "23")
+					d->publicID += '#';
+				else if(hex == "25")
+					d->publicID += '%';
+				else if(hex == "27")
+					d->publicID += '\'';
+				else if(hex == "2B")
+					d->publicID += '+';
+				else if(hex == "2F")
+					d->publicID += '/';
+				else if(hex == "3A")
+					d->publicID += ':';
+				else if(hex == "3B")
+					d->publicID += ';';
+				else if(hex == "3F")
+					d->publicID += '?';
+				else
+					d->publicID += hex;
+				
+				i += 2;
+			}
+			else
+				d->publicID += c;
+		}
+		d->publicID = d->publicID.simplifyWhiteSpace();
+	}
+}
+
+void KURN::init()
+{
+	const QString uri = url();
+
+	/* Put the position of the colon between nss and nid in sepPos */
+	const int sepPos = uri.find(":", 4);
+	setNamespaceID(uri.mid(4, sepPos-4));
+	setNamespaceSpecific(uri.mid(sepPos + 1)); /* +1 == No colon */
+
+	if(uri.startsWith("urn:", false) || uri.isEmpty())
+		d->isURN = true;
+	else
+		d->isURN = false;
+
+}
+
+KURN KURN::fromPublicID(const QString& pub)
+{
+	/* See RFC3151, section 1.1 - "Public Identifiers" */
+	QString npub = pub.simplifyWhiteSpace();
+
+	const uint length = npub.length();
+	for(uint i = 0; i < length; i++)
+	{
+		const QChar c = npub.at(i);
+		if(c == ' ')
+			npub.replace(i, 1, '+');
+		else if(c == '+')
+		{
+			npub.replace(i, 1, "%2B");
+			i += 2;
+		}
+		else if(c == ':')
+			if( npub.at(i+1) == ':')
+				npub.replace(i, 2, ';');
+			else
+			{
+				npub.replace(i, 1, "%3A");
+				i += 2;
+			}
+		else if(c == '/')
+			if(npub.at(i+1) == '/')
+				npub.replace(i, 2, ':');
+			else
+			{
+				npub.replace(i, 1, "%2F");
+				i += 2;
+			}
+	}
+	
+	return KURN(KURL::fromPathOrURL("urn:publicid:" + npub)); /* KURL performs ordinary URI encoding */
+}
+
+QString KURN::urn() const
+{
+	return "urn:" + namespaceID() + ":" + namespaceSpecific();
+}
+
+bool KURN::isValid() const
+{
+	return d->hasValidNID && d->hasValidNSS && d->isURN;
+}
+
+QString KURN::namespaceID() const
+{
+	return d->nid;
+}
+
+bool KURN::hasPublicID() const
+{
+	return d->hasPublicID;
+}
+
+QString KURN::publicID() const
+{
+	return d->publicID;
+}
+
+QString KURN::namespaceSpecific() const
+{
+	return d->nss;
+}
+
Index: kurn.h
===================================================================
RCS file: kurn.h
diff -N kurn.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ kurn.h	16 Mar 2005 12:34:25 -0000
@@ -0,0 +1,212 @@
+/* This file is part of the KDE libraries
+ *
+ * Copyright (C) 2005 Frans Englich 	<frans.englich@telia.com>
+ *
+ * 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; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ **/
+
+#ifndef kurn_h
+#define kurn_h
+
+#include <kurl.h>
+
+class QString;
+
+/**
+ * @short A class for handling URNs, with
+ * support for the publicid namespace.
+ *
+ * @author Frans Englich <frans.englich@telia.com>
+ */
+class KURN: public KURL
+{
+public:
+	/**
+	 * Constructs an empty URN.
+	 */
+	KURN();
+
+	/**
+	 * Constructs a KURN from @p urn, which is assumed to be a valid, properly encoded,
+	 * URN.
+	 *
+	 * @p urn is assumed to be a valid, that is encoded, URN.
+	 * @param urn an URN string to construct
+	 */
+	KURN(const QString& urn);
+
+	/**
+	 * This is an overloaded member function, provided for convenience.
+	 * It behaves essentially like the above function.
+	 */
+	KURN(const KURL& urn);
+
+	/**
+	 * This is an overloaded member function, provided for convenience.
+	 * It behaves essentially like the above function.
+	 */
+	KURN( const char* urn);
+
+	/**
+	 * Destructor.
+	 */
+	virtual ~KURN();
+
+	/**
+	 * Determines whether the URN is in the publicid namespace, as per
+	 * RFC 3151.
+	 *
+	 * @returns true if the URN is in the publicid namespace
+	 */
+	bool hasPublicID() const;
+
+	/**
+	 * Sets the namespace specific string of the URN to @p nss.
+	 */
+	void setNamespaceSpecific(const QString& nss);
+
+	/**
+	 * Sets the URN's namespace ID to @p nid.
+	 *
+	 * @param nid the namespace id to set
+	 */
+	void setNamespaceID( const QString& nid);
+
+	/**
+	 * Retrieves the namespace identifer of the URN. For example, for the
+	 * URN "urn:oasis:names:tc:entity:xmlns" is "oasis" returned.
+	 *
+	 * @returns the namespace identifier
+	 */
+	QString namespaceID() const;
+
+	/**
+	 * Retrieves the namespace specific part of the URN. For example, for
+	 * the URN "urn:oasis:names:tc:entity:xmlns" is "names:tc:entity:xmlns"
+	 * returned.
+	 *
+	 * @returns the namespace specific string
+	 */
+	QString namespaceSpecific() const;
+
+	/**
+	 * Retrieves the contained XML Public ID in an unwrapped, unencoded
+	 * representation. If you want the Public ID in its encoded form,
+	 * use namespaceSpecific(), or urn().
+	 *
+	 * For example:
+	 * \code
+	 * KURN dsssl("urn:publicid:ISO%2FIEC+10179%3A1996:DTD+DSSSL+Architecture:EN");
+	 * //dsssl.publicID() == "ISO/IEC 10179:1996//DTD DSSSL Architecture//EN");
+	 * \endcode
+	 *
+	 * If the URN is not in the publicid namespace, an
+	 * empty string is returned.
+	 *
+	 * @returns a public ID
+	 */
+	QString publicID() const;
+
+	/**
+	 * Returns a complete URN. This is typically a normalized for of what was
+	 * passed in one of the constructors.
+	 */
+	QString urn() const;
+
+	/**
+	 * Determines whether the contained URI is a valid URN. In other words,
+	 * the contained URI may very well be a valid URI, but simply not be
+	 * an URN, or be an invalid URN.
+	 *
+	 * @returns true if the URN is valid
+	 */
+	bool isValid() const;
+
+	/**
+	 * Constructs an URN in the publicid namespace with the
+	 * Public Identifier @p pub. For example:
+	 *
+	 * \code
+	 * KURN urn = KURN::fromPublicID("-//OASIS//DTD Docbook XML V4.1.2//EN");
+	 * //urn.urn() == "urn:publicid:-:OASIS:DTD+Docbook+XML+V4.1.2:EN"
+	 * \endcode
+	 *
+	 * @param pub the public identifier to construct an URN for
+	 * @returns an URN in the publicid with @p pub
+	 */
+	static KURN fromPublicID(const QString& pub);
+
+	/**
+	 * Comparishion operator. Two URNs are considered equal if their
+	 * namespace identifier's are case-insensitively equal, and that the
+	 * namespace specific strings are case-sensitively equal. If a
+	 * particular namespace imposes other semantics on lexical equalness for
+	 * the namespace specific string, this function must be re-implemented.
+	 *
+	 * @returns true if the two URNs are considered equal.
+	 */
+	bool operator==(const KURN &urn);
+
+
+	/**
+	 * Sets the object to house @p urn. This is identical to
+	 * calling a constructor with @p urn. @p urn is assumed to
+	 * be a valid URN.
+	 *
+	 * @param urn the URN to represent
+	 */
+	KURN& operator=(const QString &urn);
+
+	/**
+	 * This is an overloaded member function, provided for convenience.
+	 * It behaves essentially like the above function.
+	 */
+	KURN& operator=(const char * uri);
+
+	/**
+	 * This is an overloaded member function, provided for convenience.
+	 * It behaves essentially like the above function.
+	 */
+	KURN& operator=(const KURN& urn);
+
+protected:
+	
+	/**
+	 * Determines whether @p nid is a valid Namespace Identifier.
+	 *
+	 * @param nid the identifier to validate
+	 * @returns true if @p nid is a valid nid
+	 */
+	bool isValidNID(const QString& nid) const;
+
+	/**
+	 * Determines whether @p nss is a valid Namespace Specific String. Reimplement this
+	 * function to do namespace specific validation, beyond what the RFC mandates.
+	 *
+	 * @param nss the namespace string to validate
+	 * @param returns true if @p nss is considered a valid namespace specific string
+	 */
+	bool isValidNSS(const QString& nss) const;
+
+	void init();
+
+private:
+
+	class Private;
+	Private* const d;
+};
+
+#endif // kurn_h
Index: tests/Makefile.am
===================================================================
RCS file: /home/kde/kdelibs/kdecore/tests/Makefile.am,v
retrieving revision 1.50
diff -u -3 -p -r1.50 Makefile.am
--- tests/Makefile.am	24 Nov 2004 12:22:34 -0000	1.50
+++ tests/Makefile.am	16 Mar 2005 12:34:25 -0000
@@ -28,9 +28,10 @@ check_PROGRAMS = kconfigtest klocaletest
 	cplusplustest kiconloadertest kresolvertest kmdcodectest knotifytest \
 	ksortablevaluelisttest krfcdatetest testqtargs kprociotest \
 	kcharsetstest kcalendartest kmacroexpandertest kshelltest \
-	kxerrorhandlertest startserviceby kstdacceltest kglobaltest
+	kxerrorhandlertest startserviceby kstdacceltest kglobaltest \
+	kurntest
 
-TESTS = kurltest kstdacceltest
+TESTS = kurltest kstdacceltest kurntest
 
 noinst_HEADERS = kconfigtest.h klocaletest.h kprocesstest.h KIDLTest.h \
 		kipctest.h kprociotest.h
@@ -45,6 +46,7 @@ klocaletest_SOURCES = klocaletest.cpp
 #kcatalogue_SOURCES = kcatalogue.cpp libintl.cpp
 ksimpleconfigtest_SOURCES = ksimpleconfigtest.cpp
 kurltest_SOURCES = kurltest.cpp
+kurntest_SOURCES = kurntest.cpp
 kstddirstest_SOURCES = kstddirstest.cpp
 kprocesstest_SOURCES = kprocesstest.cpp
 kuniqueapptest_SOURCES = kuniqueapptest.cpp
Index: tests/kurntest.cpp
===================================================================
RCS file: tests/kurntest.cpp
diff -N tests/kurntest.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/kurntest.cpp	16 Mar 2005 12:34:25 -0000
@@ -0,0 +1,193 @@
+/* This file is part of the KDE libraries
+ *
+ * Copyright (C) 2005 Frans Englich 	<frans.englich@telia.com>
+ *
+ * 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; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ **/
+
+#include <stdlib.h>
+
+#include <qstring.h>
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+#include <kurn.h>
+
+static uint numErrors = 0;
+static uint numSucessess = 0;
+
+/**
+ * Compares @p a to @p b, and if they're not equal the program exits. In either case is
+ * a debug statement printed.
+ *
+ * @param desc a description of the test, such as the function call
+ * @param a the value to be compared to @p b
+ * @param b the value @p a is compared to
+ */
+void check(QString desc, QString a, QString b)
+{
+	if (a.isEmpty())
+		a = QString::null;
+
+	if (b.isEmpty())
+		b = QString::null;
+
+	const QString msg = desc + \
+			" Expected: \"" + b + "\", " + "got \"" + a + "\".";
+	if (a == b)
+	{
+		kdDebug() << "SUCCESS: " << msg << endl;
+		numSucessess++;
+	}
+	else
+	{
+		kdDebug() << "FAILURE: " << msg << endl;
+		numErrors++;
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	KApplication::disableAutoDcopRegistration();
+	KCmdLineArgs::init( argc, argv, "kurltest", 0, 0, 0, 0 );
+	KApplication app( false, false );
+
+	KURN simple("urn:simple:test:yup:tup");
+
+	check("KURN::urn()", simple.urn(), "urn:simple:test:yup:tup");
+	check("KURN::namespaceID()", simple.namespaceID(), "simple");
+	check("KURN::namespaceSpecific()", simple.namespaceSpecific(), "test:yup:tup");
+	check("KURN::isValid()", simple.isValid() ? "true": "false", "true");
+	check("KURN::publicID()", simple.publicID(), "");
+	check("KURN::hasPublicID()", simple.hasPublicID() ? "true": "false", "false");
+
+	simple = "urn:again:foo:no:no"; /* Ensure that values are actually changed */
+	check("KURN::namespaceID()", simple.namespaceID(), "again");
+	check("KURN::namespaceSpecific()", simple.namespaceSpecific(), "foo:no:no");
+	check("KURN::isValid()", simple.isValid() ? "true": "false", "true");
+	check("KURN::publicID()", simple.publicID(), "");
+	check("KURN::hasPublicID()", simple.hasPublicID() ? "true": "false", "false");
+
+	KURN pub("urn:publicid:yo:foo"); /* Simple public ID functionality */
+	check("KURN::namespaceID()", pub.namespaceID(), "publicid");
+	check("KURN::namespaceSpecific()", pub.namespaceSpecific(), "yo:foo");
+	check("KURN::isValid()", pub.isValid() ? "true": "false", "true");
+	check("KURN::publicID()", pub.publicID(), "yo//foo");
+	check("KURN::hasPublicID()", pub.hasPublicID() ? "true": "false", "true");
+
+	/* Examples from the RFC */
+	KURN dsssl("urn:publicid:ISO%2FIEC+10179%3A1996:DTD+DSSSL+Architecture:EN");
+	check("KURN::publicID()", dsssl.publicID(), "ISO/IEC 10179:1996//DTD DSSSL Architecture//EN");
+
+	KURN latin("urn:publicid:ISO+8879%3A1986:ENTITIES+Added+Latin+1:EN");
+	check("KURN::publicID()", latin.publicID(), "ISO 8879:1986//ENTITIES Added Latin 1//EN");
+
+	KURN oasis("urn:publicid:-:OASIS:DTD+DocBook+XML+V4.1.2:EN");
+	check("KURN::publicID()", oasis.publicID(), "-//OASIS//DTD DocBook XML V4.1.2//EN");
+
+	KURN book("urn:publicid:%2B:IDN+example.org:DTD+XML+Bookmarks+1.0:EN:XML");
+	check("KURN::publicID()", book.publicID(), "+//IDN example.org//DTD XML Bookmarks 1.0//EN//XML");
+
+	KURN arbor("urn:publicid:-:ArborText;prod:DTD+Help+Document;19970708:EN");
+	check("KURN::publicID()", arbor.publicID(), "-//ArborText::prod//DTD Help Document::19970708//EN");
+
+	KURN foo("urn:publicid:foo");
+	check("KURN::publicID()", foo.publicID(), "foo");
+
+	KURN math("urn:publicid:3%2B3=6");
+	check("KURN::publicID()", math.publicID(), "3+3=6");
+ 	
+	/* NIDs equal to "urn" are reserved, not those simply starting with "urn" */
+	math = "urn:urnig:test";
+	check("KURN::isValid()", math.isValid() ? "true": "false", "true");
+
+	KURN acme("urn:publicid:-:Acme,+Inc.:DTD+Book+Version+1.0");
+	check("KURN::publicID()", acme.publicID(), "-//Acme, Inc.//DTD Book Version 1.0");
+
+	/* Try to shake it off */
+	acme = "urn:publicid:ISO%2FIEC+10179%3A1996:DTD+DSSSL+Architecture:EN";
+	check("KURN::publicID()", acme.publicID(), "ISO/IEC 10179:1996//DTD DSSSL Architecture//EN");
+	acme = "urn:again:foo:no:no";
+	check("KURN::namespaceID()", acme.namespaceID(), "again");
+	check("KURN::namespaceSpecific()", acme.namespaceSpecific(), "foo:no:no");
+	check("KURN::isValid()", acme.isValid() ? "true": "false", "true");
+	check("KURN::publicID()", acme.publicID(), "");
+	check("KURN::hasPublicID()", acme.hasPublicID() ? "true": "false", "false");
+
+	/* Test equalness code */
+	check("KURN(\"URN:foo:a123,456\") == KURN(\"urn:foo:a123,456\")",
+			(KURN("URN:foo:a123,456") == KURN("urn:foo:a123,456"))
+			? "true" : "false", "true");
+	check("(KURN(\"URN:foo:a123,456\") == KURN(\"urn:FOO:a123,456\")",
+			(KURN("URN:foo:a123,456") == KURN("urn:FOO:a123,456"))
+			? "true" : "false", "true");
+	check("(KURN(\"urn:foo:A123,456\") == KURN(\"Urn:foo:a123,456\")",
+			(KURN("urn:foo:A123,456") == KURN("Urn:foo:a123,456"))
+			? "true" : "false", "false");
+	check("(KURN(\"urn:foo:a123%2C456\") == KURN(\"URN:FOO:a123%2c456\")",
+			(KURN("urn:foo:a123%2C456") == KURN("URN:FOO:a123%2c456"))
+			? "true" : "false", "true");
+	check("(KURN(\"urn:foo:a123%2C456\") == KURN(\"urn:FOO:a123,456\")",
+			(KURN("urn:foo:a123%2C456") == KURN("urn:FOO:a123,456"))
+			? "true" : "false", "false");
+
+
+	/* ...and the other way around */
+
+	check("KURN::fromPublicID(\"ISO/IEC 10179:1996//DTD DSSSL Architecture//EN\").urn()",
+			KURN::fromPublicID("ISO/IEC 10179:1996//DTD DSSSL Architecture//EN").urn(),
+			"urn:publicid:ISO%2FIEC+10179%3A1996:DTD+DSSSL+Architecture:EN");
+	check("KURN::fromPublicID(\"ISO 8879:1986//ENTITIES Added Latin 1//EN\").urn()",
+			KURN::fromPublicID("ISO 8879:1986//ENTITIES Added Latin 1//EN").urn(),
+			"urn:publicid:ISO+8879%3A1986:ENTITIES+Added+Latin+1:EN");
+	check("KURN::fromPublicID(\"+//IDN example.org//DTD XML Bookmarks 1.0//EN//XML\").urn()",
+			KURN::fromPublicID("+//IDN example.org//DTD XML Bookmarks 1.0//EN//XML").urn(),
+			"urn:publicid:%2B:IDN+example.org:DTD+XML+Bookmarks+1.0:EN:XML");
+	check("KURN::fromPublicID(\"-//ArborText::prod//DTD Help Document::19970708//EN\").urn()",
+			KURN::fromPublicID("-//ArborText::prod//DTD Help Document::19970708//EN").urn(),
+			"urn:publicid:-:ArborText;prod:DTD+Help+Document;19970708:EN");
+
+	check("KURN::fromPublicID(\"foo\").urn()",
+			KURN::fromPublicID("foo").urn(),
+			"urn:publicid:foo");
+
+	check("KURN::fromPublicID(\"3+3=6\").urn()",
+			KURN::fromPublicID("3+3=6").urn(),
+			"urn:publicid:3%2B3=6");
+
+	check("KURN::fromPublicID(\"-//Acme, Inc.//DTD Book Version 1.0\").urn()",
+			KURN::fromPublicID("-//Acme, Inc.//DTD Book Version 1.0").urn(),
+			"urn:publicid:-:Acme,+Inc.:DTD+Book+Version+1.0");
+
+	/* Test altering various parts */
+	oasis.setNamespaceID("yo");
+	check("oasis.publicID()", oasis.publicID(), "");
+	check("oasis.hasPublicID", oasis.hasPublicID() ? "true" : "false", "false");
+	check("oasis.namespaceSpecific()", oasis.namespaceSpecific(), "-:OASIS:DTD+DocBook+XML+V4.1.2:EN");
+	check("oasis.urn()", oasis.urn(), "urn:yo:-:OASIS:DTD+DocBook+XML+V4.1.2:EN");
+
+	if(numErrors)
+	{
+		kdDebug() << "*** FAILURE: " << numErrors << " tests failed, " << numSucessess
+			<< " succeeded. ***" << endl;
+		exit(1);
+	}
+	else
+		kdDebug() << "*** SUCCESS: All tests, " << numSucessess << ", succeeded. ***" << endl;
+
+}
+


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic