Index: XMLScanner.hpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/internal/XMLScanner.hpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- XMLScanner.hpp	28 Sep 2004 02:14:13 -0000	1.39
+++ XMLScanner.hpp	28 Sep 2004 21:27:38 -0000	1.40
@@ -731,6 +734,13 @@
     void resetUIntPool();
     void recreateUIntPool();
 
+    inline
+    void setAttrDupChkRegistry
+         (
+            const unsigned int &attrNumber
+          ,       bool         &toUseHashTable
+         );
+
     // -----------------------------------------------------------------------
     //  Data members
     //
@@ -986,6 +996,7 @@
     XMLUInt32                   fScannerId;
     XMLUInt32                   fSequenceId;
     RefVectorOf<XMLAttr>*       fAttrList;
+    RefHash2KeysTableOf<XMLAttr>*  fAttrDupChkRegistry;    
     XMLDocumentHandler*         fDocHandler;
     DocTypeHandler*             fDocTypeHandler;
     XMLEntityHandler*           fEntityHandler;
@@ -1521,6 +1532,29 @@
     fEntityDeclPoolRetrieved = false;
 }
 
+inline void XMLScanner::setAttrDupChkRegistry(const unsigned int &attrNumber
+                                            ,       bool         &toUseHashTable)
+{
+   // once the attribute exceed 20, we use hash table to check duplication
+    if (attrNumber > 20)
+   {
+        toUseHashTable = true;
+
+        if (!fAttrDupChkRegistry)
+        {
+            fAttrDupChkRegistry = new (fMemoryManager) RefHash2KeysTableOf<XMLAttr>
+            (
+              2*attrNumber+1, false, new (fMemoryManager)HashXMLCh(), fMemoryManager
+            );
+        }
+        else
+        {
+            fAttrDupChkRegistry->removeAll();
+        }
+    }
+
+}
+
 XERCES_CPP_NAMESPACE_END
 
 #endif
Index: XMLScanner.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/internal/XMLScanner.cpp,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- XMLScanner.cpp	28 Sep 2004 02:14:13 -0000	1.70
+++ XMLScanner.cpp	28 Sep 2004 21:27:38 -0000	1.71
@@ -157,6 +157,7 @@
     , fScannerId(0)
     , fSequenceId(0)
     , fAttrList(0)
+    , fAttrDupChkRegistry(0)
     , fDocHandler(0)
     , fDocTypeHandler(0)
     , fEntityHandler(0)
@@ -237,6 +238,7 @@
     , fScannerId(0)
     , fSequenceId(0)
     , fAttrList(0)
+    , fAttrDupChkRegistry(0)
     , fDocHandler(docHandler)
     , fDocTypeHandler(docTypeHandler)
     , fEntityHandler(entityHandler)
