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]

Reply via email to