Hi everyone,
Here's a patch to the URI implementation which adds support for registry
based naming authority. It's a port of the code I added to the last
release of Xerces-J. Might as well keep both implementations in synch
since they're almost identical. :)
---------------------------
Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: [EMAIL PROTECTED]
E-mail: [EMAIL PROTECTED]
Index: xml-xerces/c/src/xercesc/util/XMLUri.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/util/XMLUri.cpp,v
retrieving revision 1.17
diff -u -r1.17 XMLUri.cpp
--- xml-xerces/c/src/xercesc/util/XMLUri.cpp 1 Oct 2003 16:32:39 -0000 1.17
+++ xml-xerces/c/src/xercesc/util/XMLUri.cpp 11 Dec 2003 19:27:18 -0000
@@ -112,6 +112,16 @@
chDollarSign, chPeriod, chNull
};
+//
+// reg_name = 1*( unreserved | escaped | "$" | "," |
+// ";" | ":" | "@" | "&" | "=" | "+" )
+//
+const XMLCh XMLUri::REG_NAME_CHARACTERS[] =
+{
+ chDollarSign, chComma, chSemiColon, chColon, chAt,
+ chAmpersand, chEqual, chPlus, chNull
+};
+
// pchar plus ';' and '/'.
// pchar = unreserved | escaped |
// ":" | "@" | "&" | "=" | "+" | "$" | ","
@@ -135,6 +145,7 @@
// "UserInfo"
// "Host"
// "Port"
+// "RegName"
// "Path"
// "Query"
// "Fragment"
@@ -175,6 +186,12 @@
chLatin_P, chLatin_o, chLatin_r, chLatin_t, chNull
};
+static const XMLCh errMsg_REGNAME[] =
+{
+ chLatin_R, chLatin_e, chLatin_g,
+ chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull
+};
+
static const XMLCh errMsg_PATH[] =
{
chLatin_P, chLatin_a, chLatin_t, chLatin_h, chNull
@@ -256,6 +273,7 @@
, fUserInfo(0)
, fHost(0)
, fPort(-1)
+, fRegAuth(0)
, fPath(0)
, fQueryString(0)
, fFragment(0)
@@ -284,6 +302,7 @@
, fUserInfo(0)
, fHost(0)
, fPort(-1)
+, fRegAuth(0)
, fPath(0)
, fQueryString(0)
, fFragment(0)
@@ -310,6 +329,7 @@
, fUserInfo(0)
, fHost(0)
, fPort(-1)
+, fRegAuth(0)
, fPath(0)
, fQueryString(0)
, fFragment(0)
@@ -363,6 +383,9 @@
if (fHost)
fMemoryManager->deallocate(fHost);//delete[] fHost;
+
+ if (fRegAuth)
+ fMemoryManager->deallocate(fRegAuth);//delete[] fRegAuth;
if (fPath)
fMemoryManager->deallocate(fPath);//delete[] fPath;
@@ -384,12 +407,13 @@
//
fMemoryManager = toCopy.fMemoryManager;
fScheme = XMLString::replicate(toCopy.fScheme, fMemoryManager);
- fUserInfo = XMLString::replicate(toCopy.fUserInfo, fMemoryManager);
- fHost = XMLString::replicate(toCopy.fHost, fMemoryManager);
- fPort = toCopy.fPort;
- fPath = XMLString::replicate(toCopy.fPath, fMemoryManager);
- fQueryString = XMLString::replicate(toCopy.fQueryString, fMemoryManager);
- fFragment = XMLString::replicate(toCopy.fFragment, fMemoryManager);
+ fUserInfo = XMLString::replicate(toCopy.fUserInfo, fMemoryManager);
+ fHost = XMLString::replicate(toCopy.fHost, fMemoryManager);
+ fPort = toCopy.fPort;
+ fRegAuth = XMLString::replicate(toCopy.fRegAuth, fMemoryManager);
+ fPath = XMLString::replicate(toCopy.fPath, fMemoryManager);
+ fQueryString = XMLString::replicate(toCopy.fQueryString, fMemoryManager);
+ fFragment = XMLString::replicate(toCopy.fFragment, fMemoryManager);
}
void XMLUri::initialize(const XMLUri* const baseURI
@@ -528,13 +552,14 @@
// identified this as a bug in the RFC
if ((!fPath || !*fPath) &&
fScheme == 0 &&
- fHost == 0)
+ fHost == 0 && fRegAuth == 0)
{
fScheme = XMLString::replicate(baseURI->getScheme(), fMemoryManager);
fMemoryManager->deallocate(fUserInfo);//delete [] fUserInfo;
fUserInfo = XMLString::replicate(baseURI->getUserInfo(), fMemoryManager);
fHost = XMLString::replicate(baseURI->getHost(), fMemoryManager);
fPort = baseURI->getPort();
+ fRegAuth = XMLString::replicate(baseURI->getRegBasedAuthority(),
fMemoryManager);
fMemoryManager->deallocate(fPath);//delete [] fPath;
fPath = XMLString::replicate(baseURI->getPath(), fMemoryManager);
@@ -558,12 +583,13 @@
// check for authority - RFC 2396 5.2 #4
// if we found a host, then we've got a network path, so we're done
- if (fHost == 0)
+ if (fHost == 0 && fRegAuth == 0)
{
fMemoryManager->deallocate(fUserInfo);//delete [] fUserInfo;
fUserInfo = XMLString::replicate(baseURI->getUserInfo(), fMemoryManager);
fHost = XMLString::replicate(baseURI->getHost(), fMemoryManager);
fPort = baseURI->getPort();
+ fRegAuth = XMLString::replicate(baseURI->getRegBasedAuthority(),
fMemoryManager);
}
else
{
@@ -628,7 +654,7 @@
// path segment not equal to ".."
index = -1;
int segIndex = -1;
- int offset = 1;
+ int offset = 1;
while ((index = XMLString::patternMatch(&(path[offset]), SLASH_DOTDOT_SLASH))
!= -1)
{
@@ -803,11 +829,23 @@
}
} // if > 0
- // The order is important, do not change
- //
- setHost(host);
- setPort(port);
- setUserInfo(userinfo);
+ // Check if we have server based authority.
+ if (isValidServerBasedAuthority(host, port, userinfo))
+ {
+ if (fHost)
+ fMemoryManager->deallocate(fHost);//delete [] fHost;
+
+ if (fUserInfo)
+ fMemoryManager->deallocate(fUserInfo);//delete[] fUserInfo;
+
+ fHost = XMLString::replicate(host, fMemoryManager);
+ fPort = port;
+ fUserInfo = XMLString::replicate(userinfo, fMemoryManager);
+
+ return;
+ }
+ // This must be registry based authority or the URI is malformed.
+ setRegBasedAuthority(uriSpec);
}
// scheme = alpha *( alpha | digit | "+" | "-" | "." )
@@ -1169,6 +1207,7 @@
}
fHost = XMLString::replicate(newHost, fMemoryManager);
+ setRegBasedAuthority(0);
}
void XMLUri::setPort(int newPort)
@@ -1193,7 +1232,33 @@
}
fPort = newPort;
+}
+void XMLUri::setRegBasedAuthority(const XMLCh* const newRegAuth)
+{
+ if ( !newRegAuth )
+ {
+ if (getRegBasedAuthority())
+ fMemoryManager->deallocate(fRegAuth);//delete [] fRegAuth;
+
+ fRegAuth = 0;
+ return;
+ }
+ // reg_name = 1*( unreserved | escaped | "$" | "," |
+ // ";" | ":" | "@" | "&" | "=" | "+" )
+ else if ( !*newRegAuth || !isValidRegistryBasedAuthority(newRegAuth) )
+ {
+ ThrowXML2(MalformedURLException
+ , XMLExcepts::XMLNUM_URI_Component_Not_Conformant
+ , errMsg_REGNAME
+ , newRegAuth);
+ }
+
+ if (getRegBasedAuthority())
+ fMemoryManager->deallocate(fRegAuth);//delete [] fRegAuth;
+
+ fRegAuth = XMLString::replicate(newRegAuth, fMemoryManager);
+ setHost(0);
}
//
@@ -1384,6 +1449,143 @@
return;
}
+bool XMLUri::isValidServerBasedAuthority(const XMLCh* const host,
+ const int hostLen,
+ const int port,
+ const XMLCh* const userinfo,
+ const int userLen)
+{
+ // The order is important, do not change
+ if (!isWellFormedAddress(host, hostLen))
+ return false;
+
+ // check port number
+ if ((port > 65535) || (port < 0 && port != -1))
+ return false;
+
+ // check userinfo
+ int index = 0;
+ while (index < userLen)
+ {
+ if (isUnreservedCharacter(userinfo[index]) ||
+ (XMLString::indexOf(USERINFO_CHARACTERS, userinfo[index]) != -1))
+ {
+ index++;
+ }
+ else if (userinfo[index] == chPercent) // '%'
+ {
+ if (XMLString::isHex(userinfo[index+1]) && // 1st hex
+ XMLString::isHex(userinfo[index+2]) ) // 2nd hex
+ index +=3;
+ else
+ return false;
+ }
+ else
+ return false;
+ } //while
+
+ return true;
+}
+
+bool XMLUri::isValidServerBasedAuthority(const XMLCh* const host,
+ const int port,
+ const XMLCh* const userinfo)
+{
+ // The order is important, do not change
+ if (!isWellFormedAddress(host))
+ return false;
+
+ // check port number
+ if ((port > 65535) || (port < 0 && port != -1))
+ return false;
+
+ // check userinfo
+ if (!userinfo)
+ return false;
+
+ const XMLCh* tmpStr = userinfo;
+ while (*tmpStr)
+ {
+ if ( isUnreservedCharacter(*tmpStr) ||
+ (XMLString::indexOf(USERINFO_CHARACTERS, *tmpStr) != -1))
+ {
+ tmpStr++;
+ }
+ else if (*tmpStr == chPercent) // '%'
+ {
+ if (XMLString::isHex(*(tmpStr+1)) && // 1st hex
+ XMLString::isHex(*(tmpStr+2)) ) // 2nd hex
+ {
+ tmpStr+=3;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ } //while
+
+ return true;
+}
+
+bool XMLUri::isValidRegistryBasedAuthority(const XMLCh* const authority,
+ const int authLen)
+{
+ // check authority
+ int index = 0;
+ while (index < authLen)
+ {
+ if (isUnreservedCharacter(authority[index]) ||
+ (XMLString::indexOf(REG_NAME_CHARACTERS, authority[index]) != -1))
+ {
+ index++;
+ }
+ else if (authority[index] == chPercent) // '%'
+ {
+ if (XMLString::isHex(authority[index+1]) && // 1st hex
+ XMLString::isHex(authority[index+2]) ) // 2nd hex
+ index +=3;
+ else
+ return false;
+ }
+ else
+ return false;
+ } //while
+
+ return true;
+}
+
+bool XMLUri::isValidRegistryBasedAuthority(const XMLCh* const authority)
+{
+ // check authority
+ if (!authority)
+ return false;
+
+ const XMLCh* tmpStr = authority;
+ while (*tmpStr)
+ {
+ if (isUnreservedCharacter(*tmpStr) ||
+ (XMLString::indexOf(REG_NAME_CHARACTERS, *tmpStr) != -1))
+ {
+ tmpStr++;
+ }
+ else if (*tmpStr == chPercent) // '%'
+ {
+ if (XMLString::isHex(*(tmpStr+1)) && // 1st hex
+ XMLString::isHex(*(tmpStr+2)) ) // 2nd hex
+ {
+ tmpStr+=3;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ } //while
+
+ return true;
+}
+
//
// uric = reserved | unreserved | escaped
// escaped = "%" hex hex
@@ -1731,11 +1933,11 @@
// never required.
//
void XMLUri::buildFullText()
-{
+{
// Calculate the worst case size of the buffer required
unsigned int bufSize = XMLString::stringLen(fScheme) + 1
+ XMLString::stringLen(fFragment) + 1
- + XMLString::stringLen(fHost) + 2
+ + XMLString::stringLen(fHost ? fHost : fRegAuth) + 2
+ XMLString::stringLen(fPath)
+ XMLString::stringLen(fQueryString) + 1
+ XMLString::stringLen(fUserInfo) + 1
@@ -1752,47 +1954,48 @@
XMLString::catString(fURIText, getScheme());
outPtr += XMLString::stringLen(fURIText);
*outPtr++ = chColon;
- *outPtr++ = chForwardSlash;
- *outPtr++ = chForwardSlash;
}
- if (fUserInfo)
+ // Authority
+ if (fHost || fRegAuth)
{
- XMLString::copyString(outPtr, fUserInfo);
- outPtr += XMLString::stringLen(fUserInfo);
-
-
- /*REVISIT dont have password field in uri - is this right??
- if (fPassword)
- {
- *outPtr++ = chColon;
- XMLString::copyString(outPtr, fPassword);
- outPtr += XMLString::stringLen(fPassword);
- }
- */
- *outPtr++ = chAt;
- }
-
- if (fHost)
- {
- XMLString::copyString(outPtr, fHost);
- outPtr += XMLString::stringLen(fHost);
-
- //
- // If the port is -1, then we don't put it in. Else we need
- // to because it was explicitly provided.
- //
- if (fPort != -1)
+ *outPtr++ = chForwardSlash;
+ *outPtr++ = chForwardSlash;
+
+ // Server based authority.
+ if (fHost)
{
- *outPtr++ = chColon;
+ if (fUserInfo)
+ {
+ XMLString::copyString(outPtr, fUserInfo);
+ outPtr += XMLString::stringLen(fUserInfo);
+ *outPtr++ = chAt;
+ }
+
+ XMLString::copyString(outPtr, fHost);
+ outPtr += XMLString::stringLen(fHost);
+
+ //
+ // If the port is -1, then we don't put it in. Else we need
+ // to because it was explicitly provided.
+ //
+ if (fPort != -1)
+ {
+ *outPtr++ = chColon;
- XMLCh tmpBuf[16];
- XMLString::binToText(fPort, tmpBuf, 16, 10);
- XMLString::copyString(outPtr, tmpBuf);
- outPtr += XMLString::stringLen(tmpBuf);
+ XMLCh tmpBuf[16];
+ XMLString::binToText(fPort, tmpBuf, 16, 10);
+ XMLString::copyString(outPtr, tmpBuf);
+ outPtr += XMLString::stringLen(tmpBuf);
+ }
+ }
+ // Registry based authority.
+ else {
+ XMLString::copyString(outPtr, fRegAuth);
+ outPtr += XMLString::stringLen(fRegAuth);
}
}
-
+
if (fPath)
{
XMLString::copyString(outPtr, fPath);
@@ -1909,10 +2112,10 @@
}
}
- // we need to check if index has exceed the lenght or not
+ // we need to check if index has exceed the length or not
if (index < trimedUriSpecLen)
{
- if (!processPath(trimedUriSpec + index, trimedUriSpecLen - index,
foundScheme))
+ if (!processPath(trimedUriSpec + index, trimedUriSpecLen - index,
foundScheme))
return false;
}
@@ -2114,37 +2317,9 @@
}
}
-
- // The order is important, do not change
- if (!isWellFormedAddress(host, hostLen))
- return false;
-
- // check port number
- if ((port > 65535) || (port < 0 && port != -1))
- return false;
-
- // check userinfo
- index = 0;
- while (index < userInfoLen)
- {
- if (isUnreservedCharacter(userinfo[index]) ||
- (XMLString::indexOf(USERINFO_CHARACTERS, userinfo[index]) != -1))
- {
- index++;
- }
- else if (userinfo[index] == chPercent) // '%'
- {
- if (XMLString::isHex(userinfo[index+1]) && // 1st hex
- XMLString::isHex(userinfo[index+2]) ) // 2nd hex
- index +=3;
- else
- return false;
- }
- else
- return false;
- } //while
-
- return true;
+
+ return isValidServerBasedAuthority(host, hostLen, port, userinfo, userInfoLen)
+ || isValidRegistryBasedAuthority(authSpec, authLen);
}
bool XMLUri::processPath(const XMLCh* const pathStr,
@@ -2236,6 +2411,7 @@
serEng<<fPort;
+ serEng.writeString(fRegAuth);
serEng.writeString(fPath);
serEng.writeString(fQueryString);
serEng.writeString(fFragment);
@@ -2249,6 +2425,7 @@
serEng>>fPort;
+ serEng.readString(fRegAuth);
serEng.readString(fPath);
serEng.readString(fQueryString);
serEng.readString(fFragment);
@@ -2262,6 +2439,7 @@
, fUserInfo(0)
, fHost(0)
, fPort(-1)
+, fRegAuth(0)
, fPath(0)
, fQueryString(0)
, fFragment(0)
Index: xml-xerces/c/src/xercesc/util/XMLUri.hpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/util/XMLUri.hpp,v
retrieving revision 1.13
diff -u -r1.13 XMLUri.hpp
--- xml-xerces/c/src/xercesc/util/XMLUri.hpp 2 Dec 2003 17:50:21 -0000 1.13
+++ xml-xerces/c/src/xercesc/util/XMLUri.hpp 11 Dec 2003 19:27:19 -0000
@@ -255,6 +255,13 @@
* @return the port for this URI (-1 if not specified).
*/
int getPort() const;
+
+ /**
+ * Get the registry based authority for this URI.
+ *
+ * @return the registry based authority (null if not specified).
+ */
+ const XMLCh* getRegBasedAuthority() const;
/**
* Get the path for this URI. Note that the value returned is the path
@@ -308,6 +315,9 @@
* Set the host for this URI. If null is passed in, the userinfo
* field is also set to null and the port is set to -1.
*
+ * Note: This method overwrites registry based authority if it
+ * previously existed in this URI.
+ *
* @param newHost the host for this URI
*
*/
@@ -323,6 +333,16 @@
*
*/
void setPort(int newPort);
+
+ /**
+ * Sets the registry based authority for this URI.
+ *
+ * Note: This method overwrites server based authority
+ * if it previously existed in this URI.
+ *
+ * @param newRegAuth the registry based authority for this URI
+ */
+ void setRegBasedAuthority(const XMLCh* const newRegAuth);
/**
* Set the path for this URI.
@@ -398,6 +418,7 @@
static const XMLCh MARK_CHARACTERS[];
static const XMLCh SCHEME_CHARACTERS[];
static const XMLCh USERINFO_CHARACTERS[];
+ static const XMLCh REG_NAME_CHARACTERS[];
static const XMLCh PATH_CHARACTERS[];
//helper method for getUriText
@@ -443,6 +464,50 @@
* @return true if the scheme is conformant, false otherwise
*/
static void isConformantUserInfo(const XMLCh* const userInfo);
+
+ /**
+ * Determines whether the components host, port, and user info
+ * are valid as a server authority.
+ *
+ * @return true if the given host, port, and userinfo compose
+ * a valid server authority
+ */
+ static bool isValidServerBasedAuthority(const XMLCh* const host
+ , const int hostLen
+ , const int port
+ , const XMLCh* const userinfo
+ , const int userLen);
+
+ /**
+ * Determines whether the components host, port, and user info
+ * are valid as a server authority.
+ *
+ * @return true if the given host, port, and userinfo compose
+ * a valid server authority
+ */
+ static bool isValidServerBasedAuthority(const XMLCh* const host
+ , const int port
+ , const XMLCh* const userinfo);
+
+ /**
+ * Determines whether the given string is a registry based authority.
+ *
+ * @param authority the authority component of a URI
+ *
+ * @return true if the given string is a registry based authority
+ */
+ static bool isValidRegistryBasedAuthority(const XMLCh* const authority
+ , const int authLen);
+
+ /**
+ * Determines whether the given string is a registry based authority.
+ *
+ * @param authority the authority component of a URI
+ *
+ * @return true if the given string is a registry based authority
+ */
+ static bool isValidRegistryBasedAuthority(const XMLCh* const authority);
+
/**
* Determine whether a string is syntactically capable of representing
* a valid IPv4 address, IPv6 reference or the domain name of a network host.
@@ -593,6 +658,7 @@
XMLCh* fUserInfo;
XMLCh* fHost;
int fPort;
+ XMLCh* fRegAuth;
XMLCh* fPath;
XMLCh* fQueryString;
XMLCh* fFragment;
@@ -621,6 +687,11 @@
inline int XMLUri::getPort() const
{
return fPort;
+}
+
+inline const XMLCh* XMLUri::getRegBasedAuthority() const
+{
+ return fRegAuth;
}
inline const XMLCh* XMLUri::getPath() const
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]