@@ -279,6 +281,7 @@
 XMLScanner::~XMLScanner()
 {
     delete fAttrList;
+    delete fAttrDupChkRegistry;
     delete fValidationContext;
     fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName;
     fMemoryManager->deallocate(fExternalSchemaLocation);//delete [] fExternalSchemaLocation;
Index: WFXMLScanner.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/internal/WFXMLScanner.cpp,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- WFXMLScanner.cpp	8 Sep 2004 13:56:13 -0000	1.24
+++ WFXMLScanner.cpp	28 Sep 2004 21:27:38 -0000	1.25
@@ -1457,6 +1457,13 @@
     }
 
     if(attCount) {
+
+        //
+        // Decide if to use hash table to do duplicate checking
+        //
+        bool toUseHashTable = false;
+        setAttrDupChkRegistry(attCount, toUseHashTable);
+
         // check for duplicate namespace attributes:
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical. 
@@ -1464,17 +1471,35 @@
         XMLAttr* curAtt;
         for (unsigned int attrIndex=0; attrIndex < attCount-1; attrIndex++) {
             loopAttr = fAttrList->elementAt(attrIndex);
-            for (unsigned int curAttrIndex = attrIndex+1; curAttrIndex < attCount; curAttrIndex++) {
-                curAtt = fAttrList->elementAt(curAttrIndex);
-                if (curAtt->getURIId() == loopAttr->getURIId() &&
-                    XMLString::equals(curAtt->getName(), loopAttr->getName())) {
-                    emitError
-                    ( 
-                        XMLErrs::AttrAlreadyUsedInSTag
+
+            if (!toUseHashTable)
+            {
+                for (unsigned int curAttrIndex = attrIndex+1; curAttrIndex < attCount; curAttrIndex++) {
+                    curAtt = fAttrList->elementAt(curAttrIndex);
+                    if (curAtt->getURIId() == loopAttr->getURIId() &&
+                        XMLString::equals(curAtt->getName(), loopAttr->getName())) {
+                        emitError
+                            ( 
+                            XMLErrs::AttrAlreadyUsedInSTag
                             , curAtt->getName()
                             , elemDecl->getFullName()
+                            );
+                    }
+                }
+            }
+            else 
+            {
+                if (fAttrDupChkRegistry->containsKey((void*)loopAttr->getName(), loopAttr->getURIId()))
+                {
+                    emitError
+                    ( 
+                    XMLErrs::AttrAlreadyUsedInSTag
+                    , loopAttr->getName()
+                    , elemDecl->getFullName()
                     );
                 }
+
+                fAttrDupChkRegistry->put((void*)loopAttr->getName(), loopAttr->getURIId(), loopAttr);
             }
         }  
     }
Index: DGXMLScanner.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/internal/DGXMLScanner.cpp,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- DGXMLScanner.cpp	20 Sep 2004 15:00:49 -0000	1.53
+++ DGXMLScanner.cpp	28 Sep 2004 21:27:38 -0000	1.54
@@ -2378,6 +2378,13 @@
 void DGXMLScanner::scanAttrListforNameSpaces(RefVectorOf<XMLAttr>* theAttrList, int attCount, 
                                                 XMLElementDecl*       elemDecl)
 {
+
+    //
+    // Decide if to use hash table to do duplicate checking
+    //
+    bool toUseHashTable = false;
+    setAttrDupChkRegistry((unsigned int&)attCount, toUseHashTable);
+
     //  Make an initial pass through the list and find any xmlns attributes or
     //  schema attributes.
     //  When we find one, send it off to be used to update the element stack's
@@ -2412,17 +2419,35 @@
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical.         
         XMLAttr* loopAttr;
-        for (int attrIndex=0; attrIndex < index; attrIndex++) {
-            loopAttr = theAttrList->elementAt(attrIndex);
-            if (loopAttr->getURIId() == curAttr->getURIId() &&
-                XMLString::equals(loopAttr->getName(), curAttr->getName())) {
+
+        if (!toUseHashTable)
+        {
+            for (int attrIndex=0; attrIndex < index; attrIndex++) {
+                loopAttr = theAttrList->elementAt(attrIndex);
+                if (loopAttr->getURIId() == curAttr->getURIId() &&
+                    XMLString::equals(loopAttr->getName(), curAttr->getName())) {
+                    emitError
+                        ( 
+                        XMLErrs::AttrAlreadyUsedInSTag
+                        , curAttr->getName()
+                        , elemDecl->getFullName()
+                        );
+                }
+            }
+        }
+        else 
+        {
+            if (fAttrDupChkRegistry->containsKey((void*)curAttr->getName(), curAttr->getURIId()))
+            {
                 emitError
-                ( 
+                    ( 
                     XMLErrs::AttrAlreadyUsedInSTag
                     , curAttr->getName()
                     , elemDecl->getFullName()
-                );
+                    );
             }
+
+            fAttrDupChkRegistry->put((void*)curAttr->getName(), curAttr->getURIId(), curAttr);
         }                 
     }
 }
Index: IGXMLScanner2.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/xercesc/internal/IGXMLScanner2.cpp,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- IGXMLScanner2.cpp	26 Sep 2004 18:23:50 -0000	1.71
+++ IGXMLScanner2.cpp	28 Sep 2004 21:27:38 -0000	1.72
@@ -110,6 +110,15 @@
     XMLBufBid bbNormal(&fBufMgr);
     XMLBuffer& normBuf = bbNormal.getBuffer();
 
+    //
+    // Decide if to use hash table to do duplicate checking
+    //
+    bool toUseHashTable = false;
+    if (fGrammarType == Grammar::DTDGrammarType)
+    {
+        setAttrDupChkRegistry(attCount, toUseHashTable);
+    }
+
     //  Loop through our explicitly provided attributes, which are in the raw
     //  scanned form, and build up XMLAttr objects.
     unsigned int index;
@@ -617,16 +626,32 @@
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical. 
         if (fGrammarType == Grammar::DTDGrammarType) {
-            for (unsigned int attrIndex=0; attrIndex < retCount; attrIndex++) {
-                curAttr = toFill.elementAt(attrIndex);
-                if (uriId == curAttr->getURIId() &&
-                    XMLString::equals(suffPtr, curAttr->getName())) {
+            if (!toUseHashTable)
+            {
+                for (unsigned int attrIndex=0; attrIndex < retCount; attrIndex++) {
+                    curAttr = toFill.elementAt(attrIndex);
+                    if (uriId == curAttr->getURIId() &&
+                        XMLString::equals(suffPtr, curAttr->getName())) {
+                        emitError
+                        ( 
+
+                         XMLErrs::AttrAlreadyUsedInSTag
+                        , curAttr->getName()
+                        , elemDecl->getFullName()
+                        );
+                    }
+                }
+            }
+            else
+            {
+                if (fAttrDupChkRegistry->containsKey((void*)suffPtr, uriId))
+                {
                     emitError
-                    ( 
+                        ( 
                         XMLErrs::AttrAlreadyUsedInSTag
                         , curAttr->getName()
                         , elemDecl->getFullName()
-                    );
+                        );
                 }
             }  
         }
@@ -658,6 +683,12 @@
             );
             curAttr->setSpecified(true);
         }
+
+        if (toUseHashTable)
+        {
+            fAttrDupChkRegistry->put((void*)suffPtr, uriId, curAttr);
+        }
+
         if(psviAttr)
             psviAttr->setValue(curAttr->getValue());
             
--- xerces-c-src_2_5_0/src/xercesc/internal/XMLScanner.hpp.orig	2003-12-31 10:40:00.000000000 -0500
+++ xerces-c-src_2_5_0/src/xercesc/internal/XMLScanner.hpp	2005-03-15 20:39:50.553194368 -0500
@@ -738,6 +738,13 @@
     void resetUIntPool();
     void recreateUIntPool();
 
+    inline
+    void setAttrDupChkRegistry
+         (
+            const unsigned int &attrNumber
+          ,       bool         &toUseHashTable
+         );
+
     // -----------------------------------------------------------------------
     //  Data members
     //
@@ -985,6 +992,7 @@
     XMLUInt32                   fScannerId;
     XMLUInt32                   fSequenceId;
     RefVectorOf<XMLAttr>*       fAttrList;
+    RefHash2KeysTableOf<XMLAttr>*  fAttrDupChkRegistry;    
     XMLDocumentHandler*         fDocHandler;
     DocTypeHandler*             fDocTypeHandler;
     XMLEntityHandler*           fEntityHandler;
@@ -1490,6 +1498,29 @@
     fEntityDeclPoolRetrieved = false;
 }
 
+inline void XMLScanner::setAttrDupChkRegistry(const unsigned int &attrNumber
+                                            ,       bool         &toUseHashTable)
+{
+   // once the attribute exceed 20, we use hash table to check duplication
+    if (attrNumber > 20)
+   {
+        toUseHashTable = true;
+
+        if (!fAttrDupChkRegistry)
+        {
+            fAttrDupChkRegistry = new (fMemoryManager) RefHash2KeysTableOf<XMLAttr>
+            (
+              2*attrNumber+1, false, new (fMemoryManager)HashXMLCh(), fMemoryManager
+            );
+        }
+        else
+        {
+            fAttrDupChkRegistry->removeAll();
+        }
+    }
+
+}
+
 XERCES_CPP_NAMESPACE_END
 
 #endif
--- xerces-c-src_2_5_0/src/xercesc/internal/XMLScanner.cpp.orig	2004-01-29 06:46:30.000000000 -0500
+++ xerces-c-src_2_5_0/src/xercesc/internal/XMLScanner.cpp	2005-03-15 20:39:50.540196344 -0500
@@ -194,6 +194,7 @@
     , fScannerId(0)
     , fSequenceId(0)
     , fAttrList(0)
+    , fAttrDupChkRegistry(0)
     , fDocHandler(0)
     , fDocTypeHandler(0)
     , fEntityHandler(0)
@@ -271,6 +272,7 @@
     , fScannerId(0)
     , fSequenceId(0)
     , fAttrList(0)
+    , fAttrDupChkRegistry(0)
     , fDocHandler(docHandler)
     , fDocTypeHandler(docTypeHandler)
     , fEntityHandler(entityHandler)
@@ -313,6 +315,7 @@
 XMLScanner::~XMLScanner()
 {
     delete fAttrList;
+    delete fAttrDupChkRegistry;
     delete fValidationContext;
     fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName;
     fMemoryManager->deallocate(fExternalSchemaLocation);//delete [] fExternalSchemaLocation;
--- xerces-c-src_2_5_0/src/xercesc/internal/WFXMLScanner.cpp.orig	2005-03-15 20:39:50.532197560 -0500
+++ xerces-c-src_2_5_0/src/xercesc/internal/WFXMLScanner.cpp	2005-03-15 21:31:48.348217480 -0500
@@ -1496,26 +1496,53 @@
         );
     }
 
-    // check for duplicate namespace attributes:
-    // by checking for qualified names with the same local part and with prefixes 
-    // which have been bound to namespace names that are identical. 
-    XMLAttr* loopAttr;
-    XMLAttr* curAtt;
-    for (unsigned int attrIndex=0; attrIndex < attCount-1; attrIndex++) {
-        loopAttr = fAttrList->elementAt(attrIndex);
-        for (unsigned int curAttrIndex = attrIndex+1; curAttrIndex < attCount; curAttrIndex++) {
-            curAtt = fAttrList->elementAt(curAttrIndex);
-            if (curAtt->getURIId() == loopAttr->getURIId() &&
-                XMLString::equals(curAtt->getName(), loopAttr->getName())) {
-                emitError
-                ( 
+    if (attCount) {
+
+        //
+        // Decide if to use hash table to do duplicate checking
+        //
+        bool toUseHashTable = false;
+        setAttrDupChkRegistry(attCount, toUseHashTable);
+
+        // check for duplicate namespace attributes:
+        // by checking for qualified names with the same local part and with prefixes 
+        // which have been bound to namespace names that are identical. 
+        XMLAttr* loopAttr;
+        XMLAttr* curAtt;
+        for (unsigned int attrIndex=0; attrIndex < attCount-1; attrIndex++) {
+            loopAttr = fAttrList->elementAt(attrIndex);
+
+            if (!toUseHashTable)
+            {
+                for (unsigned int curAttrIndex = attrIndex+1; curAttrIndex < attCount; curAttrIndex++) {
+                    curAtt = fAttrList->elementAt(curAttrIndex);
+                    if (curAtt->getURIId() == loopAttr->getURIId() &&
+                        XMLString::equals(curAtt->getName(), loopAttr->getName())) {
+                        emitError
+                            ( 
+                            XMLErrs::AttrAlreadyUsedInSTag
+                            , curAtt->getName()
+                            , elemDecl->getFullName()
+                            );
+                    }
+                }
+            }
+            else 
+            {
+                if (fAttrDupChkRegistry->containsKey((void*)loopAttr->getName(), loopAttr->getURIId()))
+                {
+                    emitError
+                    ( 
                     XMLErrs::AttrAlreadyUsedInSTag
-                        , curAtt->getName()
-                        , elemDecl->getFullName()
-                );
+                    , loopAttr->getName()
+                    , elemDecl->getFullName()
+                    );
+                }
+
+                fAttrDupChkRegistry->put((void*)loopAttr->getName(), loopAttr->getURIId(), loopAttr);
             }
-        }
-    }  
+        }  
+    }
 
     // Resolve the qualified name to a URI.
     unsigned int uriId = resolvePrefix
--- xerces-c-src_2_5_0/src/xercesc/internal/DGXMLScanner.cpp.orig	2004-02-03 11:43:14.000000000 -0500
+++ xerces-c-src_2_5_0/src/xercesc/internal/DGXMLScanner.cpp	2005-03-15 20:39:50.547195280 -0500
@@ -2387,6 +2387,13 @@
 void DGXMLScanner::scanAttrListforNameSpaces(RefVectorOf<XMLAttr>* theAttrList, int attCount, 
                                                 XMLElementDecl*       elemDecl)
 {
+
+    //
+    // Decide if to use hash table to do duplicate checking
+    //
+    bool toUseHashTable = false;
+    setAttrDupChkRegistry((unsigned int&)attCount, toUseHashTable);
+
     //  Make an initial pass through the list and find any xmlns attributes or
     //  schema attributes.
     //  When we find one, send it off to be used to update the element stack's
@@ -2421,17 +2428,35 @@
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical.         
         XMLAttr* loopAttr;
-        for (int attrIndex=0; attrIndex < index; attrIndex++) {
-            loopAttr = theAttrList->elementAt(attrIndex);
-            if (loopAttr->getURIId() == curAttr->getURIId() &&
-                XMLString::equals(loopAttr->getName(), curAttr->getName())) {
+
+        if (!toUseHashTable)
+        {
+            for (int attrIndex=0; attrIndex < index; attrIndex++) {
+                loopAttr = theAttrList->elementAt(attrIndex);
+                if (loopAttr->getURIId() == curAttr->getURIId() &&
+                    XMLString::equals(loopAttr->getName(), curAttr->getName())) {
+                    emitError
+                        ( 
+                        XMLErrs::AttrAlreadyUsedInSTag
+                        , curAttr->getName()
+                        , elemDecl->getFullName()
+                        );
+                }
+            }
+        }
+        else 
+        {
+            if (fAttrDupChkRegistry->containsKey((void*)curAttr->getName(), curAttr->getURIId()))
+            {
                 emitError
-                ( 
+                    ( 
                     XMLErrs::AttrAlreadyUsedInSTag
                     , curAttr->getName()
                     , elemDecl->getFullName()
-                );
+                    );
             }
+
+            fAttrDupChkRegistry->put((void*)curAttr->getName(), curAttr->getURIId(), curAttr);
         }                 
     }
 }
--- xerces-c-src_2_5_0/src/xercesc/internal/IGXMLScanner2.cpp.orig	2004-01-29 06:46:30.000000000 -0500
+++ xerces-c-src_2_5_0/src/xercesc/internal/IGXMLScanner2.cpp	2005-03-15 20:39:50.561193152 -0500
@@ -151,6 +151,15 @@
     XMLBufBid bbNormal(&fBufMgr);
     XMLBuffer& normBuf = bbNormal.getBuffer();
 
+    //
+    // Decide if to use hash table to do duplicate checking
+    //
+    bool toUseHashTable = false;
+    if (fGrammarType == Grammar::DTDGrammarType)
+    {
+        setAttrDupChkRegistry(attCount, toUseHashTable);
+    }
+
     //  Loop through our explicitly provided attributes, which are in the raw
     //  scanned form, and build up XMLAttr objects.
     unsigned int index;
@@ -687,16 +696,32 @@
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical. 
         if (fGrammarType == Grammar::DTDGrammarType) {
-            for (unsigned int attrIndex=0; attrIndex < retCount; attrIndex++) {
-                curAttr = toFill.elementAt(attrIndex);
-                if (uriId == curAttr->getURIId() &&
-                    XMLString::equals(suffPtr, curAttr->getName())) {
+            if (!toUseHashTable)
+            {
+                for (unsigned int attrIndex=0; attrIndex < retCount; attrIndex++) {
+                    curAttr = toFill.elementAt(attrIndex);
+                    if (uriId == curAttr->getURIId() &&
+                        XMLString::equals(suffPtr, curAttr->getName())) {
+                        emitError
+                        ( 
+
+                         XMLErrs::AttrAlreadyUsedInSTag
+                        , curAttr->getName()
+                        , elemDecl->getFullName()
+                        );
+                    }
+                }
+            }
+            else
+            {
+                if (fAttrDupChkRegistry->containsKey((void*)suffPtr, uriId))
+                {
                     emitError
-                    ( 
+                        ( 
                         XMLErrs::AttrAlreadyUsedInSTag
                         , curAttr->getName()
                         , elemDecl->getFullName()
-                    );
+                        );
                 }
             }  
         }
@@ -732,6 +757,12 @@
             );
             curAttr->setSpecified(true);
         }
+
+        if (toUseHashTable)
+        {
+            fAttrDupChkRegistry->put((void*)suffPtr, uriId, curAttr);
+        }
+
         if(psviAttr)
             psviAttr->setValue(curAttr->getValue());
             
--- xerces-c-src2_4_0/src/xercesc/internal/XMLScanner.hpp.orig	2003-11-28 16:18:32.000000000 -0500
+++ xerces-c-src2_4_0/src/xercesc/internal/XMLScanner.hpp	2005-03-15 20:53:57.418451280 -0500
@@ -734,6 +734,13 @@
     void resetUIntPool();
     void recreateUIntPool();
 
+    inline
+    void setAttrDupChkRegistry
+         (
+            const unsigned int &attrNumber
+          ,       bool         &toUseHashTable
+         );
+
     // -----------------------------------------------------------------------
     //  Data members
     //
@@ -981,6 +988,7 @@
     XMLUInt32                   fScannerId;
     XMLUInt32                   fSequenceId;
     RefVectorOf<XMLAttr>*       fAttrList;
+    RefHash2KeysTableOf<XMLAttr>*  fAttrDupChkRegistry;    
     XMLDocumentHandler*         fDocHandler;
     DocTypeHandler*             fDocTypeHandler;
     XMLEntityHandler*           fEntityHandler;
@@ -1486,6 +1494,29 @@
     fEntityDeclPoolRetrieved = false;
 }
 
+inline void XMLScanner::setAttrDupChkRegistry(const unsigned int &attrNumber
+                                            ,       bool         &toUseHashTable)
+{
+   // once the attribute exceed 20, we use hash table to check duplication
+    if (attrNumber > 20)
+   {
+        toUseHashTable = true;
+
+        if (!fAttrDupChkRegistry)
+        {
+            fAttrDupChkRegistry = new (fMemoryManager) RefHash2KeysTableOf<XMLAttr>
+            (
+              2*attrNumber+1, false, new (fMemoryManager)HashXMLCh(), fMemoryManager
+            );
+        }
+        else
+        {
+            fAttrDupChkRegistry->removeAll();
+        }
+    }
+
+}
+
 XERCES_CPP_NAMESPACE_END
 
 #endif
--- xerces-c-src2_4_0/src/xercesc/internal/XMLScanner.cpp.orig	2003-11-27 01:10:31.000000000 -0500
+++ xerces-c-src2_4_0/src/xercesc/internal/XMLScanner.cpp	2005-03-15 20:53:57.404453408 -0500
@@ -194,6 +194,7 @@
     , fScannerId(0)
     , fSequenceId(0)
     , fAttrList(0)
+    , fAttrDupChkRegistry(0)
     , fDocHandler(0)
     , fDocTypeHandler(0)
     , fEntityHandler(0)
@@ -270,6 +271,7 @@
     , fScannerId(0)
     , fSequenceId(0)
     , fAttrList(0)
+    , fAttrDupChkRegistry(0)
     , fDocHandler(docHandler)
     , fDocTypeHandler(docTypeHandler)
     , fEntityHandler(entityHandler)
@@ -317,6 +319,7 @@
 XMLScanner::~XMLScanner()
 {
     delete fAttrList;
+    delete fAttrDupChkRegistry;
     delete fValidationContext;
     fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName;
     fMemoryManager->deallocate(fExternalSchemaLocation);//delete [] fExternalSchemaLocation;
--- xerces-c-src2_4_0/src/xercesc/internal/WFXMLScanner.cpp.orig	2003-11-01 15:24:22.000000000 -0500
+++ xerces-c-src2_4_0/src/xercesc/internal/WFXMLScanner.cpp	2005-03-15 21:53:44.144186088 -0500
@@ -1433,23 +1433,6 @@
                 }
             }
 
-            // check for duplicate namespace attributes:
-            // by checking for qualified names with the same local part and with prefixes 
-            // which have been bound to namespace names that are identical. 
-            XMLAttr* loopAttr;
-            for (unsigned int attrIndex=0; attrIndex < attCount; attrIndex++) {
-                loopAttr = fAttrList->elementAt(attrIndex);
-                if (curAtt->getURIId() == loopAttr->getURIId() &&
-                    XMLString::equals(curAtt->getName(), loopAttr->getName())) {
-                    emitError
-                    ( 
-                        XMLErrs::AttrAlreadyUsedInSTag
-                        , curAtt->getName()
-                        , elemDecl->getFullName()
-                    );
-                }
-            }  
-
             // increment attribute count
             attCount++;
 
@@ -1513,6 +1496,54 @@
         );
     }
 
+    if (attCount) {
+
+        //
+        // Decide if to use hash table to do duplicate checking
+        //
+        bool toUseHashTable = false;
+        setAttrDupChkRegistry(attCount, toUseHashTable);
+
+        // check for duplicate namespace attributes:
+        // by checking for qualified names with the same local part and with prefixes 
+        // which have been bound to namespace names that are identical. 
+        XMLAttr* loopAttr;
+        XMLAttr* curAtt;
+        for (unsigned int attrIndex=0; attrIndex < attCount-1; attrIndex++) {
+            loopAttr = fAttrList->elementAt(attrIndex);
+
+            if (!toUseHashTable)
+            {
+                for (unsigned int curAttrIndex = attrIndex+1; curAttrIndex < attCount; curAttrIndex++) {
+                    curAtt = fAttrList->elementAt(curAttrIndex);
+                    if (curAtt->getURIId() == loopAttr->getURIId() &&
+                        XMLString::equals(curAtt->getName(), loopAttr->getName())) {
+                        emitError
+                            ( 
+                            XMLErrs::AttrAlreadyUsedInSTag
+                            , curAtt->getName()
+                            , elemDecl->getFullName()
+                            );
+                    }
+                }
+            }
+            else 
+            {
+                if (fAttrDupChkRegistry->containsKey((void*)loopAttr->getName(), loopAttr->getURIId()))
+                {
+                    emitError
+                    ( 
+                    XMLErrs::AttrAlreadyUsedInSTag
+                    , loopAttr->getName()
+                    , elemDecl->getFullName()
+                    );
+                }
+
+                fAttrDupChkRegistry->put((void*)loopAttr->getName(), loopAttr->getURIId(), loopAttr);
+            }
+        }  
+    }
+
     // Resolve the qualified name to a URI.
     unsigned int uriId = resolvePrefix
     (
--- xerces-c-src2_4_0/src/xercesc/internal/DGXMLScanner.cpp.orig	2003-11-24 00:09:38.000000000 -0500
+++ xerces-c-src2_4_0/src/xercesc/internal/DGXMLScanner.cpp	2005-03-15 20:53:57.411452344 -0500
@@ -2355,6 +2355,13 @@
 void DGXMLScanner::scanAttrListforNameSpaces(RefVectorOf<XMLAttr>* theAttrList, int attCount, 
                                                 XMLElementDecl*       elemDecl)
 {
+
+    //
+    // Decide if to use hash table to do duplicate checking
+    //
+    bool toUseHashTable = false;
+    setAttrDupChkRegistry((unsigned int&)attCount, toUseHashTable);
+
     //  Make an initial pass through the list and find any xmlns attributes or
     //  schema attributes.
     //  When we find one, send it off to be used to update the element stack's
@@ -2389,17 +2396,35 @@
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical.         
         XMLAttr* loopAttr;
-        for (int attrIndex=0; attrIndex < index; attrIndex++) {
-            loopAttr = theAttrList->elementAt(attrIndex);
-            if (loopAttr->getURIId() == curAttr->getURIId() &&
-                XMLString::equals(loopAttr->getName(), curAttr->getName())) {
+
+        if (!toUseHashTable)
+        {
+            for (int attrIndex=0; attrIndex < index; attrIndex++) {
+                loopAttr = theAttrList->elementAt(attrIndex);
+                if (loopAttr->getURIId() == curAttr->getURIId() &&
+                    XMLString::equals(loopAttr->getName(), curAttr->getName())) {
+                    emitError
+                        ( 
+                        XMLErrs::AttrAlreadyUsedInSTag
+                        , curAttr->getName()
+                        , elemDecl->getFullName()
+                        );
+                }
+            }
+        }
+        else 
+        {
+            if (fAttrDupChkRegistry->containsKey((void*)curAttr->getName(), curAttr->getURIId()))
+            {
                 emitError
-                ( 
+                    ( 
                     XMLErrs::AttrAlreadyUsedInSTag
                     , curAttr->getName()
                     , elemDecl->getFullName()
-                );
+                    );
             }
+
+            fAttrDupChkRegistry->put((void*)curAttr->getName(), curAttr->getURIId(), curAttr);
         }                 
     }
 }
--- xerces-c-src2_4_0/src/xercesc/internal/IGXMLScanner2.cpp.orig	2003-11-28 15:20:54.000000000 -0500
+++ xerces-c-src2_4_0/src/xercesc/internal/IGXMLScanner2.cpp	2005-03-15 21:37:28.431516960 -0500
@@ -157,6 +157,15 @@
     XMLBufBid bbNormal(&fBufMgr);
     XMLBuffer& normBuf = bbNormal.getBuffer();
 
+    //
+    // Decide if to use hash table to do duplicate checking
+    //
+    bool toUseHashTable = false;
+    if (fGrammarType == Grammar::DTDGrammarType)
+    {
+        setAttrDupChkRegistry(attCount, toUseHashTable);
+    }
+
     //  Loop through our explicitly provided attributes, which are in the raw
     //  scanned form, and build up XMLAttr objects.
     unsigned int index;
@@ -661,16 +670,32 @@
         // by checking for qualified names with the same local part and with prefixes 
         // which have been bound to namespace names that are identical. 
         if (fGrammarType == Grammar::DTDGrammarType) {
-            for (unsigned int attrIndex=0; attrIndex < retCount; attrIndex++) {
-                curAttr = toFill.elementAt(attrIndex);
-                if (uriId == curAttr->getURIId() &&
-                    XMLString::equals(suffPtr, curAttr->getName())) {
+            if (!toUseHashTable)
+            {
+                for (unsigned int attrIndex=0; attrIndex < retCount; attrIndex++) {
+                    curAttr = toFill.elementAt(attrIndex);
+                    if (uriId == curAttr->getURIId() &&
+                        XMLString::equals(suffPtr, curAttr->getName())) {
+                        emitError
+                        ( 
+
+                         XMLErrs::AttrAlreadyUsedInSTag
+                        , curAttr->getName()
+                        , elemDecl->getFullName()
+                        );
+                    }
+                }
+            }
+            else
+            {
+                if (fAttrDupChkRegistry->containsKey((void*)suffPtr, uriId))
+                {
                     emitError
-                    ( 
+                        ( 
                         XMLErrs::AttrAlreadyUsedInSTag
                         , curAttr->getName()
                         , elemDecl->getFullName()
-                    );
+                        );
                 }
             }  
         }
@@ -707,6 +732,12 @@
             curAttr->setSpecified(true);
         }
             
+
+        if (toUseHashTable)
+        {
+            fAttrDupChkRegistry->put((void*)suffPtr, uriId, curAttr);
+        }
+
         // Bump the count of attrs in the list
         retCount++;
     }

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to