Changeset 3103 for icXML/icXML-devel


Ignore:
Timestamp:
May 3, 2013, 11:28:28 AM (6 years ago)
Author:
cameron
Message:

Initial imports for icXML v0.9

Location:
icXML/icXML-devel
Files:
4 added
4 deleted
121 edited

Legend:

Unmodified
Added
Removed
  • icXML/icXML-devel/BUGS.txt

    r2781 r3103  
    1 icXML-0.8 Known Issues
     1icXML-0.81 Known Issues
    22
    33(1) The DGXML and SGXML scanners are not supported.
     
    88(3) There are some known memory leaks.
    99
    10 (4) xmlns attributes in DTDs are not properly handled.
    11  
    12 (5) icXML reports errors differently than Xerces in
     10(4) icXML reports errors differently than Xerces in
    1311    many cases.
    1412
    15 (6) Superlong element names are not supported.
     13(5) Superlong element names are not supported.
    1614
  • icXML/icXML-devel/src/Makefile.am

    r2807 r3103  
    538538        xercesc/internal/IANAEncodings.hpp \
    539539        icxercesc/internal/IGXMLScanner.hpp \
    540         xercesc/internal/MemoryManagerImpl.hpp \
     540        icxercesc/internal/MemoryManagerImpl.hpp \
    541541        icxercesc/internal/ReaderMgr.hpp \
    542542        icxercesc/internal/SGXMLScanner.hpp \
     
    745745        xercesc/util/XMLBigDecimal.hpp \
    746746        xercesc/util/XMLBigInteger.hpp \
    747         xercesc/util/XMLChar.hpp \
     747        icxercesc/util/XMLChar.hpp \
    748748        icxercesc/util/XMLChTranscoder.hpp \
    749749        xercesc/util/XMLDateTime.hpp \
     
    827827        xercesc/util/XMLBigDecimal.cpp \
    828828        xercesc/util/XMLBigInteger.cpp \
    829         xercesc/util/XMLChar.cpp \
     829        icxercesc/util/XMLChar.cpp \
    830830        icxercesc/util/XMLChTranscoder.cpp \
    831831        xercesc/util/XMLDateTime.cpp \
     
    934934        xercesc/validators/schema/SchemaAttDefList.hpp \
    935935        xercesc/validators/schema/SchemaElementDecl.hpp \
    936         xercesc/validators/schema/SchemaGrammar.hpp \
     936        icxercesc/validators/schema/SchemaGrammar.hpp \
    937937        xercesc/validators/schema/SchemaInfo.hpp \
    938938        icxercesc/validators/schema/SchemaSymbols.hpp \
     
    10241024        xercesc/validators/schema/SchemaAttDefList.cpp \
    10251025        xercesc/validators/schema/SchemaElementDecl.cpp \
    1026         xercesc/validators/schema/SchemaGrammar.cpp \
     1026        icxercesc/validators/schema/SchemaGrammar.cpp \
    10271027        xercesc/validators/schema/SchemaInfo.cpp \
    10281028        icxercesc/validators/schema/SchemaSymbols.cpp \
  • icXML/icXML-devel/src/Makefile.in

    r2807 r3103  
    218218        icxercesc/util/XMLASCIITranscoder.cpp \
    219219        xercesc/util/XMLBigDecimal.cpp xercesc/util/XMLBigInteger.cpp \
    220         xercesc/util/XMLChar.cpp icxercesc/util/XMLChTranscoder.cpp \
     220        icxercesc/util/XMLChar.cpp icxercesc/util/XMLChTranscoder.cpp \
    221221        xercesc/util/XMLDateTime.cpp xercesc/util/XMLDouble.cpp \
    222222        xercesc/util/XMLEBCDICTranscoder.cpp \
     
    433433        xercesc/validators/schema/SchemaAttDefList.cpp \
    434434        xercesc/validators/schema/SchemaElementDecl.cpp \
    435         xercesc/validators/schema/SchemaGrammar.cpp \
     435        icxercesc/validators/schema/SchemaGrammar.cpp \
    436436        xercesc/validators/schema/SchemaInfo.cpp \
    437437        icxercesc/validators/schema/SchemaSymbols.cpp \
     
    513513        icxercesc/util/XMLASCIITranscoder.lo \
    514514        xercesc/util/XMLBigDecimal.lo xercesc/util/XMLBigInteger.lo \
    515         xercesc/util/XMLChar.lo icxercesc/util/XMLChTranscoder.lo \
     515        icxercesc/util/XMLChar.lo icxercesc/util/XMLChTranscoder.lo \
    516516        xercesc/util/XMLDateTime.lo xercesc/util/XMLDouble.lo \
    517517        xercesc/util/XMLEBCDICTranscoder.lo \
     
    729729        xercesc/validators/schema/SchemaAttDefList.lo \
    730730        xercesc/validators/schema/SchemaElementDecl.lo \
    731         xercesc/validators/schema/SchemaGrammar.lo \
     731        icxercesc/validators/schema/SchemaGrammar.lo \
    732732        xercesc/validators/schema/SchemaInfo.lo \
    733733        icxercesc/validators/schema/SchemaSymbols.lo \
     
    923923        icxercesc/util/XMLASCIITranscoder.hpp \
    924924        xercesc/util/XMLBigDecimal.hpp xercesc/util/XMLBigInteger.hpp \
    925         xercesc/util/XMLChar.hpp icxercesc/util/XMLChTranscoder.hpp \
     925        icxercesc/util/XMLChar.hpp icxercesc/util/XMLChTranscoder.hpp \
    926926        xercesc/util/XMLDateTime.hpp xercesc/util/XMLDOMMsg.hpp \
    927927        xercesc/util/XMLDouble.hpp \
     
    10981098        xercesc/internal/IANAEncodings.hpp \
    10991099        icxercesc/internal/IGXMLScanner.hpp \
    1100         xercesc/internal/MemoryManagerImpl.hpp \
     1100        icxercesc/internal/MemoryManagerImpl.hpp \
    11011101        icxercesc/internal/ReaderMgr.hpp \
    11021102        icxercesc/internal/SGXMLScanner.hpp \
     
    12161216        xercesc/validators/schema/SchemaAttDefList.hpp \
    12171217        xercesc/validators/schema/SchemaElementDecl.hpp \
    1218         xercesc/validators/schema/SchemaGrammar.hpp \
     1218        icxercesc/validators/schema/SchemaGrammar.hpp \
    12191219        xercesc/validators/schema/SchemaInfo.hpp \
    12201220        icxercesc/validators/schema/SchemaSymbols.hpp \
     
    18601860        xercesc/internal/IANAEncodings.hpp \
    18611861        icxercesc/internal/IGXMLScanner.hpp \
    1862         xercesc/internal/MemoryManagerImpl.hpp \
     1862        icxercesc/internal/MemoryManagerImpl.hpp \
    18631863        icxercesc/internal/ReaderMgr.hpp \
    18641864        icxercesc/internal/SGXMLScanner.hpp \
     
    20642064        xercesc/util/XMLBigDecimal.hpp \
    20652065        xercesc/util/XMLBigInteger.hpp \
    2066         xercesc/util/XMLChar.hpp \
     2066        icxercesc/util/XMLChar.hpp \
    20672067        icxercesc/util/XMLChTranscoder.hpp \
    20682068        xercesc/util/XMLDateTime.hpp \
     
    21462146        xercesc/util/XMLBigDecimal.cpp \
    21472147        xercesc/util/XMLBigInteger.cpp \
    2148         xercesc/util/XMLChar.cpp \
     2148        icxercesc/util/XMLChar.cpp \
    21492149        icxercesc/util/XMLChTranscoder.cpp \
    21502150        xercesc/util/XMLDateTime.cpp \
     
    22522252        xercesc/validators/schema/SchemaAttDefList.hpp \
    22532253        xercesc/validators/schema/SchemaElementDecl.hpp \
    2254         xercesc/validators/schema/SchemaGrammar.hpp \
     2254        icxercesc/validators/schema/SchemaGrammar.hpp \
    22552255        xercesc/validators/schema/SchemaInfo.hpp \
    22562256        icxercesc/validators/schema/SchemaSymbols.hpp \
     
    23422342        xercesc/validators/schema/SchemaAttDefList.cpp \
    23432343        xercesc/validators/schema/SchemaElementDecl.cpp \
    2344         xercesc/validators/schema/SchemaGrammar.cpp \
     2344        icxercesc/validators/schema/SchemaGrammar.cpp \
    23452345        xercesc/validators/schema/SchemaInfo.cpp \
    23462346        icxercesc/validators/schema/SchemaSymbols.cpp \
     
    27042704xercesc/util/XMLBigInteger.lo: xercesc/util/$(am__dirstamp) \
    27052705        xercesc/util/$(DEPDIR)/$(am__dirstamp)
    2706 xercesc/util/XMLChar.lo: xercesc/util/$(am__dirstamp) \
    2707         xercesc/util/$(DEPDIR)/$(am__dirstamp)
     2706icxercesc/util/XMLChar.lo: icxercesc/util/$(am__dirstamp) \
     2707        icxercesc/util/$(DEPDIR)/$(am__dirstamp)
    27082708icxercesc/util/XMLChTranscoder.lo: icxercesc/util/$(am__dirstamp) \
    27092709        icxercesc/util/$(DEPDIR)/$(am__dirstamp)
     
    34343434        xercesc/validators/schema/$(am__dirstamp) \
    34353435        xercesc/validators/schema/$(DEPDIR)/$(am__dirstamp)
    3436 xercesc/validators/schema/SchemaGrammar.lo:  \
    3437         xercesc/validators/schema/$(am__dirstamp) \
    3438         xercesc/validators/schema/$(DEPDIR)/$(am__dirstamp)
     3436icxercesc/validators/schema/SchemaGrammar.lo:  \
     3437        icxercesc/validators/schema/$(am__dirstamp) \
     3438        icxercesc/validators/schema/$(DEPDIR)/$(am__dirstamp)
    34393439xercesc/validators/schema/SchemaInfo.lo:  \
    34403440        xercesc/validators/schema/$(am__dirstamp) \
     
    37223722        -rm -f icxercesc/util/XMLChTranscoder.$(OBJEXT)
    37233723        -rm -f icxercesc/util/XMLChTranscoder.lo
     3724        -rm -f icxercesc/util/XMLChar.$(OBJEXT)
     3725        -rm -f icxercesc/util/XMLChar.lo
    37243726        -rm -f icxercesc/util/XMLString.$(OBJEXT)
    37253727        -rm -f icxercesc/util/XMLString.lo
     
    37603762        -rm -f icxercesc/validators/schema/SchemaAttDef.$(OBJEXT)
    37613763        -rm -f icxercesc/validators/schema/SchemaAttDef.lo
     3764        -rm -f icxercesc/validators/schema/SchemaGrammar.$(OBJEXT)
     3765        -rm -f icxercesc/validators/schema/SchemaGrammar.lo
    37623766        -rm -f icxercesc/validators/schema/SchemaSymbols.$(OBJEXT)
    37633767        -rm -f icxercesc/validators/schema/SchemaSymbols.lo
     
    40764080        -rm -f xercesc/util/XMLBigInteger.$(OBJEXT)
    40774081        -rm -f xercesc/util/XMLBigInteger.lo
    4078         -rm -f xercesc/util/XMLChar.$(OBJEXT)
    4079         -rm -f xercesc/util/XMLChar.lo
    40804082        -rm -f xercesc/util/XMLDateTime.$(OBJEXT)
    40814083        -rm -f xercesc/util/XMLDateTime.lo
     
    42464248        -rm -f xercesc/validators/schema/SchemaElementDecl.$(OBJEXT)
    42474249        -rm -f xercesc/validators/schema/SchemaElementDecl.lo
    4248         -rm -f xercesc/validators/schema/SchemaGrammar.$(OBJEXT)
    4249         -rm -f xercesc/validators/schema/SchemaGrammar.lo
    42504250        -rm -f xercesc/validators/schema/SchemaInfo.$(OBJEXT)
    42514251        -rm -f xercesc/validators/schema/SchemaInfo.lo
     
    43384338@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/util/$(DEPDIR)/XMLASCIITranscoder.Plo@am__quote@
    43394339@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/util/$(DEPDIR)/XMLChTranscoder.Plo@am__quote@
     4340@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/util/$(DEPDIR)/XMLChar.Plo@am__quote@
    43404341@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/util/$(DEPDIR)/XMLString.Plo@am__quote@
    43414342@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/util/$(DEPDIR)/XMLUCS4Transcoder.Plo@am__quote@
     
    43584359@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/validators/schema/$(DEPDIR)/GeneralAttributeCheck.Plo@am__quote@
    43594360@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/validators/schema/$(DEPDIR)/SchemaAttDef.Plo@am__quote@
     4361@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/validators/schema/$(DEPDIR)/SchemaGrammar.Plo@am__quote@
    43604362@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/validators/schema/$(DEPDIR)/SchemaSymbols.Plo@am__quote@
    43614363@AMDEP_TRUE@@am__include@ @am__quote@icxercesc/validators/schema/$(DEPDIR)/SchemaValidator.Plo@am__quote@
     
    44954497@AMDEP_TRUE@@am__include@ @am__quote@xercesc/util/$(DEPDIR)/XMLBigDecimal.Plo@am__quote@
    44964498@AMDEP_TRUE@@am__include@ @am__quote@xercesc/util/$(DEPDIR)/XMLBigInteger.Plo@am__quote@
    4497 @AMDEP_TRUE@@am__include@ @am__quote@xercesc/util/$(DEPDIR)/XMLChar.Plo@am__quote@
    44984499@AMDEP_TRUE@@am__include@ @am__quote@xercesc/util/$(DEPDIR)/XMLDateTime.Plo@am__quote@
    44994500@AMDEP_TRUE@@am__include@ @am__quote@xercesc/util/$(DEPDIR)/XMLDouble.Plo@am__quote@
     
    46014602@AMDEP_TRUE@@am__include@ @am__quote@xercesc/validators/schema/$(DEPDIR)/SchemaAttDefList.Plo@am__quote@
    46024603@AMDEP_TRUE@@am__include@ @am__quote@xercesc/validators/schema/$(DEPDIR)/SchemaElementDecl.Plo@am__quote@
    4603 @AMDEP_TRUE@@am__include@ @am__quote@xercesc/validators/schema/$(DEPDIR)/SchemaGrammar.Plo@am__quote@
    46044604@AMDEP_TRUE@@am__include@ @am__quote@xercesc/validators/schema/$(DEPDIR)/SchemaInfo.Plo@am__quote@
    46054605@AMDEP_TRUE@@am__include@ @am__quote@xercesc/validators/schema/$(DEPDIR)/XMLSchemaDescriptionImpl.Plo@am__quote@
  • icXML/icXML-devel/src/icxercesc/framework/XMLAttr.cpp

    r2774 r3103  
    132132bool XMLAttr::isXMLNS() const
    133133{
    134     return (getURIId() == XMLNamespaceResolver::fEmptyUriId && XMLStringU::isXML(getQName())) || (getURIId() == XMLNamespaceResolver::fXMLNSUriId);
     134    // (getURIId() == XMLNamespaceResolver::fEmptyUriId && XMLStringU::isXML(getQName(), XMLString::stringLen(getQName()))) ||
     135    return (getURIId() == XMLNamespaceResolver::fXMLNSUriId);
    135136}
    136137
  • icXML/icXML-devel/src/icxercesc/framework/XMLBuffer.hpp

    r2807 r3103  
    8080        }
    8181        //@}
     82
     83
     84    inline const XMLCh & operator[](const XMLSize_t index) const
     85    {
     86        return fBuffer[index];
     87    }
     88
     89    inline XMLCh & operator[](const XMLSize_t index)
     90    {
     91        return fBuffer[index];
     92    }
    8293
    8394        // -----------------------------------------------------------------------
     
    117128        //  Buffer Management
    118129        // -----------------------------------------------------------------------
    119         void append(const XMLCh toAppend)
     130    inline void append(const XMLCh toAppend)
    120131        {
    121132                // Put in char and bump the index
    122                 if (fIndex == fCapacity)
     133        if (unlikely(fIndex == fCapacity))
     134        {
    123135                        ensureCapacity(1);
     136        }
    124137                fBuffer[fIndex++] = toAppend;
    125138        }
    126139
    127         void append (const XMLCh* const chars, const XMLSize_t count)
     140    inline void append (const XMLCh* const chars, const XMLSize_t count)
    128141        {
    129142                if (count)
    130143                {
    131                         if (fIndex + count >= fCapacity)
     144            if (unlikely(fIndex + count >= fCapacity))
    132145                        {
    133146                                ensureCapacity(count);
     
    136149                        fIndex += count;
    137150                }
    138                 else
    139                 {
    140                         append(chars);
    141                 }
    142         }
    143 
    144         void append (const XMLCh* const chars)
     151        }
     152
     153    inline void append (const XMLCh* const chars)
    145154        {
    146155                if (chars != 0 && *chars != 0)
     
    150159                        for (; chars[count]; count++ );
    151160
    152                         if (fIndex + count >= fCapacity)
     161            if (unlikely(fIndex + count >= fCapacity))
    153162                        {
    154163                                ensureCapacity(count);
     
    159168        }
    160169
    161         void set (const XMLCh* const chars, const XMLSize_t count)
     170    inline void set (const XMLCh* const chars, const XMLSize_t count)
    162171        {
    163172                fIndex = 0;
     
    171180                        append(chars);
    172181        }
     182
     183    void set (const XMLCh ch)
     184    {
     185        fBuffer[0] = ch;
     186        fIndex = 1;
     187    }
     188
     189    void fill(const XMLCh value, const XMLSize_t count)
     190    {
     191        if (unlikely(count >= fCapacity))
     192        {
     193            fIndex = 0;
     194            ensureCapacity(count - fCapacity);
     195        }
     196        Array<XMLCh>::set(fBuffer, value, count);
     197        fIndex = count;
     198    }
    173199
    174200        const XMLCh* getRawBuffer() const
  • icXML/icXML-devel/src/icxercesc/framework/XMLElementDecl.cpp

    r2721 r3103  
    5151XMLElementDecl::~XMLElementDecl()
    5252{
    53         delete fElementName;
     53    if (fElementName) delete fElementName;
    5454}
    5555
  • icXML/icXML-devel/src/icxercesc/framework/XMLElementDecl.hpp

    r2721 r3103  
    3535class XMLContentModel;
    3636struct XMLSymbol;
    37 template<class XMLScanner> class XMLParserImpl;
     37template<class XMLScannerType> class XMLParserImpl;
     38class DTDScanner;
    3839
    3940/**
     
    5455class XMLPARSER_EXPORT XMLElementDecl : public XSerializable, public XMemory
    5556{
    56         template<class XMLScanner> friend class XMLParserImpl;
     57    friend class XMLDocumentDisseminator;
     58    template<class XMLScannerType> friend class XMLGrammarValidator;
     59    friend class DTDScanner;
     60    friend class IGXMLScanner;
    5761
    5862public:
  • icXML/icXML-devel/src/icxercesc/framework/XMLGrammarPoolImpl.cpp

    r2721 r3103  
    2929#include <xercesc/validators/DTD/DTDGrammar.hpp>
    3030#include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp>
    31 #include <xercesc/validators/schema/SchemaGrammar.hpp>
     31#include <icxercesc/validators/schema/SchemaGrammar.hpp>
    3232#include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp>
    3333#include <xercesc/util/OutOfMemoryException.hpp>
  • icXML/icXML-devel/src/icxercesc/internal/DGXMLScanner.cpp

    r2721 r3103  
    3636#include <icxercesc/framework/XMLGrammarPool.hpp>
    3737#include <xercesc/framework/XMLDTDDescription.hpp>
    38 #include <xercesc/internal/EndOfEntityException.hpp>
    3938#include <icxercesc/validators/common/GrammarResolver.hpp>
    4039#include <xercesc/validators/DTD/DocTypeHandler.hpp>
     
    309308                        //  We could be at the end of X nested entities, each of which will
    310309                        //  generate an end of entity exception as we try to move forward.
    311                         try
    312                         {
    313                                 curToken = senseNextToken(orgReader);
    314                                 break;
    315                         }
    316                         catch(const EndOfEntityException& toCatch)
    317                         {
    318                                 // Send an end of entity reference event
    319                                 if (fDocHandler)
    320                                         fDocHandler->endEntityReference(toCatch.getEntity());
    321                         }
     310            curToken = senseNextToken(orgReader);
     311            break;
    322312                }
    323313
     
    500490        while (gotData)
    501491        {
    502                 try
    503                 {
    504                         while (gotData)
    505                         {
    506                                 //  Sense what the next top level token is. According to what
    507                                 //  this tells us, we will call something to handle that kind
    508                                 //  of thing.
    509                                 XMLSize_t orgReader;
    510                                 const XMLTokens curToken = senseNextToken(orgReader);
    511 
    512                                 //  Handle character data and end of file specially. Char data
    513                                 //  is not markup so we don't want to handle it in the loop
    514                                 //  below.
    515                                 if (curToken == Token_CharData)
    516                                 {
    517                                         //  Scan the character data and call appropriate events. Let
    518                                         //  him use our local character data buffer for efficiency.
    519                                         scanCharData(fCDataBuf);
    520                                         continue;
    521                                 }
    522                                 else if (curToken == Token_EOF)
    523                                 {
    524                                         //  The element stack better be empty at this point or we
    525                                         //  ended prematurely before all elements were closed.
    526                                         if (!fElemStack.isEmpty())
    527                                         {
    528                                                 const ElemStack::StackElem* topElem = fElemStack.popTop();
    529                                                 emitError
    530                                                 (
    531                                                         XMLErrs::EndedWithTagsOnStack
    532                                                         , topElem->fThisElement->getFullName()
    533                                                 );
    534                                         }
    535 
    536                                         // Its the end of file, so clear the got data flag
    537                                         gotData = false;
    538                                         continue;
    539                                 }
    540 
    541                                 // We are in some sort of markup now
    542                                 inMarkup = true;
    543 
    544                                 //  According to the token we got, call the appropriate
    545                                 //  scanning method.
    546                                 switch(curToken)
    547                                 {
    548                                         case Token_CData :
    549                                                 // Make sure we are within content
    550                                                 if (fElemStack.isEmpty())
    551                                                         emitError(XMLErrs::CDATAOutsideOfContent);
    552                                                 scanCDSection();
    553                                                 break;
    554 
    555                                         case Token_Comment :
    556                                                 scanComment();
    557                                                 break;
    558 
    559                                         case Token_EndTag :
    560                                                 scanEndTag(gotData);
    561                                                 break;
    562 
    563                                         case Token_PI :
    564                                                 scanPI();
    565                                                 break;
    566 
    567                                         case Token_StartTag :
    568                                                 if (fDoNamespaces)
    569                                                         scanStartTagNS(gotData);
    570                                                 else
    571                                                         scanStartTag(gotData);
    572                                                 break;
    573 
    574                                         default :
    575                                                 fReaderMgr.skipToChar(chOpenAngle);
    576                                                 break;
    577                                 }
    578 
    579                                 if (orgReader != fReaderMgr.getCurrentReaderNum())
    580                                         emitError(XMLErrs::PartialMarkupInEntity);
    581 
    582                                 // And we are back out of markup again
    583                                 inMarkup = false;
    584                         }
    585                 }
    586                 catch(const EndOfEntityException& toCatch)
    587                 {
    588                         //  If we were in some markup when this happened, then its a
    589                         //  partial markup error.
    590                         if (inMarkup)
    591                                 emitError(XMLErrs::PartialMarkupInEntity);
    592 
    593                         // Send an end of entity reference event
    594                         if (fDocHandler)
    595                                 fDocHandler->endEntityReference(toCatch.getEntity());
    596 
    597                         inMarkup = false;
    598                 }
     492        while (gotData)
     493        {
     494            //  Sense what the next top level token is. According to what
     495            //  this tells us, we will call something to handle that kind
     496            //  of thing.
     497            XMLSize_t orgReader;
     498            const XMLTokens curToken = senseNextToken(orgReader);
     499
     500            //  Handle character data and end of file specially. Char data
     501            //  is not markup so we don't want to handle it in the loop
     502            //  below.
     503            if (curToken == Token_CharData)
     504            {
     505                //  Scan the character data and call appropriate events. Let
     506                //  him use our local character data buffer for efficiency.
     507                scanCharData(fCDataBuf);
     508                continue;
     509            }
     510            else if (curToken == Token_EOF)
     511            {
     512                //  The element stack better be empty at this point or we
     513                //  ended prematurely before all elements were closed.
     514                if (!fElemStack.isEmpty())
     515                {
     516                    const ElemStack::StackElem* topElem = fElemStack.popTop();
     517                    emitError
     518                    (
     519                        XMLErrs::EndedWithTagsOnStack
     520                        , topElem->fThisElement->getFullName()
     521                    );
     522                }
     523
     524                // Its the end of file, so clear the got data flag
     525                gotData = false;
     526                continue;
     527            }
     528
     529            // We are in some sort of markup now
     530            inMarkup = true;
     531
     532            //  According to the token we got, call the appropriate
     533            //  scanning method.
     534            switch(curToken)
     535            {
     536                case Token_CData :
     537                    // Make sure we are within content
     538                    if (fElemStack.isEmpty())
     539                        emitError(XMLErrs::CDATAOutsideOfContent);
     540                    scanCDSection();
     541                    break;
     542
     543                case Token_Comment :
     544                    scanComment();
     545                    break;
     546
     547                case Token_EndTag :
     548                    scanEndTag(gotData);
     549                    break;
     550
     551                case Token_PI :
     552                    scanPI();
     553                    break;
     554
     555                case Token_StartTag :
     556                    if (fDoNamespaces)
     557                        scanStartTagNS(gotData);
     558                    else
     559                        scanStartTag(gotData);
     560                    break;
     561
     562                default :
     563                    fReaderMgr.skipToChar(chOpenAngle);
     564                    break;
     565            }
     566
     567            if (orgReader != fReaderMgr.getCurrentReaderNum())
     568                emitError(XMLErrs::PartialMarkupInEntity);
     569
     570            // And we are back out of markup again
     571            inMarkup = false;
     572        }
     573
    599574        }
    600575
     
    28582833        while (true)
    28592834        {
    2860         try
    2861         {
    28622835                while(true)
    28632836                {
     
    30192992                        }
    30202993                }
    3021         }
    3022         catch(const EndOfEntityException&)
    3023         {
    3024                 // Just eat it and continue.
    3025                 gotLeadingSurrogate = false;
    3026                 escaped = false;
    3027         }
    3028         }
     2994
    30292995        return true;
    30302996#endif
     
    32263192        while (notDone)
    32273193        {
    3228                 try
    3229                 {
     3194
    32303195                        while (true)
    32313196                        {
     
    33563321                                }
    33573322                        }
    3358                 }
    3359                 catch(const EndOfEntityException& toCatch)
    3360                 {
    3361                         //  Some entity ended, so we have to send any accumulated
    3362                         //  chars and send an end of entity event.
    3363                         sendCharData(toUse);
    3364                         gotLeadingSurrogate = false;
    3365 
    3366                         if (fDocHandler)
    3367                                 fDocHandler->endEntityReference(toCatch.getEntity());
    3368                 }
     3323
    33693324        }
    33703325
  • icXML/icXML-devel/src/icxercesc/internal/DGXMLScanner.hpp

    r2807 r3103  
    2828#include <xercesc/util/Hash2KeysSetOf.hpp>
    2929#include <xercesc/validators/common/Grammar.hpp>
     30#include <icxmlc/XMLSymbol.hpp>
     31#include <icxercesc/validators/DTD/DTDElementDecl.hpp>
     32#include <icxmlc/parsers/XMLDocumentAccumulator.hpp>
    3033#include <icxmlc/XMLConfig.hpp>
    3134
     
    4245class XMLPARSER_EXPORT DGXMLScanner : public XMLScanner
    4346{
     47    template<class DGXMLScanner> friend class XMLSchemaLoader;
     48
     49    typedef DTDElementDecl ElementDeclType;
     50
    4451public :
    4552        // -----------------------------------------------------------------------
     
    8794    //  XMLParser Callback Methods
    8895    // -----------------------------------------------------------------------
    89 #if 1
    90     IDISA_ALWAYS_INLINE
    91     void handleContent
    92     (
    93           const XMLCh     *                             content
    94         , const XMLSize_t                               length
    95     )
    96     {
    97 
    98     }
    99 
    100     IDISA_ALWAYS_INLINE
    101     XMLElementDecl * handleStartTag
    102     (
    103         XMLElementDecl * const                  element
     96
     97    IDISA_ALWAYS_INLINE
     98    void validateContent
     99    (
     100        const XMLCh       *             content
     101        , const XMLSize_t               contentLength
     102        , const bool                    doPSVI
     103        , const XMLContentFlag          flags
     104        , XMLDocumentAccumulator &      parser
     105        , const bool                    forceWrite = false
     106    )
     107    {
     108        DEPRECATED_FEATURE_IN_ICXML;
     109    }
     110
     111    IDISA_ALWAYS_INLINE
     112    void validateCDATA
     113    (
     114        const XMLCh       *             cdata
     115        , const XMLSize_t               length
     116        , XMLDocumentAccumulator &      parser
     117    )
     118    {
     119        DEPRECATED_FEATURE_IN_ICXML;
     120    }
     121
     122    IDISA_ALWAYS_INLINE
     123    XMLElementDecl & getElementDecl
     124    (
     125        XMLSymbol &                   element
     126        , const unsigned int            uriId
     127        , const bool                                    isRoot
     128        , const bool                    doPSVI
     129        , XMLDocumentAccumulator &      parser
     130    )
     131    {
     132        DEPRECATED_FEATURE_IN_ICXML;
     133    }
     134
     135    IDISA_ALWAYS_INLINE
     136    bool validateAttribute
     137    (
     138        const XMLElementDecl &          elemDecl
     139        , const XMLSize_t               elementCount
     140        , const XMLSymbol &             attribute
     141        , const unsigned int            uriId
     142        , const XMLCh *                 value
     143        , const XMLSize_t               length
     144        , const MarkupType              type
     145        , const Grammar::GrammarType    grammarType
     146        , const bool                    error
     147        , const bool                    doPSVI
     148        , XMLDocumentAccumulator &      parser
     149        , const bool                    write
     150    )
     151    {
     152        DEPRECATED_FEATURE_IN_ICXML;
     153    }
     154
     155    IDISA_ALWAYS_INLINE
     156    XMLSize_t postAttributeValidation
     157    (
     158        const XMLElementDecl &          elemDecl
     159        , const QName *                 elemName
     160        , const XMLSize_t               elementCount
     161        , const XMLSize_t                               attributeCount
     162        , const unsigned int            uriId
     163        , const bool                                    isRoot
     164        , const bool                                    isEmpty
     165        , const Grammar::GrammarType    grammarType
     166        , const bool                    doPSVI
     167        , XMLDocumentAccumulator &      parser
     168    )
     169    {
     170        DEPRECATED_FEATURE_IN_ICXML;
     171    }
     172
     173    IDISA_ALWAYS_INLINE
     174    void validateEndTag
     175    (
     176        XMLElementDecl &                element
     177        , const QName *                 elemName
    104178        , const unsigned int                    uriId
    105         , const XMLSize_t                               readerNum
    106179        , const bool                                    isRoot
    107180        , XMLElementDecl **                             children
    108181        , const XMLSize_t                               childCount
    109     )
    110     {
    111         return 0;
    112     }
    113 
    114     IDISA_ALWAYS_INLINE
    115     void handleEndTag
    116     (
    117         XMLElementDecl * const                  element
    118         , const unsigned int                    uriId
    119         , const XMLSize_t                               readerNum
    120         , const bool                                    isRoot
    121         , XMLElementDecl **                             children
    122         , const XMLSize_t                               childCount
    123     )
    124     {
    125 
    126     }
    127 #endif
     182        , const bool                    doPSVI
     183        , XMLDocumentAccumulator &      parser
     184    )
     185    {
     186        DEPRECATED_FEATURE_IN_ICXML;
     187    }
     188
     189    bool toCheckIdentityConstraint() const;
    128190
    129191private :
     
    244306}
    245307
     308inline bool DGXMLScanner::toCheckIdentityConstraint() const
     309{
     310    return 0;
     311}
     312
    246313XERCES_CPP_NAMESPACE_END
    247314
  • icXML/icXML-devel/src/icxercesc/internal/ElemStack.cpp

    r2807 r3103  
    2929#include <xercesc/validators/common/Grammar.hpp>
    3030#include <icxercesc/internal/ElemStack.hpp>
     31#include <icxmlc/XMLConfig.hpp>
    3132
    3233XERCES_CPP_NAMESPACE_BEGIN
     
    7071// ---------------------------------------------------------------------------
    7172
    72 XMLSize_t ElemStack::addLevel(XMLElementDecl* const toSet, const XMLSize_t readerNum)
     73XMLSize_t ElemStack::addLevel(XMLElementDecl* const toSet, const XMLSize_t /* readerNum */)
    7374{
    7475        // See if we need to expand the stack
     
    8485        // Set up the new top row
    8586        fStack[fStackTop]->fThisElement = toSet;
    86         fStack[fStackTop]->fReaderNum = readerNum;
    8787        fStack[fStackTop]->fValidationFlag = false;
    88         fStack[fStackTop]->fCommentOrPISeen = false;
    8988        fStack[fStackTop]->fCurrentScope = Grammar::TOP_LEVEL_SCOPE;
    9089        fStack[fStackTop]->fCurrentGrammar = 0;
     
    9796const ElemStack::StackElem* ElemStack::popTop()
    9897{
     98    #ifndef TEST_WELLFORMEDNESS_CHECKER
    9999        // Watch for an underflow error
    100100        if (!fStackTop)
    101101                ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_StackUnderflow, fMemoryManager);
     102    #endif
    102103
    103104        return fStack[--fStackTop];
     
    106107
    107108void
    108 ElemStack::setElement(XMLElementDecl* const toSet, const XMLSize_t readerNum)
    109 {
     109ElemStack::setElement(XMLElementDecl* const toSet, const XMLSize_t /* readerNum */)
     110{
     111    #ifndef TEST_WELLFORMEDNESS_CHECKER
    110112        if (!fStackTop)
    111113                ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);
    112 
     114    #endif
    113115        fStack[fStackTop - 1]->fThisElement = toSet;
    114         fStack[fStackTop - 1]->fReaderNum = readerNum;
    115116}
    116117
     
    121122const ElemStack::StackElem* ElemStack::topElement() const
    122123{
     124    #ifndef TEST_WELLFORMEDNESS_CHECKER
    123125        if (!fStackTop)
    124126        {
    125127                ThrowXMLwithMemMgr(EmptyStackException, XMLExcepts::ElemStack_EmptyStack, fMemoryManager);
    126128        }
     129    #endif
    127130        return fStack[fStackTop - 1];
    128131}
     
    166169// -----------------------------------------------------------------------------
    167170
    168 // ---------------------------------------------------------------------------
    169 //  WFElemStack: Constructors and Destructor
    170 // ---------------------------------------------------------------------------
    171171WFElemStack::WFElemStack(MemoryManager* const)
    172172{
     
    179179}
    180180
    181 // ---------------------------------------------------------------------------
    182 //  WFElemStack: Stack access
    183 // ---------------------------------------------------------------------------
    184181XMLSize_t WFElemStack::addLevel()
    185182{
     
    202199}
    203200
    204 // ---------------------------------------------------------------------------
    205 //  WFElemStack: Stack top access
    206 // ---------------------------------------------------------------------------
    207201const WFElemStack::StackElem* WFElemStack::topElement() const
    208202{
     
    210204}
    211205
    212 // ---------------------------------------------------------------------------
    213 //  WFElemStack: Prefix map methods
    214 // ---------------------------------------------------------------------------
     206
    215207void WFElemStack::addPrefix(const XMLCh* const, const unsigned int)
    216208{
     
    223215}
    224216
    225 // ---------------------------------------------------------------------------
    226 //  WFElemStack: Miscellaneous methods
    227 // ---------------------------------------------------------------------------
    228217void WFElemStack::reset(const unsigned int, const unsigned int, const unsigned int, const unsigned int)
    229218{
     
    231220}
    232221
    233 // ---------------------------------------------------------------------------
    234 //  WFElemStack: Private helpers
    235 // ---------------------------------------------------------------------------
    236222void WFElemStack::expandMap()
    237223{
     
    244230}
    245231
    246 // ---------------------------------------------------------------------------
    247 //  ElemStack: Prefix map methods
    248 // ---------------------------------------------------------------------------
    249232void ElemStack::addGlobalPrefix(const XMLCh* const, const unsigned int)
    250233{
     
    268251}
    269252
    270 // ---------------------------------------------------------------------------
    271 //  ElemStack: Miscellaneous methods
    272 // ---------------------------------------------------------------------------
    273253void ElemStack::reset(const unsigned int, const unsigned int, const unsigned int, const unsigned int)
    274254{
     
    281261}
    282262
    283 // ---------------------------------------------------------------------------
    284 //  ElemStack: Private helpers
    285 // ---------------------------------------------------------------------------
    286263
    287264XMLSize_t ElemStack::addChild(QName* const, const bool)
     
    290267}
    291268
    292 // ---------------------------------------------------------------------------
    293 //  ElemStack: Stack access
    294 // ---------------------------------------------------------------------------
    295269XMLSize_t ElemStack::addLevel()
    296270{
  • icXML/icXML-devel/src/icxercesc/internal/ElemStack.hpp

    r2721 r3103  
    101101        {
    102102                XMLElementDecl*     fThisElement;
    103                 XMLSize_t           fReaderNum;
    104 
    105                 #ifndef STORE_CHILDREN_INFORMATION_IN_PARSER
    106                 // TODO: it may be possible to remove all this child code from the elem stack and instead
    107                 // store it within the XMLParser
    108                 XMLSize_t           fChildCapacity;
    109                 XMLSize_t           fChildCount;
    110                 QName**             fChildren;
    111                 #endif
    112 
    113103                bool                fValidationFlag;
    114                 bool                fCommentOrPISeen;
    115104                unsigned int        fCurrentScope;
    116 
    117105                Grammar*            fCurrentGrammar;
    118                 #ifndef PERFORM_ELEMENT_STACK_MATCHING_IN_PARSER
    119                 const XMLCh *       fSchemaElemName;
    120                 #endif
    121106        };
    122107
     
    270255}
    271256
    272 inline bool ElemStack::getCommentOrPISeen() const
    273 {
    274         return fStack[fStackTop-1]->fCommentOrPISeen;
    275 }
    276 
    277 inline void ElemStack::setCommentOrPISeen()
    278 {
    279         fStack[fStackTop-1]->fCommentOrPISeen = true;
    280 }
    281 
    282257inline void ElemStack::setCurrentSchemaElemName(const XMLCh * const schemaElemName)
    283258{
     
    365340{
    366341        DEPRECATED_FEATURE_IN_ICXML;
     342}
     343
     344
     345inline bool ElemStack::getCommentOrPISeen() const
     346{
     347    DEPRECATED_FEATURE_IN_ICXML;
     348}
     349
     350inline void ElemStack::setCommentOrPISeen()
     351{
     352    DEPRECATED_FEATURE_IN_ICXML;
    367353}
    368354
     
    407393                int                 fTopPrefix;
    408394                unsigned int        fCurrentURI;
    409                 unsigned int        fReaderNum;
    410395                unsigned int        fElemMaxLength;
    411396                XMLCh*              fThisElement;
  • icXML/icXML-devel/src/icxercesc/internal/IGXMLScanner.cpp

    r2807 r3103  
    3030#include <xercesc/framework/XMLEntityHandler.hpp>
    3131#include <xercesc/framework/XMLPScanToken.hpp>
    32 #include <xercesc/internal/EndOfEntityException.hpp>
    3332#include <xercesc/framework/MemoryManager.hpp>
    3433#include <icxercesc/framework/XMLGrammarPool.hpp>
     
    415414        delete fPSVIAttrList;
    416415        delete fPSVIElement;
    417         delete fErrorStack;
     416    delete fErrorStack;
    418417        delete fSchemaInfoList;
    419418        delete fCachedSchemaInfoList;
     
    495494    rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
    496495    rootDecl->setExternalElemDeclaration(true);
    497     if(!fUseCachedGrammar)
     496    if (!fUseCachedGrammar)
    498497    {
    499498        fGrammar->putElemDecl(rootDecl);
     
    615614        }
    616615
     616        fHasInternalOrExternalDTD = true;
     617
    617618        //  Do a sanity check that some expanded PE did not propogate out of
    618619        //  the doctype. This could happen if it was terminated early by bad
     
    626627        }
    627628
    628         fReaderMgr.skipPastSpaces();
     629        fReaderMgr.skipPastSpaces();       
    629630    }
    630631
     
    749750            // Tell it its not in an include section
    750751            dtdScanner.scanExtSubsetDecl(false, true);
     752
     753            fHasInternalOrExternalDTD = true;
    751754        }
    752755    }
     
    10441047// ---------------------------------------------------------------------------
    10451048
    1046 void IGXMLScanner::endElementPSVI(SchemaElementDecl* const elemDecl,
    1047                                                                   DatatypeValidator* const memberDV)
    1048 {
    1049         PSVIElement::ASSESSMENT_TYPE validationAttempted;
     1049bool IGXMLScanner::checkNamespaceAttribute(const XMLSymbol & attribute, const XMLCh * value, bool declared, DatatypeValidator * & attrValidator)
     1050{
     1051    bool validate = fValidate & declared;
     1052    bool tokenize = false;
     1053
     1054    if (likely(attribute.isXMLNS()))
     1055    {
     1056        attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYURI);
     1057        return 1;
     1058    }
     1059    else // if (isXSI)
     1060    {
     1061        const gid_t localPartId = attribute.getLocalPartId();
     1062
     1063        switch (localPartId)
     1064        {
     1065            case XMLSymbolTable::Type:
     1066                attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_QNAME);
     1067                break;
     1068            case XMLSymbolTable::Nil:
     1069                attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_BOOLEAN);
     1070                break;
     1071            case XMLSymbolTable::SchemaLocation:
     1072                tokenize = true;
     1073            case XMLSymbolTable::NoNamespaceSchemaLocation:
     1074                attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYURI);
     1075                // these values ought to be validated but the authors of Xerces reported a performance degradation of ~4%?
     1076                // they opted to disable validation with the intention of doing a performance assessment of the anyuri datatype.
     1077                break;
     1078            default:
     1079                return 0; // bound to the xsi namespace but is not one of the predefined xsi attributes
     1080        }
     1081    }
     1082
     1083    if (validate && attrValidator)
     1084    {
     1085        ValidationContext* const theContext = getValidationContext();
     1086
     1087        if (theContext)
     1088        {
     1089            try
     1090            {
     1091                if (tokenize)
     1092                {
     1093                    XMLStringTokenizer tokenizer(value, fMemoryManager);
     1094                    while (tokenizer.hasMoreTokens())
     1095                    {
     1096                        attrValidator->validate
     1097                        (
     1098                            tokenizer.nextToken(),
     1099                            theContext,
     1100                            fMemoryManager
     1101                        );
     1102                    }
     1103                }
     1104                else
     1105                {
     1106                    attrValidator->validate
     1107                    (
     1108                        value,
     1109                        theContext,
     1110                        fMemoryManager
     1111                    );
     1112                }
     1113            }
     1114            catch (const XMLException& idve)
     1115            {
     1116                fValidator->emitError(XMLValid::DatatypeError, idve.getCode(), idve.getMessage());
     1117            }
     1118        }
     1119    }
     1120
     1121    return 1;
     1122}
     1123
     1124bool IGXMLScanner::tokenizeAttributeValue
     1125(
     1126    const XMLCh * const             value
     1127    , const XMLSize_t               length
     1128    , XMLBuffer &                   toFill
     1129)
     1130{
     1131    DEBUG_GRAMMAR_MESSAGE("tokenizeAttributeValue(" << value << ',' << length << ')')
     1132
     1133    // TODO: this is a very poor method of handling tokenization. It assumes that the value was improperly tokenized when
     1134    // in all likelyhood the document is valid.
     1135
     1136    toFill.reset();
     1137
     1138    if (likely(length > 0))
     1139    {
     1140        // any non-space whitespace characters within the value must have been inserted by character reference expansion.
     1141        // only iterate through actual spaces.
     1142        XMLChIterator<chSpace> itr(value, length);
     1143        // find the very first non-whitespace character.
     1144        if (itr.nextc())
     1145        {
     1146            for (;;)
     1147            {
     1148                size_t pos = itr.pos();
     1149                // are there any whitespace characters after the first whitespace character?
     1150                if (!itr.next())
     1151                {
     1152                    toFill.append(&value[pos], length - pos);
     1153                    break;
     1154                }
     1155                toFill.append(&value[pos], itr.pos() - pos);
     1156
     1157                // get the position of the next non-whitespace character
     1158                if (!itr.nextc())
     1159                {
     1160                    break;
     1161                }
     1162                // if there is one, then add a space between the tokens
     1163                toFill.append(chSpace);
     1164            }
     1165        }
     1166    }
     1167
     1168    return (toFill.getLen() != length);
     1169}
     1170
     1171void IGXMLScanner::endElementPSVI(SchemaElementDecl* const elemDecl, DatatypeValidator * const memberDV)
     1172{
     1173#if 0
     1174    PSVIElement::ASSESSMENT_TYPE validationAttempted;
    10501175        PSVIElement::VALIDITY_STATE validity = PSVIElement::VALIDITY_NOTKNOWN;
    10511176
    10521177        if (fPSVIElemContext.fElemDepth > fPSVIElemContext.fFullValidationDepth)
     1178    {
    10531179                validationAttempted = PSVIElement::VALIDATION_FULL;
     1180    }
    10541181        else if (fPSVIElemContext.fElemDepth > fPSVIElemContext.fNoneValidationDepth)
     1182    {
    10551183                validationAttempted = PSVIElement::VALIDATION_NONE;
     1184    }
    10561185        else
    10571186        {
    10581187                validationAttempted  = PSVIElement::VALIDATION_PARTIAL;
    1059                                 fPSVIElemContext.fFullValidationDepth =
    1060                         fPSVIElemContext.fNoneValidationDepth = fPSVIElemContext.fElemDepth - 1;
     1188        fPSVIElemContext.fFullValidationDepth = fPSVIElemContext.fNoneValidationDepth = fPSVIElemContext.fElemDepth - 1;
    10611189        }
    10621190
    10631191        if (fValidate && elemDecl->isDeclared())
    10641192        {
    1065                 validity = (fPSVIElemContext.fErrorOccurred)
    1066                         ? PSVIElement::VALIDITY_INVALID : PSVIElement::VALIDITY_VALID;
     1193        validity = (fPSVIElemContext.fErrorOccurred) ? PSVIElement::VALIDITY_INVALID : PSVIElement::VALIDITY_VALID;
    10671194        }
    10681195
     
    10731200                typeDef = (XSTypeDefinition*) fModel->getXSObject(fPSVIElemContext.fCurrentTypeInfo);
    10741201                SchemaElementDecl::ModelTypes modelType = (SchemaElementDecl::ModelTypes)fPSVIElemContext.fCurrentTypeInfo->getContentType();
    1075                 isMixed = (modelType == SchemaElementDecl::Mixed_Simple
    1076                                 || modelType == SchemaElementDecl::Mixed_Complex);
     1202        isMixed = (modelType == SchemaElementDecl::Mixed_Simple || modelType == SchemaElementDecl::Mixed_Complex);
    10771203        }
    10781204        else if (fPSVIElemContext.fCurrentDV)
     1205    {
    10791206                typeDef = (XSTypeDefinition*) fModel->getXSObject(fPSVIElemContext.fCurrentDV);
     1207    }
    10801208
    10811209        XMLCh* canonicalValue = 0;
    1082         if (fPSVIElemContext.fNormalizedValue && !isMixed &&
    1083                         validity == PSVIElement::VALIDITY_VALID)
     1210    if (fPSVIElemContext.fNormalizedValue && !isMixed && validity == PSVIElement::VALIDITY_VALID)
    10841211        {
    10851212                if (memberDV)
     
    10951222                , fRootElemName
    10961223                , fPSVIElemContext.fIsSpecified
    1097                 , (elemDecl->isDeclared())
    1098                         ? (XSElementDeclaration*) fModel->getXSObject(elemDecl) : 0
     1224        , (elemDecl->isDeclared()) ? (XSElementDeclaration*) fModel->getXSObject(elemDecl) : 0
    10991225                , typeDef
    11001226                , (memberDV) ? (XSSimpleTypeDefinition*) fModel->getXSObject(memberDV) : 0
     
    11141240        // decrease element depth
    11151241        fPSVIElemContext.fElemDepth--;
     1242#endif
    11161243}
    11171244
     
    11281255}
    11291256
    1130 #ifdef __GNUC__
    1131 #warning "note: currently we cannot trigger the fDocHandler->startEntityReference callback"
    1132 #endif
    1133 
    1134 bool IGXMLScanner::expandEntityRef
     1257bool IGXMLScanner::expandEntityReference
    11351258(
    1136         const XMLCh *                   entityRef
    1137         , const bool                    inAttributeValue
    1138         , XMLBuffer &                   toFill
     1259    const XMLCh *                   entityReference
     1260    , const XMLSize_t               /* length */
     1261    , const bool                    inAttributeValue
     1262    , XMLBuffer &                   toFill
     1263    , bool      &                   isPredefined
     1264    , XMLReader::XMLVersion &       version
     1265    , XMLFileLoc &                  line
     1266    , XMLFileLoc &                  column
    11391267)
    11401268{
    1141     assert (entityRef != 0);
    1142 
    1143         //  If the next char is a pound, then its a character reference...
    1144         if (*entityRef == chPound)
    1145         {
    1146                 if (inAttributeValue)
    1147                 {
    1148                         XMLCh charVal[2];
    1149                         XMLSize_t len = expandCharRef(entityRef + 1, &charVal[0], chNull);
    1150 
    1151                         if (likely(len == 1))
    1152                         {
    1153                                 // if we're in an attribute, add it but tag it with an escape character so we do not accidently
    1154                                 // normalize it...
    1155                                 toFill.append(0xFFFF);
    1156                                 toFill.append(charVal[0]);
    1157                         }
    1158                         else if (len == 2)
    1159                         {
    1160                                 toFill.append(charVal[0]);
    1161                                 toFill.append(charVal[1]);
    1162                         }
    1163                 }
    1164                 else
    1165                 {
    1166                         // ...just bypass it for now
    1167                         toFill.append(chAmpersand);
    1168                         toFill.append(entityRef);
    1169                         toFill.append(chSemiColon);
    1170                 }
    1171                 return 1;
    1172         }
    1173 
    1174         // here's where we need to check if there's a SecurityManager,
     1269    // here's where we need to check if there's a SecurityManager,
    11751270        // how many entity references we've had
    1176         if (fSecurityManager != 0 && ++fEntityExpansionCount > fEntityExpansionLimit)
     1271    if (fSecurityManager && ++fEntityExpansionCount > fEntityExpansionLimit)
    11771272        {
    11781273                XMLCh expLimStr[32];
     
    11881283
    11891284        // Look up the name in the general entity pool
    1190         XMLEntityDecl * decl = fDTDGrammar->getEntityDecl(entityRef);
     1285    XMLEntityDecl * decl = fDTDGrammar->getEntityDecl(entityReference);
    11911286        InputSource * srcUsed;
    11921287
     
    11961291                // XML 1.0 Section 4.1
    11971292                // Well-formedness Constraint for entity not found:
    1198                 //   In a document without any DTD, a document with only an internal DTD subset which contains no parameter entity references,
     1293        //   In a document without any DTD, a document with only an internal DTD subset that contains no parameter entity references,
    11991294                //      or a document with "standalone='yes'", for an entity reference that does not occur within the external subset
    12001295                //      or a parameter entity
     
    12031298                if (fStandalone || fHasNoDTD)
    12041299                {
    1205                         emitError(XMLErrs::EntityNotFound, entityRef);
     1300            emitError(XMLErrs::EntityNotFound, entityReference);
    12061301                }
    12071302                else if (fValidate)
    12081303                {
    1209                         fValidator->emitError(XMLValid::VC_EntityNotFound, entityRef);
     1304            fValidator->emitError(XMLValid::VC_EntityNotFound, entityReference);
    12101305                }
    12111306                return 0;
     
    12171312        if (unlikely(fStandalone && !decl->getDeclaredInIntSubset()))
    12181313        {
    1219                 emitError(XMLErrs::IllegalRefInStandalone, entityRef);
     1314        emitError(XMLErrs::IllegalRefInStandalone, entityReference);
    12201315        }
    12211316
     
    12241319        if (unlikely(decl->isExternal()))
    12251320        {
     1321        if (unlikely(inAttributeValue))
     1322        {
     1323            emitError(XMLErrs::NoExtRefsInAttValue);
     1324            return 0;
     1325        }
     1326
    12261327                // If its unparsed, then its not valid here
    12271328                if (unlikely(decl->isUnparsed()))
    12281329                {
    1229                         emitError(XMLErrs::NoUnparsedEntityRefs, entityRef);
     1330            emitError(XMLErrs::NoUnparsedEntityRefs, entityReference);
    12301331                        return 0;
    12311332                }
     
    12571358                }
    12581359
    1259                 // Push the reader. If its a recursive expansion, then emit an error
    1260                 // and return an failure.
    1261                 if (!fReaderMgr.pushReader(reader, decl))
    1262                 {
    1263                         emitError(XMLErrs::RecursiveEntity, decl->getName());
    1264                         return 0;
    1265                 }
    1266 
    1267                 // If it starts with the XML string, then parse a text decl
    1268                 if (checkXMLDecl(true))
    1269                 {
    1270                         scanXMLDecl(Decl_Text);
    1271                 }
    1272 
    1273                 XMLCh nextCh;
    1274 
    1275                 // now expand the value out
    1276                 while (fReaderMgr.getNextCharOfCurrentReader(nextCh))
    1277                 {
    1278                         if (unlikely(nextCh == chAmpersand))
    1279                         {
    1280                                 XMLBuffer entity(1023, fMemoryManager);
    1281                                 while (fReaderMgr.getNextCharOfCurrentReader(nextCh))
    1282                                 {
    1283                                         if (unlikely(nextCh == chSemiColon))
    1284                                         {
    1285                                                 if (!expandEntityRef(entity.getRawBuffer(), inAttributeValue, toFill))
    1286                                                 {
    1287                                                         return 0;
    1288                                                 }
    1289                                                 break;
    1290                                         }
    1291                                         entity.append(nextCh);
    1292                                 }
    1293                         }
    1294                         else
    1295                         {
    1296                                 // add it to the buffer
    1297                                 toFill.append(nextCh);
    1298                         }
    1299                 }
     1360        fReaderMgr.pushReader(reader, decl);
     1361
     1362        // If it starts with the XML string, then parse a text decl
     1363        if (checkXMLDecl(true))
     1364        {
     1365            scanXMLDecl(Decl_Text);
     1366        }
     1367
     1368        reader = fReaderMgr.getCurrentReader();
     1369        // get the line, column and version information from the Reader; one of these will likely
     1370        // differ from the source document.
     1371        line = reader->getLineNumber();
     1372        column = reader->getColumnNumber();
     1373        version = reader->getXMLVersion();       
     1374        // now obtain the entire the value
     1375        reader->fill(toFill);
     1376
     1377        fReaderMgr.popReader();
    13001378        }
    13011379        else // internal entity
    13021380        {
    1303                 const XMLCh * entityValue = decl->getValue();
     1381        version = this->getXMLVersion();
    13041382
    13051383                //  If its a predefined entity reference...
    13061384                if (decl->getIsSpecialChar())
    13071385                {
    1308                         if (inAttributeValue)
    1309                         {
    1310                                 // and we're in an attribute, add it directly
    1311                                 toFill.append(decl->getValue()[0]);
    1312                         }
    1313                         else
    1314                         {
    1315                                 // else just bypass it for now
    1316                                 toFill.append(chAmpersand);
    1317                                 toFill.append(entityRef);
    1318                                 toFill.append(chSemiColon);
    1319                         }
    1320                         return 1;
    1321                 }
    1322 
    1323                 XMLSize_t length;
    1324 
    1325                 // now expand the value out
    1326                 for (;;)
    1327                 {
    1328                         // is there another entity in this entity value?
    1329                         length = XMLStringU::stringLenOrIndexOf<chAmpersand>(entityValue);
    1330 
    1331                         if (likely(length != 0))
    1332                         {
    1333                                 toFill.append(entityValue, length);
    1334                         }
    1335 
    1336                         if (likely(entityValue[length] == 0))
    1337                         {
    1338                                 // nope; so we're done!
    1339                                 break;
    1340                         }
    1341                         entityValue += length + 1;
    1342 
    1343                         length = XMLStringU::stringLenOrIndexOf<chSemiColon>(entityValue);
    1344 
    1345                         if (unlikely(entityValue[length] == 0))
    1346                         {
    1347                                 return 0;
    1348                         }
    1349 
    1350                         const_cast<XMLCh*>(entityValue)[length] = chNull;
    1351                         const bool expandedSuccessfully = expandEntityRef(entityValue, inAttributeValue, toFill);
    1352                         const_cast<XMLCh*>(entityValue)[length] = chSemiColon;
    1353 
    1354                         if (!expandedSuccessfully)
    1355                         {
    1356                                 return 0;
    1357                         }
    1358 
    1359                         entityValue += length + 1;
    1360                 }
    1361         }
    1362 
     1386            toFill.set(decl->getValue()[0]);
     1387            isPredefined = 1;
     1388                }
     1389        else
     1390        {
     1391            toFill.set(decl->getValue(), decl->getValueLen());
     1392        }
     1393        }
    13631394        return 1;
    13641395}
  • icXML/icXML-devel/src/icxercesc/internal/IGXMLScanner.hpp

    r2807 r3103  
    3535#include <xercesc/validators/DTD/DTDGrammar.hpp>
    3636#include <icxercesc/validators/DTD/DTDValidator.hpp>
    37 #include <xercesc/validators/schema/SchemaGrammar.hpp>
     37#include <icxercesc/validators/schema/SchemaGrammar.hpp>
    3838#include <icxercesc/validators/schema/SchemaValidator.hpp>
    39 
     39#include <xercesc/validators/schema/SchemaAttDefList.hpp>
    4040#include <xercesc/framework/psvi/PSVIAttributeList.hpp>
    4141#include <xercesc/framework/psvi/PSVIElement.hpp>
    4242
     43#include <icxercesc/validators/schema/SubstitutionGroupComparator.hpp>
     44#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>
     45
    4346#include <xercesc/framework/psvi/PSVIHandler.hpp>
    4447#include <xercesc/validators/schema/identity/IdentityConstraintHandler.hpp>
    4548
    4649#include <xercesc/util/XMLStringTokenizer.hpp>
    47 
    4850#include <icxmlc/XMLGrammarResolver.hpp>
     51#include <icxmlc/XMLSymbolTable.hpp>
     52#include <icxmlc/XMLParserImpl.hpp>
     53#include <icxmlc/XMLParserDefs.hpp>
     54#include <icxmlc/parsers/XMLDocumentAccumulator.hpp>
     55#include <icxmlc/XMLConfig.hpp>
    4956
    5057XERCES_CPP_NAMESPACE_BEGIN
     
    6168class PSVIAttributeList;
    6269class PSVIElement;
     70template<class ScannerType> class XMLGrammarValidator;
    6371
    6472// TODO: remove fValidator from this class; use ONLY fSchemaValidator or fDTDValidator directly
     
    7280{
    7381        template<class IGXMLScanner> friend class XMLParserImpl;
     82    template<class IGXMLScanner> friend class XMLGrammarValidator;
     83    template<class IGXMLScanner> friend class XMLSchemaLoader;
     84
     85    typedef XMLElementDecl ElementDeclType;
    7486
    7587public :
     
    121133
    122134    IDISA_ALWAYS_INLINE
    123     void handleContent
     135    void validateContent
    124136        (
    125                   const XMLCh     *       content
    126         , const XMLSize_t         length
     137        const XMLCh *                   content
     138        , XMLSize_t                     length
     139        , const bool                    doPSVI
     140        , const XMLContentFlag          flags
     141        , XMLDocumentAccumulator &      parser
     142        , const bool                    forceWrite
    127143        );
    128144
    129145    IDISA_ALWAYS_INLINE
    130     void handleCDATA
     146    void validateCDATA
    131147    (
    132         const XMLCh       * cdata
    133         , const XMLSize_t   length
     148        const XMLCh       *             cdata
     149        , const XMLSize_t               length
     150        , XMLDocumentAccumulator &      parser
    134151    );
    135152
     153    /// START / EMPTY TAG VALIDATION
     154
    136155    IDISA_ALWAYS_INLINE
    137     XMLElementDecl * handleStartTag
     156    XMLElementDecl & getElementDecl
     157    (
     158          XMLSymbol &                   element
     159        , unsigned int &                uriId
     160        , const bool                                    isRoot
     161        , const bool                    doPSVI
     162        , XMLDocumentAccumulator &      parser
     163    );
     164
     165    IDISA_ALWAYS_INLINE
     166    bool validateAttribute
     167    (
     168          XMLElementDecl &              elemDecl       
     169        , const XMLSize_t               elementCount
     170        , const XMLSymbol &             attribute
     171        , const unsigned int            uriId
     172        , const XMLCh *                 value
     173        , XMLSize_t                     length
     174        , const MarkupType              type
     175        , const Grammar::GrammarType    grammarType
     176        , const bool                    doPSVI
     177        , XMLDocumentAccumulator &      parser
     178        , const bool                    write
     179    );
     180
     181    IDISA_ALWAYS_INLINE
     182    XMLSize_t postAttributeValidation
     183    (
     184        XMLElementDecl &                elemDecl
     185        , const QName *                 elemName
     186        , const XMLSize_t               elementCount
     187        , XMLSize_t                     attributeCount
     188        , const unsigned int            uriId
     189        , const bool                    isRoot
     190        , const bool                    isEmpty
     191        , const Grammar::GrammarType    grammarType
     192        , const bool                    doPSVI
     193        , XMLDocumentAccumulator &      parser
     194    );
     195
     196
     197    IDISA_ALWAYS_INLINE
     198    void validateEndTag
    138199        (
    139                   const XMLSymbol * const               element
    140                 , const XMLAttributeList &              attributeList
    141                 , XMLSize_t                                             attributeCount
    142                 , const bool                                    isRoot
    143                 , const bool                                    isEmpty
    144                 , const XMLSize_t                               readerNum
    145         );
    146 
    147     IDISA_ALWAYS_INLINE
    148     void handleEndTag
    149         (
    150                   XMLElementDecl * const                element
     200        XMLElementDecl &                element
     201        , const QName *                 elemName
    151202                , const unsigned int                    uriId
    152                 , const XMLSize_t                               readerNum
    153203                , const bool                                    isRoot
    154204                , XMLElementDecl **                             children
    155                 , const XMLSize_t                               childCount
     205        , const XMLSize_t                               childCount
     206        , const bool                    doPSVI
     207        , XMLDocumentAccumulator &      parser
    156208        );
    157209
     
    162214        void setXsiType
    163215        (
    164                 const XMLCh *                           value
    165                 , const XMLSize_t                       length
     216        const XMLCh *                           prefix
     217        , const XMLCh *             localPart
     218        , const unsigned int        uriId
    166219        );
    167220
     
    173226        );
    174227
    175         virtual bool expandEntityRef
    176         (
    177                 const XMLCh *           entityRef
    178                 , const bool            inAttVal
    179                 , XMLBuffer &           toFill
    180         );
     228    inline bool preValidateDefaultAttribute(const QName & element, const QName & attribute, const bool isExternal) const;
     229
     230    virtual bool expandEntityReference
     231    (
     232        const XMLCh *                   entityRef
     233        , const XMLSize_t               length
     234        , const bool                    inAttributeValue
     235        , XMLBuffer &                   toFill
     236        , bool      &                   isPredefined       
     237        , XMLReader::XMLVersion &       version
     238        , XMLFileLoc &                  line
     239        , XMLFileLoc &                  column
     240    );
    181241
    182242        virtual const DTDGrammar * getDTDGrammar() const
     
    185245        }
    186246
     247    IDISA_ALWAYS_INLINE
     248    Grammar::GrammarType getGrammarType() const
     249    {
     250        return fGrammarType;
     251    }
    187252
    188253protected:
     
    216281                                                                                ,const XMLCh* const pubId);
    217282
    218         inline
    219         XMLAttDefList & getAttDefList( bool              isSchemaGrammar
    220                                                                  , ComplexTypeInfo*  currType
    221                                                                  , XMLElementDecl*   elemDecl );
    222 
    223283        // -----------------------------------------------------------------------
    224284        //  Private helper methods
    225285        // -----------------------------------------------------------------------
    226         void commonInit();
     286    void commonInit();
     287
    227288        void cleanUp();
    228289
     290    bool checkNamespaceAttribute(const XMLSymbol & attribute, const XMLCh * value, const bool declared, DatatypeValidator * & attrValidator);
     291
     292    bool tokenizeAttributeValue(const XMLCh * const value, const XMLSize_t length, XMLBuffer & toFill);
     293
     294    IDISA_ALWAYS_INLINE
     295    XMLElementDecl * findElementDecl(XMLSymbol & element, unsigned int uriId, unsigned int scope, Grammar * grammar);
     296
     297    inline unsigned int getGrammarNamespaceId();
     298
    229299        inline bool switchGrammar(const unsigned int uriId);
    230300
    231301        inline bool switchGrammar(const unsigned int uriId, const XMLCh* const newGrammarNameSpace);
    232302
    233         void updateNSMap
    234         (
    235                 const   XMLCh* const    attrName
    236                 , const XMLCh* const    attrValue
    237                 , const int             colonPosition
    238         );
    239 
    240         void updateNSMap
    241         (
    242                 const   QName* const   attrName
    243                 , const XMLCh* const   attrValue
    244         );
    245 
    246303        void parseSchemaLocation(const XMLCh* const schemaLocationStr, const XMLSize_t schemaLocationStrLen, bool ignoreLoadSchema = false);
    247304
     
    252309        inline bool setCurrentGrammar(Grammar * tempGrammar);
    253310
    254 //      /// @@ DEPRECATED @@
    255 //      bool laxElementValidation(QName* element, ContentLeafNameTypeVector* cv,
    256 //                                                        const XMLContentModel* const cm,
    257 //                                                        const XMLSize_t parentElemDepth);
    258 
    259         bool laxElementValidation(const QName* element, const ContentLeafNameTypeVector* cv,
    260                                                           const XMLContentModel* const cm,
    261                                                           const XMLSize_t parentElemDepth);
     311    inline void endElementPSVI(SchemaElementDecl & elemDecl, DatatypeValidator * const memberDV, XMLDocumentAccumulator & parser);
     312
     313    IDISA_ALWAYS_INLINE
     314    bool laxElementValidation
     315    (
     316        const QName *                           element
     317        , const unsigned int                    uriId
     318        , const ContentLeafNameTypeVector *     cv
     319        , const XMLContentModel* const          cm
     320        , const XMLSize_t                       parentElemDepth
     321    );
    262322
    263323        bool anyAttributeValidation(SchemaAttDef* attWildCard,
     
    268328        void resizeElemState();
    269329
    270         IDISA_ALWAYS_INLINE
    271         const XMLCh * normalizeByAttDef(SchemaAttDef* attDef, const XMLCh * value, const bool writeValue);
    272 
    273     IDISA_ALWAYS_INLINE
    274     void validateAttValue(XMLElementDecl * elemDecl, XMLAttDef * attDef, const XMLCh * value, DatatypeValidator *& validator, PSVIItem::VALIDITY_STATE & attrValid, XMLAttDef::AttTypes & attType);
    275330
    276331    IDISA_ALWAYS_INLINE
     
    300355        //  PSVI handling methods
    301356        // -----------------------------------------------------------------------
    302         void endElementPSVI(SchemaElementDecl* const elemDecl,
    303                                                 DatatypeValidator* const memberDV);
     357    void endElementPSVI(SchemaElementDecl* const elemDecl, DatatypeValidator* const memberDV);
     358
    304359        void resetPSVIElemContext();
    305360
     
    307362        //  DEPRECATED PRIVATE METHODS; KEPT FOR DLL COMPATIBILITY
    308363        // -----------------------------------------------------------------------
    309         bool basicAttrValueScan
    310         (
    311                 const   XMLCh* const    attrName
    312                 ,       XMLBuffer&      toFill
    313         );
    314         XMLSize_t rawAttrScan
    315         (
    316                 const   XMLCh* const                elemName
    317                 ,       RefVectorOf<KVStringPair>&  toFill
    318                 ,       bool&                       isEmpty
    319         );
    320         bool scanAttValue
    321         (
    322                 const   XMLAttDef* const    attDef
    323                 , const   XMLCh* const      attrName
    324                 ,       XMLBuffer&          toFill
    325         );
    326 
    327         XMLSize_t buildAttList
    328         (
    329                 const   RefVectorOf<KVStringPair>&  providedAttrs
    330                 , const XMLSize_t                   attCount
    331                 ,       XMLElementDecl*             elemDecl
    332                 ,       RefVectorOf<XMLAttr>&       toFill
    333         );
    334 
    335         void updateNSMap
    336         (
    337                 const   XMLCh* const    attrName
    338                 , const XMLCh* const    attrValue
    339         );
    340 
    341         bool normalizeAttValue
    342         (
    343                 const   XMLAttDef* const    attDef
    344                 , const XMLCh* const       name
    345                 , const XMLCh* const        value
    346                 ,       XMLBuffer&          toFill
    347         );
    348 
    349         bool normalizeAttRawValue
    350         (
    351                 const   XMLCh* const        attrName
    352                 , const XMLCh* const        value
    353                 ,       XMLBuffer&          toFill
    354         );
    355 
    356         void parseSchemaLocation(const XMLCh* const schemaLocationStr, bool ignoreLoadSchema = false);
    357 
    358         void processSchemaLocation(XMLCh* const schemaLoc);
     364    bool basicAttrValueScan(const XMLCh* const, XMLBuffer&);
     365
     366    XMLSize_t rawAttrScan(const XMLCh* const, RefVectorOf<KVStringPair>&, bool&);
     367
     368    bool scanAttValue(const XMLAttDef* const, const XMLCh* const, XMLBuffer&);
     369
     370    XMLSize_t buildAttList(const RefVectorOf<KVStringPair>&, const XMLSize_t, XMLElementDecl*, RefVectorOf<XMLAttr>&);
     371
     372    void updateNSMap(const XMLCh* const, const XMLCh* const);
     373
     374    bool normalizeAttValue(const XMLAttDef* const, const XMLCh* const, const XMLCh* const, XMLBuffer&);
     375
     376    bool normalizeAttRawValue(const XMLCh* const, const XMLCh* const, XMLBuffer&);
     377
     378    void parseSchemaLocation(const XMLCh* const, bool);
     379
     380    void processSchemaLocation(XMLCh* const);
    359381
    360382        void resizeRawAttrColonList();
    361383
    362         void scanRawAttrListforNameSpaces(XMLSize_t attCount);
     384    void scanRawAttrListforNameSpaces(XMLSize_t);
     385
     386    inline
     387    XMLAttDefList & getAttDefList( bool              isSchemaGrammar
     388                                 , ComplexTypeInfo*  currType
     389                                 , XMLElementDecl*   elemDecl );
     390
     391    void updateNSMap
     392    (
     393        const   XMLCh* const    attrName
     394        , const XMLCh* const    attrValue
     395        , const int             colonPosition
     396    );
     397
     398    void updateNSMap
     399    (
     400        const   QName* const   attrName
     401        , const XMLCh* const   attrValue
     402    );
     403
     404    bool laxElementValidation(QName* element, ContentLeafNameTypeVector* cv, const XMLContentModel* const cm, const XMLSize_t parentElemDepth);
    363405
    364406        // -----------------------------------------------------------------------
     
    417459        XSModel*                                fModel;
    418460        PSVIElement*                            fPSVIElement;
    419         ValueStackOf<bool>*                     fErrorStack;
     461    ValueStackOf<bool>*                     fErrorStack;
    420462        PSVIElemContext                         fPSVIElemContext;
    421463        RefHash2KeysTableOf<SchemaInfo>*        fSchemaInfoList;
    422464        RefHash2KeysTableOf<SchemaInfo>*        fCachedSchemaInfoList;
    423         XMLGrammerResolver                      fGrammarList;
     465    XMLGrammarResolver                      fGrammarList;
    424466    DatatypeValidator *                     fAnySimpleTypeValidator;
    425467        XMLParserImpl<IGXMLScanner>*            fProgressiveParser;
     
    441483}
    442484
    443 DatatypeValidator * IGXMLScanner::getAnySimpleTypeValidator()
     485inline DatatypeValidator * IGXMLScanner::getAnySimpleTypeValidator()
    444486{
    445487    if (unlikely(fAnySimpleTypeValidator == 0))
    446488    {
    447489        fAnySimpleTypeValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYSIMPLETYPE);
    448         assert (fAnySimpleTypeValidator != 0);
    449490    }
    450491    return fAnySimpleTypeValidator;
     
    454495//  IGXMLScanner: Private helper methods
    455496// ---------------------------------------------------------------------------
     497
     498unsigned int IGXMLScanner::getGrammarNamespaceId()
     499{
     500    unsigned int grammarUriId = fGrammar->getTargetNamespaceId();
     501    if (unlikely(grammarUriId == XMLNamespaceResolver::fUnknownUriId))
     502    {
     503        grammarUriId = fUriResolver->resolveUriId(fGrammar->getTargetNamespace());
     504        fGrammar->setTargetNamespaceId(grammarUriId);
     505    }
     506    return grammarUriId;
     507}
    456508
    457509XMLAttDefList &
     
    460512                                                   , XMLElementDecl*   elemDecl)
    461513{
    462         if (isSchemaGrammar && currType)
    463                 return currType->getAttDefList();
    464         else
    465                 return elemDecl->getAttDefList();
     514    return (isSchemaGrammar && currType) ? currType->getAttDefList() : elemDecl->getAttDefList();
    466515}
    467516
    468517bool IGXMLScanner::switchGrammar(const unsigned int uriId)
    469518{
     519    DEBUG_GRAMMAR_MESSAGE("switchGrammar(" << uriId << ')')
     520
    470521        Grammar * grammar = fGrammarList.getGrammar(uriId);
     522    const XMLCh * grammarNameSpace = NULL;
    471523        if (unlikely(grammar == NULL))
    472524        {
    473                 const XMLCh * const grammarNameSpace = (*fUriResolver)[uriId];
     525        grammarNameSpace = fUriResolver->getUriForId(uriId);
    474526                grammar = fGrammarResolver->getGrammar(grammarNameSpace);
    475527                if (!grammar && !fSkipDTDValidation)
     
    480532                fGrammarList.setGrammar(uriId, grammar);
    481533        }
    482         DEBUG_GRAMMAR_MESSAGE("switchGrammar(" << uriId << ")=" << grammar);
     534
     535    DEBUG_GRAMMAR_MESSAGE("switchGrammar(" << uriId << ',' << grammarNameSpace << ")=" << grammar)
     536
    483537        return setCurrentGrammar(grammar);
    484538}
     
    503557bool IGXMLScanner::switchGrammar(const XMLCh* const newGrammarNameSpace)
    504558{
    505         const bool switched = switchGrammar(fUriResolver->resolveUriId(newGrammarNameSpace), newGrammarNameSpace);
    506         DEBUG_GRAMMAR_MESSAGE("switchGrammar(" << newGrammarNameSpace << ")=" << switched);
    507         return switched;
     559    return switchGrammar(fUriResolver->resolveUriId(newGrammarNameSpace), newGrammarNameSpace);
    508560}
    509561
     
    516568        else if (grammar != fGrammar)
    517569        {
    518                 Grammar::GrammarType grammarType = grammar->getGrammarType();
    519 
    520                 DEBUG_GRAMMAR_MESSAGE("grammarType=" << grammarType)
    521 
    522                 if (grammarType == Grammar::SchemaGrammarType)
     570        DEBUG_GRAMMAR_MESSAGE(" *** setCurrentGrammar(" << grammar << ") " << (grammar->getGrammarType() == Grammar::SchemaGrammarType ? "Schema" : "DTD"))
     571
     572        fGrammarType = grammar->getGrammarType();
     573
     574        if (fGrammarType == Grammar::SchemaGrammarType)
    523575                {
    524576                        fValidator = fSchemaValidator;
     
    531583                                }
    532584                        }
     585
     586            fSchemaValidator->setGrammar(grammar);
    533587                }
    534                 else if (grammarType == Grammar::DTDGrammarType)
     588        else if (fGrammarType == Grammar::DTDGrammarType)
    535589                {
    536590                        if (fSkipDTDValidation)
     
    548602                                }
    549603                        }
     604
     605            fDTDValidator->setGrammar(grammar);
    550606                }
    551607
    552                 fGrammarType = grammarType;
    553608                fGrammar = grammar;
    554                 fValidator->setGrammar(grammar);
     609
    555610        }
    556611        return true;
    557 }
    558 
    559 void
    560 IGXMLScanner::validateAttValue
    561 (
    562     XMLElementDecl * elemDecl
    563     , XMLAttDef * attDef
    564     , const XMLCh * value
    565     , DatatypeValidator *& validator
    566     , PSVIItem::VALIDITY_STATE & attrValid
    567     , XMLAttDef::AttTypes & attType
    568 )
    569 {
    570     if (fValidate)
    571     {
    572         if (fGrammarType == Grammar::SchemaGrammarType)
    573         {
    574             SchemaAttDef * schemaAttDef = reinterpret_cast<SchemaAttDef*>(attDef);
    575 
    576             //  Normalize the raw value since we have the attribute type. We
    577             //  don't care about the return status here. If it failed, an error
    578             //  will be issued, which is all we care about.
    579 
    580             const XMLCh * xsNormalized = normalizeByAttDef(schemaAttDef, value, fNormalizeData && fValidate);
    581 
    582             fSchemaValidator->validateAttrValue(schemaAttDef, xsNormalized, false, elemDecl);
    583 
    584             validator = fSchemaValidator->getMostRecentAttrValidator();
    585 
    586             if (unlikely(fSchemaValidator->getErrorOccurred()))
    587             {
    588                 fPSVIElemContext.fErrorOccurred = true;
    589                 if (getPSVIHandler())
    590                 {
    591                     attrValid = PSVIItem::VALIDITY_INVALID;
    592                 }
    593             }
    594 
    595             attType = schemaAttDef->getType();
    596         }
    597         else // if (fGrammarType == Grammar::DTDGrammarType)
    598         {
    599             DTDAttDef * dtdAttDef = reinterpret_cast<DTDAttDef*>(attDef);
    600 
    601             fDTDValidator->validateAttrValue(dtdAttDef, value, false, elemDecl);
    602 
    603             attType = dtdAttDef->getType();
    604         }
    605     }
    606     else
    607     {   // no decl; default DOMTypeInfo to anySimpleType
    608         validator = getAnySimpleTypeValidator();
    609     }   
    610 }
    611 
    612 const XMLCh * IGXMLScanner::normalizeByAttDef(SchemaAttDef* attDef, const XMLCh * value, const bool writeValue)
    613 {
    614         DatatypeValidator* tempDV = attDef->getDatatypeValidator();
    615         if (tempDV && tempDV->getWSFacet() != DatatypeValidator::PRESERVE)
    616         {
    617                 // normalize the attribute according to schema whitespace facet
    618                 fSchemaValidator->normalizeWhiteSpace
    619                 (
    620                         tempDV, value, fWSNormalizeBuf, true
    621                 );
    622                 if (writeValue)
    623                 {
    624                         XMLString::copyNString
    625                         (
    626                                 const_cast<XMLCh*>(value), fWSNormalizeBuf.getRawBuffer(), fWSNormalizeBuf.getLen()
    627                         );
    628                         return value;
    629                 }
    630                 return fWSNormalizeBuf.getRawBuffer();
    631         }
    632         return value;
    633612}
    634613
     
    648627}
    649628
     629#ifdef __GNUC__
     630#warning "TO CONSIDER: could it be possible to split the tag validation routines into get and validate functions?"
     631/// Could perform resolution in the WF and NS layers and validation in the GV.
     632/// Difficulty would be to maintain state--but the grammar may not need it as long as the proper elemDecl and attDef were obtained.
     633/// Would be possible to create a stream of
     634#endif
     635
    650636// --------------------------------------------------------------------------------------------------------
    651637// HANDLE START / EMPTY TAG FUNCTIONS
    652638// --------------------------------------------------------------------------------------------------------
    653639
    654 XMLElementDecl * IGXMLScanner::handleStartTag
     640XMLElementDecl & IGXMLScanner::getElementDecl
    655641(
    656       const XMLSymbol * const           element
    657     , const XMLAttributeList &          attributeList
    658     , XMLSize_t                                         attributeCount
     642      XMLSymbol &                   element
     643    , unsigned int &                uriId
    659644    , const bool                                        isRoot
    660     , const bool                                        isEmpty
    661     , const XMLSize_t                           readerNum
     645    , const bool                    doPSVI
     646    , XMLDocumentAccumulator &      parser   
    662647)
    663648{
    664     #ifdef __GNUC__
    665     #warning "optimize the fDoNamespaces branches? may or may not help depending on what the compiler is able to do"
    666     #endif
    667 
    668649    /// ----------------------------- DETERMINE THE ELEMENT DECLARATION -----------------------------------
    669650
     
    671652    XMLElementDecl * elemDecl = 0;
    672653
    673     if (!fDoNamespaces)
     654    fPSVIElemContext.fErrorOccurred = false;
     655    if (unlikely(!fDoNamespaces))
    674656    {
    675657        //  Lets try to look up the element in the validator's element decl pool
     
    681663        //  Actually, we *don't* tell him to fault in a decl if he does not find one- NG
    682664
    683         elemDecl = element->getElemDecl();
    684 
    685         if (!elemDecl)
    686         {
    687             const XMLCh * qName = element->getName();
    688             elemDecl = element->getElemDecl(XMLNamespaceResolver::fEmptyUriId, Grammar::TOP_LEVEL_SCOPE, fGrammar);
    689 
    690             // look for it in the undeclared pool:
     665        elemDecl = findElementDecl(element, XMLNamespaceResolver::fEmptyUriId, Grammar::TOP_LEVEL_SCOPE, fDTDGrammar);
     666
     667        if (unlikely(elemDecl == 0))
     668        {           
     669            elemDecl = fDTDElemNonDeclPool->getByKey(element.getName());
     670            DEBUG_GRAMMAR_MESSAGE("fDTDElemNonDeclPool->getByKey(" << element.getName() << ")=" << elemDecl)
    691671            if (!elemDecl)
    692672            {
    693                 elemDecl = fDTDElemNonDeclPool->getByKey(qName);
    694                 bool notDeclared = false;
    695 
    696                 if (!elemDecl)
    697                 {
    698                     // we're assuming this must be a DTD element.  DTD's can be
    699                     // used with or without namespaces, but schemas cannot be used without
    700                     // namespaces.
    701                     elemDecl = new (fMemoryManager) DTDElementDecl
    702                     (
    703                         element->fQName
    704                         , DTDElementDecl::Any
    705                         , fMemoryManager
    706                     );
    707                     elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
    708                     if (fValidate)
    709                     {
    710                         elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
    711                         notDeclared = true;
    712                     }
    713                 }
    714                 else
    715                 {
    716                     notDeclared = !elemDecl->isDeclared();
    717                 }
    718 
    719                 // If its not marked declared and validating, then emit an error
    720                 if (notDeclared)
    721                 {
    722                     fValidator->emitError(XMLValid::ElementNotDefined, qName);
    723                 }
    724             }
    725 
    726             element->setElemDecl(elemDecl);
     673                // we're assuming this must be a DTD element.  DTD's can be
     674                // used with or without namespaces, but schemas cannot be used without
     675                // namespaces.
     676                elemDecl = new (fMemoryManager) DTDElementDecl(element.fQName, DTDElementDecl::Any, fMemoryManager);
     677                elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
     678                elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
     679            }
     680            element.setElemDecl(XMLNamespaceResolver::fEmptyUriId, Grammar::TOP_LEVEL_SCOPE, elemDecl);
     681        }
     682
     683        // If its not marked declared and validating, then emit an error
     684        if (unlikely(!elemDecl->isDeclared() && fValidate))
     685        {
     686            fDTDValidator->emitError(XMLValid::ElementNotDefined, element.getName());
     687            fValidate = false;
    727688        }
    728689
    729690        // Expand the element stack and add the new element
    730         fElemStack.addLevel(elemDecl, readerNum);
    731         fElemStack.setValidationFlag(fValidate);
     691        fElemStack.addLevel(elemDecl, 0);
     692
     693        fValidate &= !fSkipDTDValidation;
    732694
    733695        //  Validate the element
    734696        if (fValidate)
    735697        {
    736             fValidator->validateElement(elemDecl);
    737         }
    738 
    739         //  If this is the first element and we are validating, check the root
    740         //  element.
    741         if (unlikely(isRoot))
    742         {
    743             fRootGrammar = fGrammar;
    744             if (fValidate)
    745             {
    746                 //  If a DocType exists, then check if it matches the root name there.
    747                 if (unlikely(fRootElemName && !XMLString::equals(element->getName(), fRootElemName)))
    748                 {
    749                     fValidator->emitError(XMLValid::RootElemNotLikeDocType);
    750                 }
    751             }
    752         }
    753     }
    754     else
     698            fDTDValidator->validateElement(elemDecl);
     699        }
     700    }
     701    else  // if (fDoNamespaces)
    755702    {
    756703        // save the contentleafname and currentscope before addlevel, for later use
     
    759706        unsigned int currentScope = Grammar::TOP_LEVEL_SCOPE;
    760707        bool laxThisOne = false;
    761         const unsigned int elementUriId = element->getQName()->getURI();
    762 
    763         if ((!isRoot) && (fGrammarType == Grammar::SchemaGrammarType))
    764         {
    765             // schema validator will have correct type if validating
    766             SchemaElementDecl* tempElement = (SchemaElementDecl*)fElemStack.topElement()->fThisElement;
    767             SchemaElementDecl::ModelTypes modelType = tempElement->getModelType();
    768             ComplexTypeInfo *currType = 0;
    769 
    770             if (fValidate)
    771             {
    772                 currType = fSchemaValidator->getCurrentTypeInfo();
    773                 if (likely(currType != 0))
    774                     modelType = (SchemaElementDecl::ModelTypes)currType->getContentType();
    775                 else // something must have gone wrong
    776                     modelType = SchemaElementDecl::Any;
    777             }
    778             else
    779             {
    780                 currType = tempElement->getComplexTypeInfo();
    781             }
    782 
    783             switch (modelType)
    784             {
    785                 case SchemaElementDecl::Mixed_Simple:
    786                 case SchemaElementDecl::Mixed_Complex:
    787                 case SchemaElementDecl::Children:
    788                     cm = currType->getContentModel();
    789                     cv = cm->getContentLeafNameTypeVector();
    790                     currentScope = fElemStack.getCurrentScope();
    791                     break;
    792                 case SchemaElementDecl::Any:
    793                     laxThisOne = true;
    794             }
    795         }
    796 
    797         //if schema, check if we should lax or skip the validation of this element
    798         if (cv)
    799         {
    800             // elementDepth will be > 0, as cv is only constructed if element is not root.
    801             laxThisOne = laxElementValidation(element->getQName(), cv, cm, fElemStack.getLevel());
    802         }
    803 
    804         // this info needed for DOMTypeInfo
    805         fPSVIElemContext.fErrorOccurred = false;
    806 
    807         if (fGrammarType == Grammar::DTDGrammarType)
    808         {
    809             if (!fSkipDTDValidation)
    810             {
    811                 elemDecl = element->getElemDecl(XMLNamespaceResolver::fEmptyUriId, Grammar::TOP_LEVEL_SCOPE, fGrammar);
    812                 if (elemDecl && elemDecl->hasAttDefs())
    813                 {
    814                     XMLAttDefList & attDefList = elemDecl->getAttDefList();
    815                     for (XMLSize_t i = 0; i < attDefList.getAttDefCount(); i++)
     708
     709        bool bXsiTypeSet = false;
     710        bool wasAdded = false;
     711
     712        if (fGrammarType == Grammar::SchemaGrammarType)
     713        {
     714            bXsiTypeSet = fSchemaValidator->getIsXsiTypeSet();
     715
     716            if (likely(!isRoot))
     717            {
     718                SchemaElementDecl::ModelTypes modelType;
     719                ComplexTypeInfo *currType;
     720
     721                if (fValidate)
     722                {
     723                    // schema validator will have correct type if validating
     724                    currType = fSchemaValidator->getCurrentTypeInfo();
     725                    modelType = currType ? (SchemaElementDecl::ModelTypes)currType->getContentType() : SchemaElementDecl::Any;
     726                }
     727                else
     728                {
     729                    SchemaElementDecl & parent = *((SchemaElementDecl*)fElemStack.topElement()->fThisElement);
     730                    currType = parent.getComplexTypeInfo();
     731                    modelType = parent.getModelType();
     732                }
     733
     734                switch (modelType)
     735                {
     736                    case SchemaElementDecl::Mixed_Simple:
     737                    case SchemaElementDecl::Mixed_Complex:
     738                    case SchemaElementDecl::Children:
     739                        cm = currType->getContentModel();
     740                        cv = cm->getContentLeafNameTypeVector();
     741                        currentScope = fElemStack.getCurrentScope();
     742                        //if schema, check if we should lax or skip the validation of this element
     743                        laxThisOne = laxElementValidation(element.getQName(), uriId, cv, cm, fElemStack.getLevel());
     744                        break;
     745                    case SchemaElementDecl::Any:
     746                        laxThisOne = true;
     747                }
     748            }
     749
     750            elemDecl = findElementDecl(element, uriId, currentScope, fGrammar);
     751
     752            if (unlikely(elemDecl == 0))
     753            {               
     754                if (likely(fDoSchema))
     755                {
     756                    const unsigned int grammarUriId = getGrammarNamespaceId();
     757                    Grammar * const originalGrammar = fGrammar;
     758                    if (unlikely(grammarUriId != uriId))
    816759                    {
    817                         // Get the current att def, for convenience and its def type
    818                         const XMLAttDef & curDef = attDefList.getAttDef(i);
    819                         const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
    820 
    821                         // update the NSMap if there are any default/fixed xmlns attributes
    822                         if ((defType == XMLAttDef::Default) || (defType == XMLAttDef::Fixed))
     760                        if (likely(switchGrammar(uriId)))
    823761                        {
    824                             const XMLCh * rawPtr = curDef.getFullName();
    825                             if (XMLStringU::isXMLNS(rawPtr))
    826                             {
    827                                 #ifdef __GNUC__
    828                                 #warning "IGXMLScanner::beginStartTag cannot handle default xmlns attributes in the DTD."
    829                                 #endif
    830                             }
     762                            elemDecl = findElementDecl(element, uriId, currentScope, fGrammar);
     763                        }
     764                        else if (unlikely(!laxThisOne && fValidate))
     765                        {
     766                            // the laxElementValidation routine (called above) will
     767                            // set fValidate to false for a "skipped" element
     768                            fSchemaValidator->emitError(XMLValid::GrammarNotFound, fUriResolver->getUriForId(uriId));
    831769                        }
    832770                    }
    833                 }
    834             }
    835 
    836             if (!elemDecl)
    837             {
    838                 elemDecl = fDTDElemNonDeclPool->getByKey(element->getName());
    839                 if (elemDecl)
    840                 {
    841                     element->setElemDecl(XMLNamespaceResolver::fEmptyUriId, Grammar::TOP_LEVEL_SCOPE, elemDecl, fGrammar);
    842                 }
    843             }
    844         }
    845 
    846         if (fDoSchema)
    847         {
    848             if (fGrammarType == Grammar::DTDGrammarType)
    849             {
    850                 if (!switchGrammar(elementUriId))
    851                 {
    852                     fValidator->emitError
    853                     (
    854                         XMLValid::GrammarNotFound, fUriResolver->getUriForId(elementUriId)
    855                     );
    856                 }
    857             }
    858             else if (fGrammarType == Grammar::SchemaGrammarType)
    859             {
    860                 Grammar * grammar = fGrammar;
    861                 elemDecl = element->getElemDecl(elementUriId, currentScope, grammar);
    862                 if (likely(elemDecl != 0))
    863                 {
    864                     if (unlikely(grammar != fGrammar))
     771
     772                    if (unlikely(elemDecl == 0 && (currentScope != Grammar::TOP_LEVEL_SCOPE)))
    865773                    {
    866                         fGrammar = grammar;
    867                         fGrammarType = grammar->getGrammarType();
    868                         fValidator->setGrammar(grammar);
    869                     }
    870                 }
    871                 else // if not found, then it may be a reference, try TOP_LEVEL_SCOPE
    872                 {
    873                     bool checkTopLevel = (currentScope != Grammar::TOP_LEVEL_SCOPE);
    874 
    875                     const unsigned int grammarUriId =
    876                         fUriResolver->resolveUriId(fGrammar->getTargetNamespace());
    877 
    878                     if (grammarUriId != elementUriId)
    879                     {
    880                         checkTopLevel = switchGrammar(elementUriId);
    881 
    882                         // the laxElementValidation routine (called above) will
    883                         // set fValidate to false for a "skipped" element
    884                         if (unlikely(!laxThisOne && fValidate && !checkTopLevel))
     774                        // try the top level
     775                        elemDecl = findElementDecl(element, uriId, Grammar::TOP_LEVEL_SCOPE, fGrammar);
     776
     777                        if (unlikely(elemDecl == 0 && fValidate))
    885778                        {
    886                             fValidator->emitError
    887                             (
    888                                 XMLValid::GrammarNotFound, fUriResolver->getUriForId(elementUriId)
    889                             );
    890                         }
    891 
    892                     }
    893 
    894                     if (checkTopLevel)
    895                     {
    896                         elemDecl = element->getElemDecl(elementUriId, Grammar::TOP_LEVEL_SCOPE, fGrammar);
    897                     }
    898 
    899                     if (!elemDecl && currentScope != Grammar::TOP_LEVEL_SCOPE)
    900                     {
    901                         if (grammarUriId == elementUriId)
    902                         {
    903                             // still not found in specified uri; try emptyNamespace see if element should be un-qualified.
    904                             if (elementUriId != XMLNamespaceResolver::fEmptyUriId)
     779                            if (grammarUriId == uriId)
    905780                            {
    906                                 XMLElementDecl* tempElemDecl =
    907                                     element->getElemDecl(XMLNamespaceResolver::fEmptyUriId, currentScope, fGrammar);
    908 
    909                                 if (tempElemDecl && tempElemDecl->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate)
     781                                // still not found in specified uri; try emptyNamespace see if element should be un-qualified.
     782                                if (uriId != XMLNamespaceResolver::fEmptyUriId)
    910783                                {
    911                                     fValidator->emitError(XMLValid::ElementNotUnQualified, element->getName());
    912                                     elemDecl = tempElemDecl;
    913                                 }
    914                             }
    915                         }
    916                         else if (elementUriId == XMLNamespaceResolver::fEmptyUriId)
    917                         {
    918                             // still Not found in specified uri
    919                             // go to original Grammar again to see if element needs
    920                             // to be fully qualified.
    921                             // Use a temp variable until we decide this is the case
    922 
    923                             if (setCurrentGrammar(grammar))
    924                             {
    925                                 XMLElementDecl* tempElemDecl = element->getElemDecl(grammarUriId, currentScope, fGrammar);
    926                                 if (tempElemDecl && tempElemDecl->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate)
    927                                 {
    928                                     fValidator->emitError(XMLValid::ElementNotQualified, element->getName());
    929                                     elemDecl = tempElemDecl;
    930                                 }
    931                             }
    932                             else if (!laxThisOne && fValidate)
    933                             {
    934                                 fValidator->emitError(XMLValid::GrammarNotFound, fGrammar->getTargetNamespace());
    935                             }
    936                         }
    937                     }
    938 
    939                     if (!elemDecl)
    940                     {
    941                         // still not found
    942                         // switch back to original grammar first if necessary
    943                         if (grammarUriId != elementUriId)
    944                         {
    945                             setCurrentGrammar(grammar);
    946                         }
    947 
    948                         // look in the list of undeclared elements, as would have been
    949                         // done before we made grammars stateless:
    950                         elemDecl = fSchemaElemNonDeclPool->getByKey(element->getQName()->getLocalPart(), elementUriId, (int)Grammar::TOP_LEVEL_SCOPE);
    951                     }
    952 
    953                     if (elemDecl)
    954                     {
    955                         element->setElemDecl(elementUriId, currentScope, elemDecl, fGrammar);
    956                     }
    957                 }
    958             }
    959         }
    960 
    961         //  Look up the element now in the grammar. This will get us back a
    962         //  generic element decl object. We tell him to fault one in if he does
    963         //  not find it.
    964         bool wasAdded = false;
    965 
    966         if (!elemDecl)
    967         {
    968             if (fGrammarType == Grammar::DTDGrammarType)
    969             {
    970                 elemDecl = new (fMemoryManager) DTDElementDecl(element->getQName(), DTDElementDecl::Any, fMemoryManager);
    971                 elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
    972             }
    973             else if (fGrammarType == Grammar::SchemaGrammarType)
    974             {
    975                 elemDecl = new (fMemoryManager) SchemaElementDecl
    976                 (
    977                     element->getQName()
    978                     , SchemaElementDecl::Any
    979                     , Grammar::TOP_LEVEL_SCOPE
    980                     , fMemoryManager
    981                 );
    982                 elemDecl->setId
    983                 (
    984                     fSchemaElemNonDeclPool->put
    985                     (
    986                         (void*)elemDecl->getBaseName()
    987                         , elementUriId
    988                         , (int)Grammar::TOP_LEVEL_SCOPE
    989                         , (SchemaElementDecl*)elemDecl
    990                     )
    991                 );
    992             }
    993 
    994             element->setElemDecl(elementUriId, Grammar::TOP_LEVEL_SCOPE, elemDecl, fGrammar);
    995 
    996             wasAdded = true;
    997         }
    998 
    999         //  We do something different here according to whether we found the element or not.
    1000         const bool bXsiTypeSet = (fGrammarType == Grammar::SchemaGrammarType) && fSchemaValidator->getIsXsiTypeSet();
    1001 
    1002         if (wasAdded)
    1003         {
    1004             if (laxThisOne && !bXsiTypeSet)
    1005             {
    1006                 fValidate = false;
    1007             }
    1008             else if (fValidate)
    1009             {
    1010                 // If validating then emit an error
    1011 
    1012                 // This is to tell the reuse Validator that this element was
    1013                 // faulted-in, was not an element in the grammar pool originally
    1014                 elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
    1015 
    1016                 // xsi:type was specified, don't complain about missing definition
    1017                 if (!bXsiTypeSet)
    1018                 {
    1019                     fValidator->emitError(XMLValid::ElementNotDefined, elemDecl->getFullName());
    1020 
    1021                     if (fGrammarType == Grammar::SchemaGrammarType)
    1022                     {
    1023                         fPSVIElemContext.fErrorOccurred = true;
    1024                     }
    1025                 }
    1026             }
    1027         }
    1028         else if (!elemDecl->isDeclared())
    1029         {
    1030             // If its not marked declared and validating, then emit an error
    1031             if (elemDecl->getCreateReason() == XMLElementDecl::NoReason)
    1032             {
    1033                 if (!bXsiTypeSet && fGrammarType == Grammar::SchemaGrammarType)
    1034                 {
    1035                     fPSVIElemContext.fErrorOccurred = true;
    1036                 }
    1037             }
    1038 
    1039             if (laxThisOne)
    1040             {
    1041                 fValidate = false;
    1042             }
    1043             else if (fValidate && !bXsiTypeSet)
    1044             {
    1045                 fValidator->emitError(XMLValid::ElementNotDefined, elemDecl->getFullName());
    1046             }
    1047         }
    1048 
    1049         //  Now we can update the element stack to set the current element decl.
    1050         const XMLSize_t elemDepth = fElemStack.addLevel(elemDecl, fReaderMgr.getCurrentReaderNum());
    1051 
    1052         if (isRoot)
    1053         {
    1054             fRootGrammar = fGrammar;
    1055             if (fGrammarType == Grammar::SchemaGrammarType && !fRootElemName)
    1056             {
    1057                 fRootElemName = XMLString::replicate(element->getName(), element->getLength());
    1058             }
    1059         }
    1060 
    1061         if (fGrammarType == Grammar::SchemaGrammarType && fPSVIHandler)
    1062         {
    1063             fPSVIElemContext.fElemDepth++;
    1064             if (elemDecl->isDeclared())
    1065             {
    1066                 fPSVIElemContext.fNoneValidationDepth = fPSVIElemContext.fElemDepth;
    1067             }
    1068             else
    1069             {
    1070                 fPSVIElemContext.fFullValidationDepth = fPSVIElemContext.fElemDepth;
    1071             }
    1072         }
    1073 
    1074         //  Validate the element
    1075         if (fValidate)
    1076         {
    1077             fValidator->validateElement(elemDecl);
    1078             if (fValidator->handlesSchema())
    1079             {
    1080                 if (fSchemaValidator->getErrorOccurred())
    1081                 {
    1082                     fPSVIElemContext.fErrorOccurred = true;
    1083                 }
    1084             }
    1085         }
    1086 
    1087         if (fGrammarType == Grammar::SchemaGrammarType)
    1088         {
    1089             ComplexTypeInfo* typeinfo = (fValidate)
    1090                 ? fSchemaValidator->getCurrentTypeInfo()
    1091                 : ((SchemaElementDecl*)elemDecl)->getComplexTypeInfo();
    1092 
    1093             if (typeinfo)
    1094             {
    1095                 currentScope = typeinfo->getScopeDefined();
    1096 
    1097                 // switch grammar if the typeinfo has a different grammar (happens when there is xsi:type)
    1098                 XMLCh* typeName = typeinfo->getTypeName();
    1099                 const int comma = XMLString::indexOf(typeName, chComma);
    1100                 if (comma > 0)
    1101                 {
    1102                     XMLBuffer prefixBuf(comma + 1, fMemoryManager);
    1103                     prefixBuf.append(typeName, comma);
    1104                     const XMLCh* uriStr = prefixBuf.getRawBuffer();
    1105 
    1106                     bool errorCondition = !switchGrammar(uriStr) && fValidate;
    1107                     if (errorCondition && !laxThisOne)
    1108                     {
    1109                         fValidator->emitError
    1110                         (
    1111                             XMLValid::GrammarNotFound
    1112                             , prefixBuf.getRawBuffer()
    1113                         );
    1114                     }
    1115                 }
    1116                 else if (comma == 0)
    1117                 {
    1118                     bool errorCondition = !switchGrammar(XMLNamespaceResolver::fEmptyUriId) && fValidate;
    1119                     if (errorCondition && !laxThisOne)
    1120                     {
    1121                         fValidator->emitError
    1122                         (
    1123                             XMLValid::GrammarNotFound
    1124                             , XMLUni::fgZeroLenString
    1125                         );
    1126                     }
    1127                 }
    1128             }
    1129 
    1130             fElemStack.setCurrentScope(currentScope);
    1131 
    1132             // Set element next state
    1133             if (elemDepth >= fElemStateSize)
    1134             {
    1135                 resizeElemState();
    1136             }
    1137 
    1138             fElemState[elemDepth] = 0;
    1139             fElemLoopState[elemDepth] = 0;
    1140         }
    1141 
    1142         fElemStack.setCurrentGrammar(fGrammar);
    1143         fElemStack.setValidationFlag(fValidate);
    1144 
    1145         //  If this is the first element and we are validating, check the root
    1146         //  element.
    1147         if (unlikely(isRoot && fValidate && fRootElemName))
    1148         {
    1149             //  If a DocType exists, then check if it matches the root name there.
    1150             if (!XMLString::equals(element->getName(), fRootElemName))
    1151             {
    1152                 fValidator->emitError(XMLValid::RootElemNotLikeDocType);
    1153             }
    1154         }
    1155 
    1156         // PSVI handling:  even if it turns out there are
    1157         // no attributes, we need to reset this list...
    1158         if (getPSVIHandler() && fGrammarType == Grammar::SchemaGrammarType )
    1159         {
    1160             fPSVIAttrList->reset();
    1161         }
    1162     }
    1163 
    1164     /// -------------------------------- HANDLE ATTRIBUTES -----------------------------------
    1165 
    1166     for (XMLSize_t index = 0; index < attributeCount; index++)
    1167     {
    1168         const XMLAttribute & attributeItem = attributeList[index];
    1169 
    1170         const XMLSymbol * const attribute = attributeItem.getAttribute();
    1171         const XMLCh * value = attributeItem.getValue();
    1172         // const XMLSize_t length = attributeList[index].getLength();
    1173 
    1174         XMLAttDef::AttTypes attType = XMLAttDef::CData;
    1175 
    1176         if (!fDoNamespaces)
    1177         {
    1178             //  See if this attribute is declared for this element. If we are
    1179             //  not validating of course it will not be at first, but we will
    1180             //  fault it into the pool (to avoid lots of redundant errors.)
    1181             DTDElementDecl * const dtdElemDecl = reinterpret_cast<DTDElementDecl*>(elemDecl);
    1182 
    1183             XMLAttDef * attDef = dtdElemDecl->getAttDef(attribute->getName());
    1184 
    1185             //  Add this attribute to the attribute list that we use to
    1186             //  pass them to the handler. We reuse its existing elements
    1187             //  but expand it as required.
    1188 
    1189             // Note that we want to this first since this will
    1190             // make a copy of the namePtr; we can then make use of
    1191             // that copy in the hashtable lookup that checks
    1192             // for duplicates.  This will mean we may have to update
    1193             // the type of the XMLAttr later.
    1194 
    1195             if (unlikely(!attDef))
    1196             {
    1197                 //  If there is a validation handler, then we are validating so emit an error.
    1198                 if (fValidate)
    1199                 {
    1200                     fValidator->emitError
    1201                     (
    1202                         XMLValid::AttNotDefinedForElement
    1203                         , attribute->getName()
    1204                         , element->getName()
    1205                     );
    1206                 }
    1207             }
    1208             else
    1209             {
    1210                 // prepare for duplicate detection
    1211                 attDef->setLastOccurrence(attribute->fLastOccurence);
    1212 
    1213                 //  Now that its all stretched out, lets look at its type and
    1214                 //  determine if it has a valid value. It will output any needed
    1215                 //  errors, but we just keep going. We only need to do this if
    1216                 //  we are validating.
    1217                 if (fValidate)
    1218                 {
    1219                     // Let the validator pass judgement on the attribute value
    1220                     fValidator->validateAttrValue
    1221                     (
    1222                         attDef
    1223                         , value
    1224                         , false
    1225                         , dtdElemDecl
    1226                     );
    1227                 }
    1228             }
    1229         }
    1230         else // if (fDoNamespaces)
    1231         {
    1232             //  If its not a special case namespace attr of some sort, then we
    1233             //  do normal checking and processing.
    1234             DatatypeValidator * attrValidator = 0;
    1235             PSVIAttribute *psviAttr = 0;
    1236             bool otherXSI = false;
    1237             const unsigned int attributeUriId = attribute->getQName()->getURI();
    1238 
    1239             // moving some of the processAttList code here....
    1240 
    1241             PSVIItem::VALIDITY_STATE attrValid = PSVIItem::VALIDITY_VALID;
    1242             PSVIItem::ASSESSMENT_TYPE attrAssessed = PSVIItem::VALIDATION_FULL;
    1243 
    1244             const QName* const qName = attribute->getQName();
    1245             // const XMLCh* const prefPtr = qName->getPrefix();
    1246             const XMLCh* const localPart = qName->getLocalPart();
    1247 
    1248             //  If the uri comes back as the xmlns or xml URI or its just a name
    1249             //  and that name is 'xmlns', then we handle it specially. So set a
    1250             //  boolean flag that lets us quickly below know which we are dealing
    1251             //  with.
    1252 
    1253             const bool isXSI = (attributeUriId == XMLNamespaceResolver::fSchemaInstanceUriId);
    1254             const bool isNamespaceAttribute = (isXSI | attribute->isXMLNS());
    1255 
    1256             if (unlikely(isNamespaceAttribute && fGrammarType == Grammar::SchemaGrammarType))
    1257             {
    1258                 bool ValueValidate = false;
    1259                 bool tokenizeBuffer = false;
    1260 
    1261                 if (attributeUriId == XMLNamespaceResolver::fXMLNSUriId)
    1262                 {
    1263                     attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYURI);
    1264                 }
    1265                 else if (isXSI)
    1266                 {
    1267                     if (XMLString::equals(localPart, SchemaSymbols::fgATT_NILL))
    1268                     {
    1269                         attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_BOOLEAN);
    1270                         ValueValidate = true;
    1271                     }
    1272                     else if (XMLString::equals(localPart, SchemaSymbols::fgXSI_SCHEMALOCATION))
    1273                     {
    1274                         // use anyURI as the validator
    1275                         // tokenize the data and use the anyURI data for each piece
    1276                         attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYURI);
    1277                         ValueValidate = false;
    1278                         tokenizeBuffer = true;
    1279                     }
    1280                     else if (XMLString::equals(localPart, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCATION))
    1281                     {
    1282                         attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYURI);
    1283                         ValueValidate = false;
    1284                     }
    1285                     else if (XMLString::equals(localPart, SchemaSymbols::fgXSI_TYPE))
    1286                     {
    1287                         attrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_QNAME);
    1288                         ValueValidate = true;
    1289                     }
    1290                     else
    1291                     {
    1292                         otherXSI = true;
    1293                     }
    1294                 }
    1295 
    1296                 if (!otherXSI)
    1297                 {
    1298                     if (fValidate && attrValidator && ValueValidate)
    1299                     {
    1300                         ValidationContext* const theContext = getValidationContext();
    1301 
    1302                         if (theContext)
    1303                         {
    1304                             try
    1305                             {
    1306                                 if (tokenizeBuffer)
    1307                                 {
    1308                                     XMLStringTokenizer tokenizer(value, fMemoryManager);
    1309                                     while (tokenizer.hasMoreTokens())
     784                                    XMLElementDecl * temp = findElementDecl(element, XMLNamespaceResolver::fEmptyUriId, currentScope, fGrammar);
     785                                    if (temp && temp->getCreateReason() != XMLElementDecl::JustFaultIn && fValidate)
    1310786                                    {
    1311                                         attrValidator->validate
    1312                                         (
    1313                                             tokenizer.nextToken(),
    1314                                             theContext,
    1315                                             fMemoryManager
    1316                                         );
    1317                                     }
    1318                                 }
    1319                                 else
    1320                                 {
    1321                                     attrValidator->validate
    1322                                     (
    1323                                         value,
    1324                                         theContext,
    1325                                         fMemoryManager
    1326                                     );
    1327                                 }
    1328                             }
    1329                             catch (const XMLException& idve)
    1330                             {
    1331                                 fValidator->emitError(XMLValid::DatatypeError, idve.getCode(), idve.getMessage());
    1332                             }
    1333                         }
    1334                     }
    1335 
    1336                     if (getPSVIHandler())
    1337                     {
    1338                         psviAttr = fPSVIAttrList->getPSVIAttributeToFill(localPart, fUriResolver->getUriForId(attributeUriId));
    1339 
    1340                         XSSimpleTypeDefinition *validatingType = (attrValidator)
    1341                             ? (XSSimpleTypeDefinition *)fModel->getXSObject(attrValidator)
    1342                             : 0;
    1343                         // no attribute declarations for these...
    1344                         psviAttr->reset
    1345                         (
    1346                             fRootElemName
    1347                             , PSVIItem::VALIDITY_NOTKNOWN
    1348                             , PSVIItem::VALIDATION_NONE
    1349                             , validatingType
    1350                             , 0
    1351                             , 0
    1352                             , false
    1353                             , 0
    1354                             , attrValidator
    1355                         );
    1356                     }
    1357                 }
    1358             } // if (isNamespaceAttribute && (fGrammarType == Grammar::SchemaGrammarType))
    1359 
    1360             if (likely(!isNamespaceAttribute || fGrammarType == Grammar::DTDGrammarType || otherXSI))
    1361             {
    1362                 // Some checking for attribute wild card first (for schema)
    1363                 bool laxThisOne = false;
    1364                 bool skipThisOne = false;
    1365 
    1366                 XMLAttDef * attDefForWildCard = 0;
    1367                 XMLAttDef * attDef = 0;
    1368 
    1369                 if (fGrammarType == Grammar::SchemaGrammarType)
    1370                 {
    1371                     ComplexTypeInfo *currType = 0;
    1372                     DatatypeValidator *currDV = 0;
    1373 
    1374                     if (fValidate)
    1375                     {
    1376                         currType = fSchemaValidator->getCurrentTypeInfo();
    1377                         if (!currType)
    1378                         {
    1379                             currDV = fSchemaValidator->getCurrentDatatypeValidator();
    1380                         }
    1381                     }
    1382 
    1383                     //retrieve the att def
    1384                     SchemaAttDef* attWildCard = 0;
    1385                     if (currType)
    1386                     {
    1387                         attDef = currType->getAttDef(localPart, attributeUriId);
    1388                         attWildCard = currType->getAttWildCard();
    1389                     }
    1390                     else if (!currDV)
    1391                     { // check explicitly-set wildcard
    1392                         attDef = ((SchemaElementDecl*)elemDecl)->getAttDef(localPart, attributeUriId);
    1393                         attWildCard = ((SchemaElementDecl*)elemDecl)->getAttWildCard();
    1394                     }
    1395 
    1396                     // if not found or faulted in - check for a matching wildcard attribute
    1397                     // if no matching wildcard attribute, check (un)qualifed cases and flag
    1398                     // appropriate errors
    1399                     if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn))
    1400                     {
    1401                         if (attWildCard)
    1402                         {
    1403                             //if schema, see if we should lax or skip the validation of this attribute
    1404                             if (anyAttributeValidation(attWildCard, attributeUriId, skipThisOne, laxThisOne))
    1405                             {
    1406                                 if (!skipThisOne)
    1407                                 {
    1408                                     Grammar* sGrammar = fGrammarList.getGrammar(attributeUriId);
    1409                                     if (unlikely(sGrammar == NULL))
    1410                                     {
    1411                                         sGrammar = fGrammarResolver->getGrammar((*fUriResolver)[attributeUriId]);
    1412                                         fGrammarList.setGrammar(attributeUriId, sGrammar);
    1413                                     }
    1414 
    1415                                     if (sGrammar && sGrammar->getGrammarType() == Grammar::SchemaGrammarType)
    1416                                     {
    1417                                         RefHashTableOf<XMLAttDef>* attRegistry = ((SchemaGrammar*)sGrammar)->getAttributeDeclRegistry();
    1418 
    1419                                         if (attRegistry)
    1420                                         {
    1421                                             attDefForWildCard = attRegistry->get(localPart);
    1422                                         }
     787                                        fSchemaValidator->emitError(XMLValid::ElementNotUnQualified, element.getName());
     788                                        elemDecl = temp;
     789                                        uriId = XMLNamespaceResolver::fEmptyUriId;
    1423790                                    }
    1424791                                }
    1425792                            }
    1426                             #ifdef __GNUC__
    1427                             #warning "INVESTIGATE: can I set attDef to attWildCard to simplify the logic below?"
    1428                             #endif
    1429                         }
    1430                         else if (currType)
    1431                         {
    1432                             // not found, see if the attDef should be qualified or not
    1433                             attDef = currType->getAttDef
    1434                             (
    1435                                 localPart
    1436                                 , attributeUriId == XMLNamespaceResolver::fEmptyUriId
    1437                                 ? fUriResolver->resolveUriId(fGrammar->getTargetNamespace())
    1438                                 : XMLNamespaceResolver::fEmptyUriId
    1439                             );
    1440 
    1441                             if (fValidate && attDef && attDef->getCreateReason() != XMLAttDef::JustFaultIn)
     793                            else if (uriId == XMLNamespaceResolver::fEmptyUriId)
    1442794                            {
    1443                                 XMLValid::Codes errCode =
    1444                                     (attributeUriId == XMLNamespaceResolver::fEmptyUriId)
    1445                                     ? XMLValid::AttributeNotQualified
    1446                                     : XMLValid::AttributeNotUnQualified;
    1447 
    1448                                 fValidator->emitError(errCode, attDef->getFullName());
    1449 
    1450                                 fPSVIElemContext.fErrorOccurred = true;
    1451                                 if (getPSVIHandler())
     795                                // still Not found in specified uri
     796                                // go to original Grammar again to see if element needs
     797                                // to be fully qualified.
     798                                // Use a temp variable until we decide this is the case
     799
     800                                if (originalGrammar)
    1452801                                {
    1453                                     attrValid = PSVIItem::VALIDITY_INVALID;
     802                                    XMLElementDecl * temp = findElementDecl(element, grammarUriId, currentScope, originalGrammar);
     803                                    if (temp && temp->getCreateReason() != XMLElementDecl::JustFaultIn)
     804                                    {
     805                                        fSchemaValidator->emitError(XMLValid::ElementNotQualified, element.getName());
     806                                        fGrammar = originalGrammar;
     807                                        fGrammarType = Grammar::SchemaGrammarType;
     808                                        fValidator = fSchemaValidator;
     809                                        uriId = grammarUriId;
     810                                        elemDecl = temp;
     811                                    }
    1454812                                }
    1455                             }
    1456                         }
    1457                     } // if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn))
    1458                 }
    1459                 else // if (fGrammarType == Grammar::DTDGrammarType)
    1460                 {
    1461                     //  Find this attribute within the parent element. We pass both
    1462                     //  the uriID/name and the raw QName buffer, since we don't know
    1463                     //  how the derived validator and its elements store attributes.
    1464                     attDef = ((DTDElementDecl*)elemDecl)->getAttDef(qName->getRawName());
    1465                 }
    1466 
    1467                 if (attDef)
    1468                 {
    1469                     attDef->setLastOccurrence(element->fLastOccurence);
    1470 
    1471                     if (unlikely(attDef->getDefaultType() == XMLAttDef::Prohibited && fValidate)) // attribute was provided for this definition
    1472                     {
    1473                         // TODO: is it safe to move the prohibited attribute validation into the attribute scan?
    1474 
    1475                         // (schema) report error for PROHIBITED attrs that are present (V_TAGc)
    1476                         fValidator->emitError(XMLValid::ProhibitedAttributePresent, attDef->getFullName());
    1477 
    1478                         if ((fGrammarType == Grammar::SchemaGrammarType))
    1479                         {
    1480                             fPSVIElemContext.fErrorOccurred = true;
    1481                             if (getPSVIHandler())
    1482                             {
    1483                                 QName * attQName = ((SchemaAttDef *)attDef)->getAttName();
    1484                                 // bad luck...
    1485                                 PSVIAttribute *prohibitedAttr = fPSVIAttrList->getAttributePSVIByName
    1486                                 (
    1487                                     attQName->getLocalPart(), fUriResolver->getUriForId(attributeUriId)
    1488                                 );
    1489                                 prohibitedAttr->updateValidity(PSVIItem::VALIDITY_INVALID);
    1490                             }
    1491                         }
    1492                     }
    1493                 }
    1494                 else // if (!attDef)
    1495                 {
    1496                     if (fGrammarType == Grammar::SchemaGrammarType)
    1497                     {
    1498                         // if we've found either an attDef or an attDefForWildCard,
    1499                         // then we're doing full validation and it may still be valid.
    1500                         if (!attDefForWildCard)
    1501                         {
    1502                             fPSVIElemContext.fErrorOccurred |= !(laxThisOne & skipThisOne);
    1503 
    1504                             if (getPSVIHandler())
    1505                             {
    1506                                 if (!laxThisOne && !skipThisOne)
     813                                else if (!laxThisOne)
    1507814                                {
    1508                                     attrValid = PSVIItem::VALIDITY_INVALID;
    1509                                 }
    1510                                 else
    1511                                 {
    1512                                     attrValid = PSVIItem::VALIDITY_NOTKNOWN;
    1513                                     attrAssessed = (laxThisOne) ? PSVIItem::VALIDATION_PARTIAL : PSVIItem::VALIDATION_NONE;
     815                                    fSchemaValidator->emitError(XMLValid::GrammarNotFound, originalGrammar->getTargetNamespace());
    1514816                                }
    1515817                            }
     
    1517819                    }
    1518820
    1519                     if (unlikely(fValidate && !attDefForWildCard && !skipThisOne && !laxThisOne))
     821                    if (unlikely(elemDecl == 0))
    1520822                    {
    1521                         //
    1522                         //  Its not valid for this element, so issue an error if we are
    1523                         //  validating.
    1524                         //
    1525                         XMLBuffer bufMsg;
    1526                         if (attributeUriId != XMLNamespaceResolver::fEmptyUriId)
     823                        DEBUG_GRAMMAR_MESSAGE("fSchemaElemNonDeclPool->getByKey(" << element.getQName()->getLocalPart() << ',' << uriId << ',' << Grammar::TOP_LEVEL_SCOPE << ')')
     824
     825                        fGrammar = originalGrammar;
     826                        fGrammarType = Grammar::SchemaGrammarType;
     827                        fValidator = fSchemaValidator;
     828                        // look in the list of undeclared elements, as would have been
     829                        // done before we made grammars stateless:
     830                        elemDecl = fSchemaElemNonDeclPool->getByKey(element.getQName()->getLocalPart(), uriId, (int)Grammar::TOP_LEVEL_SCOPE);
     831                    }
     832                }
     833
     834                if (unlikely(elemDecl == 0))
     835                {
     836                    //  Could not find the element declaration; fault one in.
     837                    elemDecl = new (fMemoryManager) SchemaElementDecl(element.getQName(), SchemaElementDecl::Any, Grammar::TOP_LEVEL_SCOPE, fMemoryManager);
     838                    elemDecl->setId(fSchemaElemNonDeclPool->put((void*)elemDecl->getBaseName(), uriId, (int)Grammar::TOP_LEVEL_SCOPE, (SchemaElementDecl*)elemDecl));
     839                    elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
     840                    element.setElemDecl(uriId, currentScope, elemDecl);
     841                    wasAdded = true;
     842                }
     843
     844                element.setElemDecl(uriId, currentScope, elemDecl);
     845            }
     846        }
     847        else // if (fGrammarType == Grammar::DTDGrammarType)
     848        {
     849            elemDecl = findElementDecl(element, uriId, Grammar::TOP_LEVEL_SCOPE, fDTDGrammar);
     850            if (unlikely(elemDecl == 0))
     851            {
     852                elemDecl = fDTDElemNonDeclPool->getByKey(element.getName());
     853                if (fDoSchema)
     854                {
     855                    if (unlikely(!switchGrammar(uriId)))
     856                    {
     857                        fDTDValidator->emitError(XMLValid::GrammarNotFound, fUriResolver->getUriForId(uriId));
     858                    }
     859                }
     860                if (unlikely(elemDecl == 0))
     861                {
     862                    //  Could not find the element declaration; fault one in.
     863                    elemDecl = new (fMemoryManager) DTDElementDecl(element.getQName(), DTDElementDecl::Any, fMemoryManager);
     864                    elemDecl->setId(fDTDElemNonDeclPool->put((DTDElementDecl*)elemDecl));
     865                    elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);
     866                    wasAdded = true;
     867                }
     868
     869                element.setElemDecl(uriId, Grammar::TOP_LEVEL_SCOPE, elemDecl);
     870            }
     871            fValidate &= !fSkipDTDValidation;
     872        }
     873
     874
     875        if (!elemDecl->isDeclared())
     876        {
     877            DEBUG_GRAMMAR_MESSAGE(" --- faulting element in! laxThisOne=" << laxThisOne << " bXsiTypeSet=" << bXsiTypeSet)
     878
     879            if (laxThisOne && !bXsiTypeSet)
     880            {
     881                fValidate = false;
     882            }
     883            else if (fValidate)
     884            {
     885                // if xsi:type was specified, don't complain about missing definition
     886                if (!bXsiTypeSet)
     887                {
     888                    fValidator->emitError(XMLValid::ElementNotDefined, elemDecl->getFullName());
     889                    fPSVIElemContext.fErrorOccurred = true;
     890                }
     891            }
     892        }
     893
     894        //  Now we can update the element stack to set the current element decl.
     895        const XMLSize_t elemDepth = fElemStack.addLevel(elemDecl, 0);
     896
     897        //  Validate the element       
     898        if (fGrammarType == Grammar::SchemaGrammarType)
     899        {
     900            ComplexTypeInfo * typeInfo;
     901            if (fValidate)
     902            {
     903                fSchemaValidator->validateElement(elemDecl);
     904                fPSVIElemContext.fErrorOccurred |= fSchemaValidator->getErrorOccurred();
     905                typeInfo = fSchemaValidator->getCurrentTypeInfo();
     906            }
     907            else
     908            {
     909                typeInfo = ((SchemaElementDecl*)elemDecl)->getComplexTypeInfo();
     910            }
     911
     912            if (typeInfo)
     913            {
     914                currentScope = typeInfo->getScopeDefined();
     915                // switch grammar if the typeinfo has a different grammar (happens when there is xsi:type)
     916                XMLCh* typeName = typeInfo->getTypeName();
     917                const int comma = XMLString::indexOf(typeName, chComma);
     918                if (comma > 0)
     919                {
     920                    XMLBuffer prefixBuf(comma + 1, fMemoryManager);
     921                    prefixBuf.set(typeName, comma);
     922                    const XMLCh* uri = prefixBuf.getRawBuffer();
     923                    bool switched = switchGrammar(uri);
     924                    if (!switched && !laxThisOne && fValidate)
     925                    {
     926                        fSchemaValidator->emitError(XMLValid::GrammarNotFound, uri);
     927                    }
     928                }
     929                else if (comma == 0)
     930                {
     931                    bool switched = switchGrammar(XMLNamespaceResolver::fEmptyUriId);
     932                    if (!switched && !laxThisOne && fValidate)
     933                    {
     934                        fSchemaValidator->emitError(XMLValid::GrammarNotFound, XMLUni::fgZeroLenString);
     935                    }
     936                }
     937            }
     938
     939            fElemStack.setCurrentScope(currentScope);
     940
     941            // Set element next state
     942            if (unlikely(elemDepth >= fElemStateSize))
     943            {
     944                resizeElemState();
     945            }
     946
     947            fElemState[elemDepth] = 0;
     948            fElemLoopState[elemDepth] = 0;
     949        }
     950        else if (fValidate) // && fGrammarType == Grammar::DTDGrammarType
     951        {
     952            fDTDValidator->validateElement(elemDecl);
     953        }
     954
     955        fElemStack.setCurrentGrammar(fGrammar);       
     956    }
     957
     958    fElemStack.setValidationFlag(fValidate);
     959
     960    //  If this is the first element and we are validating, check the root element.
     961    if (unlikely(isRoot))
     962    {
     963        fRootGrammar = fGrammar;
     964        if (fRootElemName)
     965        {
     966            bool validRootName = (!fValidate || XMLString::equals(element.getName(), fRootElemName));
     967            if (unlikely(!validRootName))
     968            {
     969                fValidator->emitError(XMLValid::RootElemNotLikeDocType);
     970            }
     971        }
     972        else
     973        {
     974            setRootElemName(const_cast<XMLCh*>(element.getName()));
     975        }
     976    }
     977
     978    assert (elemDecl != 0);
     979
     980    return *elemDecl;
     981}
     982
     983XMLElementDecl * IGXMLScanner::findElementDecl(XMLSymbol & element, unsigned int uriId, unsigned int scope, Grammar * grammar)
     984{   
     985    size_t index;
     986    XMLElementDecl * elemDecl = element.getElemDecl(uriId, scope, index);
     987    if (unlikely(elemDecl == 0))
     988    {
     989        assert (grammar != 0);
     990        elemDecl = grammar->getElemDecl(uriId, element.getQName()->getLocalPart(), element.getQName()->getRawName(), scope);
     991        if (elemDecl)
     992        {
     993            element.setElemDecl(index, uriId, scope, elemDecl);
     994        }
     995    }
     996    return elemDecl;
     997}
     998
     999bool IGXMLScanner::validateAttribute
     1000(
     1001      XMLElementDecl &              elemDecl
     1002    , const XMLSize_t               elementCount
     1003    , const XMLSymbol &             attribute
     1004    , const unsigned int            uriId
     1005    , const XMLCh *                 value
     1006    , XMLSize_t                     length
     1007    , const MarkupType              type
     1008    , const Grammar::GrammarType    grammarType
     1009    , const bool                    doPSVI
     1010    , XMLDocumentAccumulator &      parser
     1011    , const bool                    write
     1012)
     1013{
     1014    XMLAttDef::AttTypes attType = XMLAttDef::CData;
     1015
     1016    if (unlikely(grammarType == Grammar::DTDGrammarType))
     1017    {
     1018        //  See if this attribute is declared for this element. If we are
     1019        //  not validating of course it will not be at first, but we will
     1020        //  fault it into the pool (to avoid lots of redundant errors.)
     1021        DTDElementDecl & dtdElemDecl = reinterpret_cast<DTDElementDecl&>(elemDecl);
     1022
     1023        DTDAttDef * attDef = dtdElemDecl.getAttDef(attribute.getName());
     1024
     1025        //  Add this attribute to the attribute list that we use to
     1026        //  pass them to the handler. We reuse its existing elements
     1027        //  but expand it as required.
     1028
     1029        // Note that we want to this first since this will
     1030        // make a copy of the namePtr; we can then make use of
     1031        // that copy in the hashtable lookup that checks
     1032        // for duplicates.  This will mean we may have to update
     1033        // the type of the XMLAttr later.
     1034
     1035        bool tokenized = false;
     1036
     1037        if (unlikely(attDef == 0))
     1038        {
     1039            //  If there is a validation handler, then we are validating so emit an error.
     1040            if (fValidate)
     1041            {
     1042                fDTDValidator->emitError(XMLValid::AttNotDefinedForElement, attribute.getName(), dtdElemDecl.getFullName());
     1043            }
     1044        }
     1045        else
     1046        {
     1047            // prepare for duplicate detection
     1048            attDef->setLastOccurrence(elementCount);
     1049            attType = attDef->getType();
     1050
     1051            // check to see if we need to tokenize the value
     1052            if (unlikely(attType != XMLAttDef::CData && attType <= XMLAttDef::Enumeration))
     1053            {
     1054                tokenized = tokenizeAttributeValue(value, length, fWSNormalizeBuf);
     1055                if (unlikely(tokenized))
     1056                {
     1057                    if (unlikely(fStandalone && fValidate && attDef->isExternal()))
     1058                    {
     1059                        // Can't have a standalone document declaration of "yes" if  attribute
     1060                        // values are subject to normalisation
     1061                        fValidator->emitError(XMLValid::NoAttNormForStandalone, attDef->getFullName());
     1062                    }
     1063                    value = fWSNormalizeBuf.getRawBuffer();
     1064                    length = fWSNormalizeBuf.getLen();
     1065                }
     1066            }
     1067
     1068            if (fValidate)
     1069            {
     1070                if (unlikely(attDef->getDefaultType() == XMLAttDef::Prohibited))
     1071                {
     1072                    // (schema) report error for PROHIBITED attrs that are present (V_TAGc)
     1073                    fDTDValidator->emitError(XMLValid::ProhibitedAttributePresent, attDef->getFullName());
     1074                }
     1075
     1076                // Let the validator pass judgement on the attribute value
     1077                fDTDValidator->validateAttrValue(attDef, value, false, &dtdElemDecl);
     1078            }
     1079        }
     1080
     1081        if (unlikely(type & Surpressed)) return 0;
     1082
     1083        parser.writeAttribute(attribute.getQName(), attType, uriId, value, length, type, write | tokenized);
     1084    }
     1085    else // if (fDoNamespaces)
     1086    {
     1087        SchemaElementDecl & schemaElemDecl = ((SchemaElementDecl&)elemDecl);
     1088        SchemaAttDef * attDef = 0;
     1089        const QName * attName = attribute.getQName();
     1090        PSVIItem::VALIDITY_STATE attrValid = PSVIItem::VALIDITY_VALID;
     1091        PSVIItem::ASSESSMENT_TYPE attrAssessed = PSVIItem::VALIDATION_FULL;
     1092        DatatypeValidator * attrValidator = 0;       
     1093        bool normalized = false;
     1094
     1095        //  If the uri comes back as the xmlns or xml URI or its just a name
     1096        //  and that name is 'xmlns', then we handle it specially. So set a
     1097        //  boolean flag that lets us quickly below know which we are dealing
     1098        //  with.
     1099
     1100        const bool isXSI = (uriId == XMLNamespaceResolver::fSchemaInstanceUriId);
     1101        const bool isXMLNS = (uriId == XMLNamespaceResolver::fXMLNSUriId);
     1102        bool isNamespaceAttribute = (isXSI | isXMLNS);
     1103
     1104        if (unlikely(isNamespaceAttribute))
     1105        {
     1106            isNamespaceAttribute = checkNamespaceAttribute(attribute, value, elemDecl.isDeclared(), attrValidator);
     1107            if (likely(isNamespaceAttribute))
     1108            {
     1109                attrValid = PSVIItem::VALIDITY_NOTKNOWN;
     1110                attrAssessed = PSVIItem::VALIDATION_NONE;
     1111                if (type & Surpressed) return 0;
     1112            }
     1113        }
     1114
     1115        if (likely(!isNamespaceAttribute))
     1116        {
     1117            // Some checking for attribute wild card first (for schema)
     1118            bool laxThisOne = false;
     1119            bool skipThisOne = false;
     1120
     1121            ComplexTypeInfo *currType = 0;
     1122            DatatypeValidator *currDV = 0;
     1123
     1124            const XMLCh* const localPart = attName->getLocalPart();
     1125
     1126            if (fValidate)
     1127            {
     1128                currType = fSchemaValidator->getCurrentTypeInfo();
     1129                if (!currType)
     1130                {
     1131                    currDV = fSchemaValidator->getCurrentDatatypeValidator();
     1132                }
     1133            }
     1134
     1135            //retrieve the att def
     1136            SchemaAttDef* attWildCard = 0;
     1137            if (currType)
     1138            {
     1139                attDef = currType->getAttDef(localPart, uriId);
     1140                attWildCard = currType->getAttWildCard();
     1141            }
     1142            else if (!currDV)
     1143            {
     1144                // check explicitly-set wildcard
     1145                attDef = schemaElemDecl.getAttDef(localPart, uriId);
     1146                attWildCard = schemaElemDecl.getAttWildCard();
     1147            }
     1148
     1149            // if not found or faulted in - check for a matching wildcard attribute
     1150            // if no matching wildcard attribute, check (un)qualifed cases and flag
     1151            // appropriate errors
     1152            if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn))
     1153            {
     1154                if (attWildCard)
     1155                {
     1156                    //if schema, see if we should lax or skip the validation of this attribute
     1157                    if (anyAttributeValidation(attWildCard, uriId, skipThisOne, laxThisOne))
     1158                    {
     1159                        if (!skipThisOne)
    15271160                        {
    1528                             bufMsg.append(chOpenCurly);
    1529                             bufMsg.append(fUriResolver->getUriForId(attributeUriId));
    1530                             bufMsg.append(chCloseCurly);
    1531                         }
    1532                         bufMsg.append(localPart);
    1533                         fValidator->emitError
    1534                         (
    1535                             XMLValid::AttNotDefinedForElement
    1536                             , bufMsg.getRawBuffer()
    1537                             , element->getQName()->getLocalPart()
    1538                         );
    1539                     }
    1540                 }
    1541 
    1542                 /// VALIDATE THE ATTRIBUTE VALUE BASED ON THE DEFINITION
    1543 
    1544                 if (attDefForWildCard)
    1545                 {
    1546                     validateAttValue(elemDecl, attDefForWildCard, value, attrValidator, attrValid, attType);
    1547                 }
    1548                 else if (attDef)
    1549                 {
    1550                     validateAttValue(elemDecl, attDef, value, attrValidator, attrValid, attType);
    1551                 }
    1552                 else if (fGrammarType == Grammar::SchemaGrammarType)
    1553                 {
    1554                     attrValidator = getAnySimpleTypeValidator();
    1555                 }
    1556 
    1557 
    1558                 // now fill in the PSVIAttributes entry for this attribute:
    1559                 if (getPSVIHandler() && (fGrammarType == Grammar::SchemaGrammarType))
    1560                 {
    1561                     psviAttr = fPSVIAttrList->getPSVIAttributeToFill(localPart, fUriResolver->getUriForId(attributeUriId));
    1562                     SchemaAttDef * actualAttDef = 0;
    1563                     if (attDef)
    1564                         actualAttDef = (SchemaAttDef*)attDef;
    1565                     else if (attDefForWildCard)
    1566                         actualAttDef = (SchemaAttDef*)attDefForWildCard;
    1567 
    1568                     if (actualAttDef)
    1569                     {
    1570                         XSAttributeDeclaration *attrDecl = (XSAttributeDeclaration *)fModel->getXSObject(actualAttDef);
    1571                         DatatypeValidator * attrDataType = actualAttDef->getDatatypeValidator();
    1572                         XSSimpleTypeDefinition *validatingType = (XSSimpleTypeDefinition *)fModel->getXSObject(attrDataType);
    1573                         if (attrValid != PSVIItem::VALIDITY_VALID)
    1574                         {
    1575                             psviAttr->reset
    1576                             (
    1577                                 fRootElemName
    1578                                 , attrValid
    1579                                 , attrAssessed
    1580                                 , validatingType
    1581                                 , 0
    1582                                 , actualAttDef->getValue()
    1583                                 , false
    1584                                 , attrDecl
    1585                                 , 0
    1586                             );
    1587                         }
    1588                         else
    1589                         {
    1590                             XSSimpleTypeDefinition *memberType = 0;
    1591                             if (validatingType->getVariety() == XSSimpleTypeDefinition::VARIETY_UNION)
    1592                                 memberType = (XSSimpleTypeDefinition *)fModel->getXSObject(attrValidator);
    1593                             psviAttr->reset
    1594                             (
    1595                                 fRootElemName
    1596                                 , attrValid
    1597                                 , attrAssessed
    1598                                 , validatingType
    1599                                 , memberType
    1600                                 , actualAttDef->getValue()
    1601                                 , false
    1602                                 , attrDecl
    1603                                 , (memberType) ? attrValidator : attrDataType
    1604                             );
     1161                            Grammar* sGrammar = fGrammarList.getGrammar(uriId);
     1162                            if (unlikely(sGrammar == NULL))
     1163                            {
     1164                                sGrammar = fGrammarResolver->getGrammar((*fUriResolver)[uriId]);
     1165                                fGrammarList.setGrammar(uriId, sGrammar);
     1166                            }
     1167
     1168                            if (sGrammar && sGrammar->getGrammarType() == Grammar::SchemaGrammarType)
     1169                            {
     1170                                RefHashTableOf<XMLAttDef>* attRegistry = ((SchemaGrammar*)sGrammar)->getAttributeDeclRegistry();
     1171                                if (attRegistry)
     1172                                {
     1173                                    attDef = reinterpret_cast<SchemaAttDef *>(attRegistry->get(localPart));
     1174                                }
     1175                            }
    16051176                        }
    16061177                    }
    1607                     else
     1178                }
     1179                else if (currType)
     1180                {
     1181                    const unsigned int tempUriId =
     1182                        (uriId == XMLNamespaceResolver::fEmptyUriId)
     1183                            ? fUriResolver->resolveUriId(fGrammar->getTargetNamespace()) // NOTE: should this just be elementUriId? verify!
     1184                            : XMLNamespaceResolver::fEmptyUriId;
     1185
     1186                    // not found, see if the attDef should be qualified or not
     1187                    attDef = currType->getAttDef(localPart, tempUriId);
     1188
     1189                    if (unlikely(attDef && attDef->getCreateReason() != XMLAttDef::JustFaultIn) && fValidate)
    16081190                    {
    1609                         psviAttr->reset
    1610                         (
    1611                             fRootElemName
    1612                             , attrValid
    1613                             , attrAssessed
    1614                             , 0
    1615                             , 0
    1616                             , 0
    1617                             , false
    1618                             , 0
    1619                             , 0
    1620                         );
     1191                        XMLValid::Codes errCode =
     1192                            (uriId == XMLNamespaceResolver::fEmptyUriId)
     1193                            ? XMLValid::AttributeNotQualified
     1194                            : XMLValid::AttributeNotUnQualified;
     1195
     1196                        fSchemaValidator->emitError(errCode, attDef->getFullName());
     1197                        fPSVIElemContext.fErrorOccurred = true;
     1198                        attrValid = PSVIItem::VALIDITY_INVALID;
    16211199                    }
    16221200                }
    1623             }
    1624         } // end of if (fDoNamespaces) { ... } else { ... }
    1625 
    1626         #ifdef __GNUC__
    1627         #warning "TODO: move the fAttrList into the XMLParserImpl and construct them directly there with all the non-derived values set"
    1628         #endif
    1629         XMLAttr * curAttr;
    1630 
    1631         const XMLSize_t length = attributeItem.getLength();
    1632         const bool specified = attributeItem.getSpecified();
    1633 
    1634         if (unlikely(index >= fAttrList.size()))
    1635         {
    1636             curAttr = new (fMemoryManager) XMLAttr
    1637             (
    1638                 attribute->getQName()
    1639                 , value
    1640                 , length
    1641                 , attType
    1642                 , specified
    1643                 , fMemoryManager
    1644             );
    1645 
    1646             fAttrList.addElement(curAttr);
    1647         }
    1648         else
    1649         {
    1650             curAttr = fAttrList.elementAt(index);
    1651             curAttr->set
    1652             (
    1653                 attribute->getQName()
    1654                 , value
    1655                 , length
    1656                 , attType
    1657             );
    1658             curAttr->setSpecified(specified);
    1659         }
    1660 
    1661     }
    1662 
     1201            } // if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn))
     1202
     1203            if (attDef)
     1204            {
     1205                attDef->setLastOccurrence(elementCount);
     1206                attType = attDef->getType();
     1207                if (unlikely(attDef->getDefaultType() == XMLAttDef::Prohibited) && fValidate)
     1208                {
     1209                    // (schema) report error for PROHIBITED attrs that are present (V_TAGc)
     1210                    fSchemaValidator->emitError(XMLValid::ProhibitedAttributePresent, attDef->getFullName());
     1211                    fPSVIElemContext.fErrorOccurred = true;
     1212                    attrValid = PSVIItem::VALIDITY_INVALID;
     1213                }
     1214            }
     1215            else // if (!attDef && !attDefForWildCard)
     1216            {
     1217                if (unlikely(fValidate && !isNamespaceAttribute && !(laxThisOne | skipThisOne)))
     1218                {
     1219                    fPSVIElemContext.fErrorOccurred = true;
     1220                    attrValid = PSVIItem::VALIDITY_INVALID;
     1221                    reportUndefinedAttribute(uriId, attribute.getQName(), schemaElemDecl);
     1222                }
     1223                else
     1224                {
     1225                    attrValid = PSVIItem::VALIDITY_NOTKNOWN;
     1226                    attrAssessed = (laxThisOne) ? PSVIItem::VALIDATION_PARTIAL : PSVIItem::VALIDATION_NONE;
     1227                }
     1228            }
     1229
     1230            /// VALIDATE THE ATTRIBUTE VALUE BASED ON THE DEFINITION
     1231            if (attDef && fValidate)
     1232            {
     1233                //  Normalize the raw value since we have the attribute type. We
     1234                //  don't care about the return status here. If it failed, an error
     1235                //  will be issued, which is all we care about.
     1236
     1237                const XMLCh * normalizedValue = value;
     1238                XMLSize_t normalizedLength = length;
     1239
     1240                DatatypeValidator* tempDV = attDef->getDatatypeValidator();
     1241                if (tempDV && tempDV->getWSFacet() != DatatypeValidator::PRESERVE)
     1242                {
     1243                    fSchemaValidator->normalizeWhiteSpace(tempDV->getWSFacet(), value, fWSNormalizeBuf, length, true);
     1244                    normalizedValue = fWSNormalizeBuf.getRawBuffer();
     1245                    normalizedLength = fWSNormalizeBuf.getLen();
     1246                }
     1247
     1248                fSchemaValidator->validateAttrValue(attDef, normalizedValue, false, &schemaElemDecl);
     1249
     1250                attrValidator = fSchemaValidator->getMostRecentAttrValidator();
     1251
     1252                if (unlikely(fSchemaValidator->getErrorOccurred()))
     1253                {
     1254                    fPSVIElemContext.fErrorOccurred = true;
     1255                    attrValid = PSVIItem::VALIDITY_INVALID;
     1256                }
     1257
     1258                if (fNormalizeData)
     1259                {
     1260                    value = normalizedValue;
     1261                    length = normalizedLength;
     1262                    normalized = true;
     1263                }
     1264            }
     1265            else
     1266            {   // no decl; default DOMTypeInfo to anySimpleType
     1267                attrValidator = getAnySimpleTypeValidator();
     1268            }
     1269        }
     1270
     1271        parser.writeAttribute(attName, attType, uriId, value, length, type, normalized | write);
     1272
     1273        if (doPSVI)
     1274        {
     1275            XSAttributeDeclaration * attrDecl = 0;
     1276            XSSimpleTypeDefinition * memberType = 0;
     1277            XSSimpleTypeDefinition * validatingType = 0;
     1278            DatatypeValidator * dataValidator = 0;
     1279            if (attDef)
     1280            {
     1281                attrDecl = (XSAttributeDeclaration *)fModel->getXSObject(attDef);
     1282                DatatypeValidator * attrDataType = attDef->getDatatypeValidator();
     1283                validatingType = (XSSimpleTypeDefinition *)fModel->getXSObject(attrDataType);
     1284                if (attrValid == PSVIItem::VALIDITY_VALID)
     1285                {
     1286                    if (validatingType->getVariety() == XSSimpleTypeDefinition::VARIETY_UNION)
     1287                    {
     1288                        memberType = (XSSimpleTypeDefinition *)fModel->getXSObject(attrValidator);
     1289                        dataValidator = (memberType) ? attrValidator : attrDataType;
     1290                    }
     1291                }
     1292            }
     1293            parser.writeAttributePSVI(attrDecl, memberType, validatingType, attrValid, attrAssessed, dataValidator);
     1294        }
     1295    }
     1296    return 1;
     1297}
     1298
     1299XMLSize_t IGXMLScanner::postAttributeValidation
     1300(
     1301      XMLElementDecl &              elemDecl
     1302    , const QName *                 elemName
     1303    , const XMLSize_t               elementCount
     1304    , XMLSize_t                     attributeCount
     1305    , const unsigned int            uriId
     1306    , const bool                                        isRoot
     1307    , const bool                                        isEmpty
     1308    , const Grammar::GrammarType    grammarType
     1309    , const bool                    doPSVI
     1310    , XMLDocumentAccumulator &      parser
     1311)
     1312{
    16631313    /// ------------------------------ POST ATTRIBUTE VALIDATION ---------------------------------
    16641314
    1665     if (!fDoNamespaces)
    1666     {
    1667         //  Ok, so lets get an enumerator for the attributes of this element
    1668         //  and run through them for well formedness and validity checks. But
    1669         //  make sure that we had any attributes before we do it, since the list
    1670         //  would have have gotten faulted in anyway.
    1671         if (elemDecl->hasAttDefs())
    1672         {
    1673             // N.B.:  this assumes DTD validation.
    1674             XMLAttDefList & attDefList = elemDecl->getAttDefList();
    1675             for(XMLSize_t i = 0; i < attDefList.getAttDefCount(); i++)
    1676             {
    1677                 // Get the current att def, for convenience and its def type
    1678                 const XMLAttDef & curDef = attDefList.getAttDef(i);
    1679                 const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
    1680 
    1681                 if (unlikely(curDef.getLastOccurrence() != element->fLastOccurence))
    1682                 { // did not occur
    1683                     if (fValidate)
     1315    if (fValidate)
     1316    {
     1317        if (grammarType == Grammar::DTDGrammarType)
     1318        {
     1319            DTDElementDecl & dtdElemDecl = reinterpret_cast<DTDElementDecl&>(elemDecl);
     1320
     1321            //  Ok, so lets get an enumerator for the attributes of this element
     1322            //  and run through them for well formedness and validity checks. But
     1323            //  make sure that we had any attributes before we do it, since the list
     1324            //  would have have gotten faulted in anyway.
     1325            if (unlikely(dtdElemDecl.hasAttDefs()))
     1326            {
     1327                const XMLAttDefList & attDefList = dtdElemDecl.getAttDefList();
     1328                size_t attDefCount = attDefList.getAttDefCount();
     1329
     1330                for (XMLSize_t i = 0; attDefCount--; i++)
     1331                {
     1332                    // Get the current att def, for convenience and its def type
     1333                    const DTDAttDef & attDef = (DTDAttDef &)attDefList.getAttDef(i);
     1334                    const XMLAttDef::DefAttTypes defType = attDef.getDefaultType();
     1335
     1336                    if (unlikely(attDef.getLastOccurrence() != elementCount))
    16841337                    {
    16851338                        // If we are validating and its required, then an error
    16861339                        if (defType == XMLAttDef::Required)
    16871340                        {
    1688                             fValidator->emitError(XMLValid::RequiredAttrNotProvided, curDef.getFullName());
    1689                         }
    1690                         else if ((defType == XMLAttDef::Default) || (defType == XMLAttDef::Fixed))
    1691                         {
    1692                             if (fStandalone && curDef.isExternal())
    1693                             {
    1694                                 // XML 1.0 Section 2.9
    1695                                 // Document is standalone, so attributes must not be defaulted.
    1696                                 fValidator->emitError(XMLValid::NoDefAttForStandalone, curDef.getFullName(), elemDecl->getFullName());
    1697                             }
     1341                            fDTDValidator->emitError(XMLValid::RequiredAttrNotProvided, attDef.getFullName());
    16981342                        }
    16991343                    }
    1700 
    1701                     #ifdef IGNORE_DEFAULT_ATTRIBUTES
    1702                     // Fault in the value if needed, and bump the att count
    1703                     if ((defType == XMLAttDef::Default) || (defType == XMLAttDef::Fixed))
    1704                     {
    1705                         // Let the validator pass judgement on the attribute value
    1706                         if (fValidate)
    1707                         {
    1708                             fValidator->validateAttrValue
    1709                             (
    1710                                 &curDef
    1711                                 , curDef.getValue()
    1712                                 , false
    1713                                 , elemDecl
    1714                             );
    1715                         }
    1716 
    1717                         XMLAttr * curAtt;
    1718                         if (attributeCount >= fAttrList.size())
    1719                         {
    1720                             curAtt = new (fMemoryManager) XMLAttr
    1721                             (
    1722                                 curDef.getAttName()
    1723                                 , curDef.getValue()
    1724                                 , curDef.getType()
    1725                                 , false
    1726                                 , fMemoryManager
    1727                             );
    1728                             fAttrList.addElement(curAtt);
    1729                         }
    1730                         else
    1731                         {
    1732                             curAtt = fAttrList.elementAt(attributeCount);
    1733                             curAtt->set
    1734                             (
    1735                                 curDef.getAttName()
    1736                                 , curDef.getValue()
    1737                                 , curDef.getType()
    1738                             );
    1739                             curAtt->setSpecified(false);
    1740                         }
    1741                         attributeCount++;
    1742                     }
    1743                     #endif
    1744                 }
    1745             }
    1746         }
    1747 
    1748         //  If empty, validate content right now if we are validating and then
    1749         //  pop the element stack top. Else, we have to update the current stack
    1750         //  top's namespace mapping elements.
    1751         if (isEmpty)
    1752         {
    1753             // If validating, then insure that its legal to have no content
    1754             if (fValidate)
    1755             {
    1756                 XMLSize_t failure;
    1757                 bool res = fValidator->checkContent(elemDecl, ((XMLElementDecl**)0), 0, &failure);
    1758                 if (!res)
    1759                 {
    1760                     fValidator->emitError
    1761                     (
    1762                         XMLValid::ElementNotValidForContent
    1763                         , elemDecl->getFullName()
    1764                         , elemDecl->getFormattedContentModel()
    1765                     );
    1766                 }
    1767             }
    1768 
    1769             // Pop the element stack back off since it'll never be used now
    1770             fElemStack.popTop();
    1771 
    1772             // If the elem stack is empty, then it was an empty root
    1773             if (!isRoot)
    1774             {
    1775                 // Restore the validation flag
    1776                 fValidate = fElemStack.getValidationFlag();
    1777             }
    1778         }
    1779 
    1780         //  If we have a document handler, then tell it about this start tag. We
    1781         //  don't have any URI id to send along, so send fEmptyNamespaceId. We also do not send
    1782         //  any prefix since its just one big name if we are not doing namespaces.
    1783         if (fDocHandler)
    1784         {
    1785             QName * origQName = elemDecl->getElementName();
    1786             elemDecl->setElementName(element->fQName);
    1787 
    1788             fDocHandler->startElement
    1789             (
    1790                 *elemDecl
    1791                 , XMLNamespaceResolver::fEmptyUriId
    1792                 , 0
    1793                 , fAttrList
    1794                 , attributeCount
    1795                 , isEmpty
    1796                 , isRoot
    1797             );
    1798 
    1799             elemDecl->setElementName(origQName);
    1800         }
    1801     }
    1802     else // if (fDoNamespaces)
    1803     {
    1804         const QName * qName = element->getQName();
    1805 
    1806         if (fValidate)
    1807         {
    1808             //  If doing DTD's, Ask the element to clear the 'provided' flag on all of the att defs
    1809             //  that it owns, and to return us a boolean indicating whether it has
    1810             //  any defs.  If schemas are being validated, the complexType
    1811             // at the top of the SchemaValidator's stack will
    1812             // know what's best.  REVISIT:  don't modify grammar at all; eliminate
    1813             // this step...
    1814 
     1344                }
     1345            }
     1346        }
     1347        else // if (fDoNamespaces && (grammarType == Grammar::SchemaGrammarType))
     1348        {
    18151349            ComplexTypeInfo * currType = 0;
    18161350            DatatypeValidator * currDV = 0;
    18171351
    1818             if (fGrammarType == Grammar::SchemaGrammarType)
    1819             {
    1820                 currType = fSchemaValidator->getCurrentTypeInfo();
    1821                 if (!currType)
    1822                 {
    1823                     currDV = fSchemaValidator->getCurrentDatatypeValidator();
    1824                 }
    1825             }
    1826 
    1827             const bool hasDefs = (currType) ? currType->hasAttDefs() : elemDecl->hasAttDefs();
     1352            SchemaElementDecl & schemaElemDecl = reinterpret_cast<SchemaElementDecl&>(elemDecl);
     1353
     1354            currType = fSchemaValidator->getCurrentTypeInfo();
     1355            if (!currType)
     1356            {
     1357                currDV = fSchemaValidator->getCurrentDatatypeValidator();
     1358            }
     1359
     1360            const bool hasDefs = (currType) ? currType->hasAttDefs() : schemaElemDecl.hasAttDefs();
    18281361
    18291362            //  Now, if there are any attributes declared by this element, let's
     
    18371370                // (2) add default attrs if missing (FIXED and NOT_FIXED)
    18381371
    1839                 XMLAttDefList & attDefList = getAttDefList((fGrammarType == Grammar::SchemaGrammarType), currType, elemDecl);
    1840 
    1841                 for(XMLSize_t i = 0; i < attDefList.getAttDefCount(); i++)
     1372                const XMLAttDefList & attDefList = (currType) ? currType->getAttDefList() : schemaElemDecl.getAttDefList();
     1373                size_t attDefCount = attDefList.getAttDefCount();
     1374
     1375                for (XMLSize_t i = 0; attDefCount--; i++)
    18421376                {
    18431377                    // Get the current att def, for convenience and its def type
    1844                     const XMLAttDef *curDef = &attDefList.getAttDef(i);
    1845                     const XMLAttDef::DefAttTypes defType = curDef->getDefaultType();
     1378                    const SchemaAttDef & attDef = (SchemaAttDef &)attDefList.getAttDef(i);
     1379                    const XMLAttDef::DefAttTypes defType = attDef.getDefaultType();
    18461380
    18471381                    // if this attribute is not present within the element
    1848                     if (unlikely(curDef->getLastOccurrence() != element->fLastOccurence))
     1382                    if (unlikely(attDef.getLastOccurrence() != elementCount))
    18491383                    {
    18501384                        // note that since there is no attribute information
     
    18551389                        if ((defType == XMLAttDef::Required) || (defType == XMLAttDef::Required_And_Fixed))
    18561390                        {
    1857                             fValidator->emitError(XMLValid::RequiredAttrNotProvided, curDef->getFullName());
    1858 
    1859                             if (fGrammarType == Grammar::SchemaGrammarType)
    1860                             {
    1861                                 fPSVIElemContext.fErrorOccurred = true;
    1862                             }
     1391                            fSchemaValidator->emitError(XMLValid::RequiredAttrNotProvided, attDef.getFullName());
     1392                            fPSVIElemContext.fErrorOccurred = true;
    18631393                        }
    18641394                        else if ((defType == XMLAttDef::Default) || (defType == XMLAttDef::Fixed))
    18651395                        {
    1866                             if (fStandalone && curDef->isExternal())
     1396                            if (fStandalone && attDef.isExternal())
    18671397                            {
    18681398                                // XML 1.0 Section 2.9
    18691399                                // Document is standalone, so attributes must not be defaulted.
    1870                                 fValidator->emitError(XMLValid::NoDefAttForStandalone, curDef->getFullName(), elemDecl->getFullName());
    1871                                 if (fGrammarType == Grammar::SchemaGrammarType)
     1400                                fSchemaValidator->emitError(XMLValid::NoDefAttForStandalone, attDef.getFullName(), schemaElemDecl.getFullName());
     1401                                fPSVIElemContext.fErrorOccurred = true;
     1402                            }
     1403
     1404                            // Let the validator pass judgement on the attribute value
     1405                            fSchemaValidator->validateAttrValue(&attDef, attDef.getValue(), false, &schemaElemDecl);
     1406
     1407                            parser.writeAttribute(attDef.getAttName(), attDef.getType(), getURIIdForPrefix(attDef.getAttName()->getPrefix()), attDef.getValue(), XMLString::stringLen(attDef.getValue()), SchemaDefaultAttribute);
     1408
     1409                            if (doPSVI)
     1410                            {
     1411                                XSAttributeDeclaration * attrDecl = (XSAttributeDeclaration *)fModel->getXSObject((void*)&attDef);
     1412                                DatatypeValidator * attrValidator = attDef.getDatatypeValidator();
     1413                                XSSimpleTypeDefinition *validatingType = 0;
     1414                                PSVIItem::VALIDITY_STATE attrValid = PSVIItem::VALIDITY_INVALID;
     1415                                XSSimpleTypeDefinition * memberType = 0;
     1416                                // check if any error occurred during the validation of default value
     1417                                if (likely(!fSchemaValidator->getErrorOccurred()))
    18721418                                {
    1873                                     fPSVIElemContext.fErrorOccurred = true;
     1419                                    attrValid = PSVIItem::VALIDITY_VALID;
     1420                                    validatingType = (XSSimpleTypeDefinition*)fModel->getXSObject(attrValidator);
     1421                                    if (validatingType->getVariety() == XSSimpleTypeDefinition::VARIETY_UNION)
     1422                                    {
     1423                                        DatatypeValidator * mostRecentAttrValidator = fSchemaValidator->getMostRecentAttrValidator();
     1424                                        memberType = (XSSimpleTypeDefinition*)fModel->getXSObject(mostRecentAttrValidator);
     1425                                        if (memberType)
     1426                                        {
     1427                                            attrValidator = mostRecentAttrValidator;
     1428                                        }
     1429                                    }
    18741430                                }
     1431                                parser.writeAttributePSVI(attrDecl, memberType, validatingType, attrValid, PSVIItem::VALIDATION_FULL, attrValidator);
    18751432                            }
    1876 
    1877                             #ifndef IGNORE_DEFAULT_ATTRIBUTES
    1878                             if (fGrammarType == Grammar::SchemaGrammarType)
    1879                             {
    1880                             #endif
    1881                                 // Let the validator pass judgement on the attribute value
    1882                                 fValidator->validateAttrValue
    1883                                 (
    1884                                     curDef
    1885                                     , curDef->getValue()
    1886                                     , false
    1887                                     , elemDecl
    1888                                 );
    1889 
    1890                                 XMLAttr * curAttr;
    1891                                 if (attributeCount >= fAttrList.size())
    1892                                 {
    1893                                     curAttr = new (fMemoryManager) XMLAttr(fMemoryManager);
    1894                                     // fValidator->faultInAttr(*curAttr, *curDef);
    1895                                     fAttrList.addElement(curAttr);
    1896                                 }
    1897                                 else
    1898                                 {
    1899                                     curAttr = fAttrList.elementAt(attributeCount);
    1900                                     // fValidator->faultInAttr(*curAttr, *curDef);
    1901                                 }
    1902 
    1903                                 fValidator->faultInAttr(*curAttr, *curDef);
    1904 
    1905                                 if (fGrammarType == Grammar::DTDGrammarType)
    1906                                 {
    1907                                     //  Map the new attribute's prefix to a URI id and store that in the attribute object.
    1908                                     curAttr->setURIId(fUriResolver->getUriIdForPrefix(curAttr->getPrefix(), fContextId));
    1909                                 }
    1910 
    1911                                 // Indicate it was not explicitly specified and bump count
    1912                                 curAttr->setSpecified(false);
    1913 
    1914                                 // increase the attributeCount
    1915                                 attributeCount++;
    1916                             #ifndef IGNORE_DEFAULT_ATTRIBUTES
    1917                             }
    1918                             #endif
    1919 
    1920                             if (getPSVIHandler() && (fGrammarType == Grammar::SchemaGrammarType))
    1921                             {
    1922                                 QName * attName = ((SchemaAttDef *)curDef)->getAttName();
    1923                                 PSVIAttribute *defAttrToFill = fPSVIAttrList->getPSVIAttributeToFill
    1924                                 (
    1925                                     attName->getLocalPart()
    1926                                     , fUriResolver->getUriForId(attName->getURI())
    1927                                 );
    1928                                 XSAttributeDeclaration *defAttrDecl = (XSAttributeDeclaration *)fModel->getXSObject((void *)curDef);
    1929                                 DatatypeValidator * attrDataType = ((SchemaAttDef *)curDef)->getDatatypeValidator();
    1930                                 XSSimpleTypeDefinition *defAttrType =
    1931                                     (XSSimpleTypeDefinition*)fModel->getXSObject(attrDataType);
    1932                                 // would have occurred during validation of default value
    1933                                 if(fSchemaValidator->getErrorOccurred())
    1934                                 {
    1935                                     defAttrToFill->reset
    1936                                     (
    1937                                         fRootElemName
    1938                                         , PSVIItem::VALIDITY_INVALID
    1939                                         , PSVIItem::VALIDATION_FULL
    1940                                         , defAttrType
    1941                                         , 0
    1942                                         , curDef->getValue()
    1943                                         , true
    1944                                         , defAttrDecl
    1945                                         , 0
    1946                                     );
    1947                                 }
    1948                                 else
    1949                                 {
    1950                                     XSSimpleTypeDefinition *defAttrMemberType = 0;
    1951                                     if (defAttrType->getVariety() == XSSimpleTypeDefinition::VARIETY_UNION)
    1952                                     {
    1953                                         defAttrMemberType = (XSSimpleTypeDefinition *)fModel->getXSObject
    1954                                         (
    1955                                             fSchemaValidator->getMostRecentAttrValidator()
    1956                                         );
    1957                                     }
    1958                                     defAttrToFill->reset(
    1959                                         fRootElemName
    1960                                         , PSVIItem::VALIDITY_VALID
    1961                                         , PSVIItem::VALIDATION_FULL
    1962                                         , defAttrType
    1963                                         , defAttrMemberType
    1964                                         , curDef->getValue()
    1965                                         , true
    1966                                         , defAttrDecl
    1967                                         , (defAttrMemberType)?fSchemaValidator->getMostRecentAttrValidator():attrDataType
    1968                                     );
    1969                                 }
    1970                                 defAttrToFill->setValue(curDef->getValue());
    1971                             }
     1433                            // increase the attributeCount
     1434                            attributeCount++;
    19721435                        }
    19731436                    }
    1974                     /*else if (unlikely(defType == XMLAttDef::Prohibited)) // attribute was provided for this definition
    1975                     {
    1976                         // TODO: is it safe to move the prohibited attribute validation into the attribute scan?
    1977 
    1978                         // (schema) report error for PROHIBITED attrs that are present (V_TAGc)
    1979                         fValidator->emitError(XMLValid::ProhibitedAttributePresent, curDef->getFullName());
    1980 
    1981                         if ((fGrammarType == Grammar::SchemaGrammarType))
    1982                         {
    1983                             fPSVIElemContext.fErrorOccurred = true;
    1984                             if (getPSVIHandler())
    1985                             {
    1986                                 QName * attQName = ((SchemaAttDef *)curDef)->getAttName();
    1987                                 // bad luck...
    1988                                 PSVIAttribute *prohibitedAttr = fPSVIAttrList->getAttributePSVIByName
    1989                                 (
    1990                                     attQName->getLocalPart()
    1991                                     , fUriResolver->getUriForId(attQName->getURI())
    1992                                 );
    1993                                 prohibitedAttr->updateValidity(PSVIItem::VALIDITY_INVALID);
    1994                             }
    1995                         }
    1996                     }*/
    1997                 }
    1998             }
    1999         }
    2000 
    2001         const unsigned int uriId = element->getQName()->getURI();
    2002 
    2003         if (fGrammarType == Grammar::SchemaGrammarType)
    2004         {
    2005             // activate identity constraints
    2006             if (fGrammar && toCheckIdentityConstraint())
    2007             {
    2008                 fICHandler->activateIdentityConstraint
    2009                 (
    2010                       (SchemaElementDecl*)elemDecl
    2011                     , (int)fElemStack.getLevel()
    2012                     , uriId
    2013                     , qName->getPrefix()
    2014                     , fAttrList
    2015                     , attributeCount
    2016                     , fValidationContext
    2017                 );
    2018             }
    2019         }
    2020 
    2021         // Since the element may have default values, call start tag now regardless if it is empty or not
    2022         // If we have a document handler, then tell it about this start tag
    2023         if (fDocHandler)
    2024         {
    2025             QName * origQName = elemDecl->getElementName();
    2026             elemDecl->setElementName(qName);
    2027 
    2028             fDocHandler->startElement
    2029             (
    2030                 *elemDecl
    2031                 , uriId
    2032                 , qName->getPrefix()
    2033                 , fAttrList
    2034                 , attributeCount
    2035                 , false
    2036                 , isRoot
    2037             );
    2038 
    2039             elemDecl->setElementName(origQName);
    2040         }
    2041 
    2042         // if we have a PSVIHandler, now's the time to call
    2043         // its handleAttributesPSVI method:
    2044         if (fPSVIHandler && fGrammarType == Grammar::SchemaGrammarType)
    2045         {
    2046             QName * eName = elemDecl->getElementName();
    2047 
    2048             fPSVIHandler->handleAttributesPSVI
    2049             (
    2050                 eName->getLocalPart()
    2051                 , fUriResolver->getUriForId(eName->getURI())
    2052                 , fPSVIAttrList
    2053             );
    2054         }
    2055 
    2056         //  If empty, validate content right now if we are validating and then
    2057         //  pop the element stack top. Else, we have to update the current stack
    2058         //  top's namespace mapping elements.
    2059         if (isEmpty)
    2060         {
    2061             // Pop the element stack back off since it'll never be used now
    2062             fElemStack.popTop();
    2063 
    2064             // reset current type info
    2065             DatatypeValidator* psviMemberType = 0;
    2066             if (fGrammarType == Grammar::SchemaGrammarType)
    2067             {
    2068                 if (fValidate && elemDecl->isDeclared())
    2069                 {
    2070                     fPSVIElemContext.fCurrentTypeInfo = fSchemaValidator->getCurrentTypeInfo();
    2071                     if (!fPSVIElemContext.fCurrentTypeInfo)
    2072                         fPSVIElemContext.fCurrentDV = fSchemaValidator->getCurrentDatatypeValidator();
    2073                     else
    2074                         fPSVIElemContext.fCurrentDV = 0;
    2075                     if (fPSVIHandler)
    2076                     {
    2077                         if (XMLString::stringLen(fPSVIElemContext.fNormalizedValue) == 0)
    2078                             fPSVIElemContext.fNormalizedValue = 0;
    2079                     }
    2080                 }
    2081                 else
    2082                 {
    2083                     fPSVIElemContext.fCurrentDV = 0;
    2084                     fPSVIElemContext.fCurrentTypeInfo = 0;
    2085                     fPSVIElemContext.fNormalizedValue = 0;
    2086                 }
    2087             }
     1437                }
     1438            }
     1439        }
     1440    }
     1441
     1442    /// ------------------------------ END OF TAG HANDLING ---------------------------------
     1443
     1444    //  If empty, validate content right now if we are validating and then
     1445    //  pop the element stack top. Else, we have to update the current stack
     1446    //  top's namespace mapping elements.
     1447    if (isEmpty)
     1448    {
     1449        // Pop the element stack back off since it'll never be used now
     1450        fElemStack.popTop();
     1451
     1452        if (grammarType == Grammar::DTDGrammarType)
     1453        {
     1454            parser.writeStartTag(elemDecl, elemName, uriId, attributeCount, true);
    20881455
    20891456            // If validating, then insure that its legal to have no content
     
    20911458            {
    20921459                XMLSize_t failure;
    2093                 bool res = fValidator->checkContent(elemDecl, ((XMLElementDecl**)0), 0, &failure);
    2094                 if (!res)
    2095                 {
    2096                     fValidator->emitError
    2097                     (
    2098                         XMLValid::ElementNotValidForContent
    2099                         , elemDecl->getFullName()
    2100                         , elemDecl->getFormattedContentModel()
    2101                     );
    2102                 }
    2103 
    2104                 if (fGrammarType == Grammar::SchemaGrammarType)
    2105                 {
    2106                     if (fSchemaValidator->getErrorOccurred())
     1460                if (unlikely(!fDTDValidator->checkContent(&elemDecl, ((XMLElementDecl**)0), 0, &failure)))
     1461                {
     1462                    fDTDValidator->emitError(XMLValid::ElementNotValidForContent, elemDecl.getFullName(), elemDecl.getFormattedContentModel());
     1463                }
     1464            }
     1465
     1466        }
     1467        else // if (grammarType == Grammar::SchemaGrammarType)
     1468        {
     1469            DatatypeValidator* psviMemberType = 0;
     1470            bool isSpecified = false;
     1471            if (fValidate)
     1472            {
     1473                // If validating, then insure that its legal to have no content
     1474                XMLSize_t failure;
     1475                if (unlikely(!fSchemaValidator->checkContent(&elemDecl, ((XMLElementDecl**)0), 0, &failure)))
     1476                {
     1477                    fSchemaValidator->emitError(XMLValid::ElementNotValidForContent, elemDecl.getFullName(), elemDecl.getFormattedContentModel());
     1478                }
     1479
     1480                isSpecified = fSchemaValidator->getIsElemSpecified();
     1481
     1482                if (doPSVI)
     1483                {
     1484                    fPSVIElemContext.fIsSpecified = isSpecified;
     1485                    fPSVIElemContext.fErrorOccurred |= fSchemaValidator->getErrorOccurred();
     1486                    if (likely(elemDecl.isDeclared()))
    21071487                    {
    2108                         fPSVIElemContext.fErrorOccurred = true;
    2109                     }
    2110                     else
    2111                     {
    2112                         if (fPSVIHandler)
    2113                         {
    2114                             fPSVIElemContext.fIsSpecified = fSchemaValidator->getIsElemSpecified();
    2115                             if(fPSVIElemContext.fIsSpecified)
    2116                                 fPSVIElemContext.fNormalizedValue = ((SchemaElementDecl *)elemDecl)->getDefaultValue();
    2117                         }
     1488                        fPSVIElemContext.fCurrentTypeInfo = fSchemaValidator->getCurrentTypeInfo();
     1489                        fPSVIElemContext.fCurrentDV = fPSVIElemContext.fCurrentTypeInfo ? 0 : fSchemaValidator->getCurrentDatatypeValidator();
     1490                        fPSVIElemContext.fNormalizedValue = fSchemaValidator->getNormalizedValue();
     1491                        if (fPSVIElemContext.fNormalizedValue && *fPSVIElemContext.fNormalizedValue == 0)
     1492                            fPSVIElemContext.fNormalizedValue = 0;
    21181493                        // note that if we're empty, won't be a current DV
    21191494                        if (fPSVIElemContext.fCurrentDV && fPSVIElemContext.fCurrentDV->getType() == DatatypeValidator::Union)
     1495                        {
    21201496                            psviMemberType = fValidationContext->getValidatingMemberType();
    2121                     }
    2122 
    2123                     // call matchers and de-activate context
    2124                     if (toCheckIdentityConstraint())
    2125                     {
    2126                         fICHandler->deactivateContext
    2127                         (
    2128                             (SchemaElementDecl *)elemDecl
    2129                             , fContent.getRawBuffer()
    2130                             , fValidationContext
    2131                             , fPSVIElemContext.fCurrentDV
    2132                         );
    2133                     }
    2134 
    2135                 }
    2136             }
    2137             else if (fGrammarType == Grammar::SchemaGrammarType)
    2138             {
    2139                 fSchemaValidator->resetNillable();
    2140             }
    2141 
    2142             if (fGrammarType == Grammar::SchemaGrammarType)
    2143             {
    2144                 if (fPSVIHandler)
    2145                 {
    2146                     endElementPSVI((SchemaElementDecl*)elemDecl, psviMemberType);
    2147                 }
    2148             }
    2149 
    2150             // If we have a doc handler, tell it about the end tag
    2151             if (fDocHandler)
    2152             {
    2153                 QName * origQName = elemDecl->getElementName();
    2154                 elemDecl->setElementName(qName);
    2155 
    2156                 fDocHandler->endElement
    2157                 (
    2158                     *elemDecl
    2159                     , uriId
    2160                     , isRoot
    2161                     , qName->getPrefix()
    2162                 );
    2163 
    2164                 elemDecl->setElementName(origQName);
    2165             }
    2166 
    2167             // If the elem stack is empty, then it was an empty root
    2168             if (!isRoot)
    2169             {
    2170                 // Restore the grammar
    2171                 fGrammar = fElemStack.getCurrentGrammar();
    2172                 fGrammarType = fGrammar->getGrammarType();
    2173 
    2174                 if (fGrammarType == Grammar::SchemaGrammarType && !fValidator->handlesSchema())
    2175                 {
    2176                     if (fValidatorFromUser)
    2177                         ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Gen_NoSchemaValidator, fMemoryManager);
    2178                     else
    2179                     {
    2180                         fValidator = fSchemaValidator;
    2181                     }
    2182                 }
    2183                 else if (fGrammarType == Grammar::DTDGrammarType && !fValidator->handlesDTD())
    2184                 {
    2185                     if (fValidatorFromUser)
    2186                         ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Gen_NoDTDValidator, fMemoryManager);
    2187                     else
    2188                     {
    2189                         fValidator = fDTDValidator;
    2190                     }
    2191                 }
    2192 
    2193                 fValidator->setGrammar(fGrammar);
    2194 
    2195                 // Restore the validation flag
    2196                 fValidate = fElemStack.getValidationFlag();
    2197             }
    2198         }
    2199 
    2200         if (fGrammarType == Grammar::SchemaGrammarType)
    2201         {
    2202             // send a partial element psvi
    2203             if (fPSVIHandler)
    2204             {
    2205                 ComplexTypeInfo   * curTypeInfo = 0;
    2206                 DatatypeValidator * curDV = 0;
    2207                 XSTypeDefinition  * typeDef = 0;
    2208 
    2209                 if (fValidate && elemDecl->isDeclared())
    2210                 {
    2211                     curTypeInfo = fSchemaValidator->getCurrentTypeInfo();
    2212 
    2213                     if (curTypeInfo)
    2214                     {
    2215                         typeDef = (XSTypeDefinition*) fModel->getXSObject(curTypeInfo);
    2216                     }
    2217                     else
    2218                     {
    2219                         curDV = fSchemaValidator->getCurrentDatatypeValidator();
    2220 
    2221                         if (curDV)
    2222                         {
    2223                             typeDef = (XSTypeDefinition*) fModel->getXSObject(curDV);
    22241497                        }
    22251498                    }
    2226                 }
    2227 
    2228                 fPSVIElement->reset
    2229                 (
    2230                       PSVIElement::VALIDITY_NOTKNOWN
    2231                     , PSVIElement::VALIDATION_NONE
    2232                     , fRootElemName
    2233                     , fSchemaValidator->getIsElemSpecified()
    2234                     , (elemDecl->isDeclared()) ? (XSElementDeclaration*) fModel->getXSObject(elemDecl) : 0
    2235                     , typeDef
    2236                     , 0 //memberType
    2237                     , fModel
    2238                     , ((SchemaElementDecl*)elemDecl)->getDefaultValue()
    2239                     , 0
    2240                     , 0
    2241                     , 0
    2242                 );
    2243 
    2244 
    2245                 fPSVIHandler->handlePartialElementPSVI
    2246                 (
    2247                     elemDecl->getBaseName()
    2248                     , fUriResolver->getUriForId(elemDecl->getURI())
    2249                     , fPSVIElement
    2250                 );
    2251 
    2252             }
    2253 
    2254             // not empty
     1499                    if (isSpecified)
     1500                    {
     1501                        fPSVIElemContext.fNormalizedValue = ((SchemaElementDecl &)elemDecl).getDefaultValue();
     1502                    }
     1503                }
     1504            }
     1505
     1506
     1507            fSchemaValidator->resetNillable();
     1508            if (doPSVI)
     1509            {
     1510                endElementPSVI((SchemaElementDecl &)elemDecl, psviMemberType, parser);
     1511            }
     1512
     1513            if (unlikely(isSpecified))
     1514            {
     1515                parser.writeStartTag(elemDecl, elemName, uriId, attributeCount, false);
     1516                const XMLCh * defaultValue = ((SchemaElementDecl&)elemDecl).getDefaultValue();
     1517                parser.writeContent(defaultValue, XMLString::stringLen(defaultValue));
     1518                parser.writeEndTag(elemDecl, elemName, uriId);
     1519            }
     1520            else
     1521            {
     1522                parser.writeStartTag(elemDecl, elemName, uriId, attributeCount, true);
     1523            }
     1524        }
     1525
     1526        // If the elem stack is empty, then it was an empty root
     1527        if (likely(!isRoot))
     1528        {
     1529            // if namespaces exist, then its possible we have multiple grammars. check to see what the previous grammar was.
     1530            if (fDoNamespaces)
     1531            {
     1532                // Restore the grammar
     1533                setCurrentGrammar(fElemStack.getCurrentGrammar());
     1534            }
     1535            // Restore the validation flag
     1536            fValidate = fElemStack.getValidationFlag();
     1537        }
     1538    }
     1539    else // if (!isEmpty)
     1540    {
     1541        parser.writeStartTag(elemDecl, elemName, uriId, attributeCount, false);
     1542        if (doPSVI && likely(grammarType == Grammar::SchemaGrammarType))
     1543        {
    22551544            fErrorStack->push(fPSVIElemContext.fErrorOccurred);
    22561545        }
    22571546    }
    22581547
    2259     return elemDecl;
     1548    return attributeCount;
    22601549}
    22611550
     
    22641553// --------------------------------------------------------------------------------------------------------
    22651554
    2266 void IGXMLScanner::handleEndTag
     1555void IGXMLScanner::validateEndTag
    22671556(
    2268     XMLElementDecl * const                      elemDecl
     1557    XMLElementDecl &                elemDecl
     1558    , const QName *                 elemName
    22691559    , const unsigned int                        uriId
    2270     , const XMLSize_t                           readerNum
    22711560    , const bool                                        isRoot
    22721561    , XMLElementDecl **                         children
    22731562    , const XMLSize_t                           childCount
     1563    , const bool                    doPSVI
     1564    , XMLDocumentAccumulator &      parser
    22741565)
    22751566{
    2276 //      //  Pop the stack of the element we are supposed to be ending. Remember
    2277 //      //  that we don't own this. The stack just keeps them and reuses them.
    2278 
    2279     // these get initialized below
    2280     const ElemStack::StackElem * topElem = fElemStack.topElement();
    2281 
    2282     // Make sure we are back on the same reader as where we started
    2283     if (unlikely(topElem->fReaderNum != readerNum))
    2284     {
    2285         emitError(XMLErrs::PartialTagMarkupError);
    2286     }
    2287 
    2288     if (fGrammarType == Grammar::SchemaGrammarType)
     1567    DEBUG_GRAMMAR_MESSAGE("validateEndTag(" << elemDecl << ',' << elemName << ',' << uriId << ',' << isRoot << ",...," << childCount << ',' << doPSVI << ')');
     1568
     1569    // these get initialized below 
     1570    fPSVIElemContext.fErrorOccurred = false;
     1571
     1572    if (doPSVI && likely(fGrammarType == Grammar::SchemaGrammarType))
    22891573    {
    22901574        // reset error occurred
    22911575        fPSVIElemContext.fErrorOccurred = fErrorStack->pop();
    2292         if (fValidate && elemDecl->isDeclared())
     1576        if (fValidate && elemDecl.isDeclared())
    22931577        {
    22941578            fPSVIElemContext.fCurrentTypeInfo = fSchemaValidator->getCurrentTypeInfo();
    2295             if(!fPSVIElemContext.fCurrentTypeInfo)
    2296                 fPSVIElemContext.fCurrentDV = fSchemaValidator->getCurrentDatatypeValidator();
    2297             else
    2298                 fPSVIElemContext.fCurrentDV = 0;
    2299 
    2300             if(fPSVIHandler)
    2301             {
    2302                 //fPSVIElemContext.fNormalizedValue = fSchemaValidator->getNormalizedValue();
     1579            fPSVIElemContext.fCurrentDV = fPSVIElemContext.fCurrentTypeInfo ? 0 : fSchemaValidator->getCurrentDatatypeValidator();
     1580            if (getPSVIHandler())
     1581            {               
     1582                fPSVIElemContext.fNormalizedValue = fSchemaValidator->getNormalizedValue();
    23031583                if (fPSVIElemContext.fNormalizedValue && *fPSVIElemContext.fNormalizedValue == 0)
    23041584                    fPSVIElemContext.fNormalizedValue = 0;
     
    23131593    }
    23141594
     1595    DatatypeValidator* psviMemberType = 0;
     1596    bool writePSVI = 0;
    23151597    //  If validation is enabled, then lets pass him the list of children and
    23161598    //  this element and let him validate it.
    2317     DatatypeValidator* psviMemberType = 0;
    2318 
    23191599    if (fValidate)
    23201600    {
    2321         // XML1.0-3rd
    2322         // Validity Constraint:
    2323         // The declaration matches EMPTY and the element has no content (not even
    2324         // entity references, comments, PIs or white space).
    2325         //
    2326         if (fGrammarType == Grammar::DTDGrammarType && (topElem->fCommentOrPISeen) && ((DTDElementDecl*)elemDecl)->getModelType() == DTDElementDecl::Empty)
    2327         {
    2328             fValidator->emitError(XMLValid::EmptyElemHasContent, elemDecl->getFullName());
    2329         }
    2330 
    23311601        XMLSize_t failure;
    2332         bool res = fValidator->checkContent
    2333         (
    2334            elemDecl
    2335            , children
    2336            , childCount
    2337            , &failure
    2338         );
    2339 
    2340         if (unlikely(!res))
     1602        if (unlikely(!fValidator->checkContent(&elemDecl, children, childCount, &failure)))
    23411603        {
    23421604            //  One of the elements is not valid for the content. NOTE that
     
    23471609            if (!childCount)
    23481610            {
    2349                 fValidator->emitError
    2350                 (
    2351                     XMLValid::EmptyNotValidForContent
    2352                     , elemDecl->getFormattedContentModel()
    2353                 );
     1611                fValidator->emitError(XMLValid::EmptyNotValidForContent, elemDecl.getFormattedContentModel());
    23541612            }
    23551613            else if (failure >= childCount)
    23561614            {
    2357                 fValidator->emitError
    2358                 (
    2359                     XMLValid::NotEnoughElemsForCM
    2360                     , elemDecl->getFormattedContentModel()
    2361                 );
     1615                fValidator->emitError(XMLValid::NotEnoughElemsForCM, elemDecl.getFormattedContentModel());
    23621616            }
    23631617            else
    23641618            {
    2365                 fValidator->emitError
    2366                 (
    2367                     XMLValid::ElementNotValidForContent
    2368                     , children[failure]->getFullName()
    2369                     , elemDecl->getFormattedContentModel()
    2370                 );
    2371             }
    2372         }
    2373 
    2374         if (fGrammarType == Grammar::SchemaGrammarType)
     1619                fValidator->emitError(XMLValid::ElementNotValidForContent, children[failure]->getFullName(), elemDecl.getFormattedContentModel());
     1620            }
     1621        }
     1622
     1623        const bool isSpecified = fSchemaValidator->getIsElemSpecified();
     1624
     1625        if (doPSVI && likely(fGrammarType == Grammar::SchemaGrammarType))
    23751626        {
    23761627            if (fSchemaValidator->getErrorOccurred())
     1628            {
    23771629                fPSVIElemContext.fErrorOccurred = true;
    2378             else if (fPSVIElemContext.fCurrentDV && fPSVIElemContext.fCurrentDV->getType() == DatatypeValidator::Union)
    2379                 psviMemberType = fValidationContext->getValidatingMemberType();
    2380 
    2381             if (fPSVIHandler)
    2382             {
    2383                 fPSVIElemContext.fIsSpecified = fSchemaValidator->getIsElemSpecified();
    2384                 if (fPSVIElemContext.fIsSpecified)
    2385                 {
    2386                     fPSVIElemContext.fNormalizedValue = ((SchemaElementDecl *)elemDecl)->getDefaultValue();
    2387                 }
    2388             }
    2389 
    2390             // call matchers and de-activate context
    2391             if (toCheckIdentityConstraint())
    2392             {
    2393                 fICHandler->deactivateContext
    2394                 (
    2395                     (SchemaElementDecl *)elemDecl
    2396                     , fContent.getRawBuffer()
    2397                     , fValidationContext
    2398                     , fPSVIElemContext.fCurrentDV
    2399                 );
    2400             }
    2401         }
    2402     }
     1630            }
     1631            else if (getPSVIHandler())
     1632            {
     1633                if (fPSVIElemContext.fCurrentDV && fPSVIElemContext.fCurrentDV->getType() == DatatypeValidator::Union)
     1634                    psviMemberType = fValidationContext->getValidatingMemberType();
     1635            }
     1636
     1637            fPSVIElemContext.fIsSpecified = isSpecified;
     1638            if (isSpecified)
     1639            {
     1640                fPSVIElemContext.fNormalizedValue = ((SchemaElementDecl &)elemDecl).getDefaultValue();
     1641            }
     1642
     1643            writePSVI = true;
     1644        }
     1645
     1646        fSchemaValidator->resetNillable();
     1647
     1648        if (isSpecified)
     1649        {
     1650            const XMLCh * defaultValue = ((SchemaElementDecl&)elemDecl).getDefaultValue();
     1651            parser.writeContent(defaultValue, XMLString::stringLen(defaultValue));
     1652        }
     1653    }   
     1654
     1655    if (writePSVI)
     1656    {
     1657        endElementPSVI((SchemaElementDecl&)elemDecl, psviMemberType, parser);
     1658    }
     1659    parser.writeEndTag(elemDecl, elemName, uriId);
    24031660
    24041661    // QName dv needed topElem to resolve URIs on the checkContent
    24051662    fElemStack.popTop();
    24061663
    2407     if (fGrammarType == Grammar::SchemaGrammarType)
    2408     {
    2409         if (fPSVIHandler)
    2410         {
    2411             endElementPSVI((SchemaElementDecl*)topElem->fThisElement, psviMemberType);
    2412         }
    2413         // now we can reset the datatype buffer, since the
    2414         // application has had a chance to copy the characters somewhere else
    2415         // fSchemaValidator->clearDatatypeBuffer();
    2416         fPSVIElemContext.fNormalizedValue = 0;
    2417     }
    2418 
    2419     // If we have a doc handler, tell it about the end tag
    2420     if (fDocHandler)
    2421     {
    2422         fDocHandler->endElement
    2423         (
    2424             * elemDecl
    2425             , uriId
    2426             , isRoot
    2427             , elemDecl->getElementName()->getPrefix()
    2428         );
    2429     }
    24301664
    24311665    // If this was the root, then done with content
    24321666    if (likely(!isRoot))
    24331667    {
    2434         if (fGrammarType == Grammar::SchemaGrammarType)
    2435         {
    2436             // update error information
    2437             fErrorStack->push((fErrorStack->size() && fErrorStack->pop()) || fPSVIElemContext.fErrorOccurred);
     1668        // if an error occured within a child element, its parent is also in error
     1669        if (doPSVI && unlikely(fPSVIElemContext.fErrorOccurred) && fGrammarType == Grammar::SchemaGrammarType)
     1670        {
     1671            fErrorStack->push(fPSVIElemContext.fErrorOccurred | fErrorStack->pop());
    24381672        }
    24391673
     
    24781712// --------------------------------------------------------------------------------------------------------
    24791713
    2480 void IGXMLScanner::handleContent
     1714void IGXMLScanner::validateContent
    24811715(
    2482     const XMLCh       * content
    2483     , const XMLSize_t   length
     1716    const XMLCh     *               content
     1717    , XMLSize_t                     length
     1718    , const bool                    doPSVI   
     1719    , const XMLContentFlag          flags
     1720    , XMLDocumentAccumulator &      parser
     1721    , const bool                    write
    24841722)
    24851723{
     
    24891727    if (fValidate)
    24901728    {
    2491         // And see if the current element is a 'Children' style content model
    2492         const ElemStack::StackElem * topElem = fElemStack.topElement();
     1729        // bool hasContentCommenPItOrRef = (length) || (flags & (HasCommentOrProcessingInstruction | ContainsEntityReference));
    24931730
    24941731        // Get the character data opts for the current element
    24951732        XMLElementDecl::CharDataOpts charOpts = XMLElementDecl::AllCharData;
    2496         // fGrammar->getGrammarType()
     1733        const XMLElementDecl * elemDecl = 0;
    24971734        if (fGrammarType == Grammar::SchemaGrammarType)
    2498         {
     1735        {           
    24991736            // And see if the current element is a 'Children' style content model
    25001737            ComplexTypeInfo * currType = fSchemaValidator->getCurrentTypeInfo();
     
    25121749            }
    25131750        }
    2514         else // DTD grammar
    2515         {
    2516             charOpts = topElem->fThisElement->getCharDataOpts();
    2517         }
     1751        else // if (fGrammarType == Grammar::DTDGrammarType)
     1752        {
     1753            // And see if the current element is a 'Children' style content model
     1754            elemDecl = fElemStack.topElement()->fThisElement;
     1755            charOpts = ((const DTDElementDecl*)elemDecl)->getCharDataOpts();
     1756        }
     1757
     1758        bool contentModelError = 0;
    25181759
    25191760        if (charOpts == XMLElementDecl::AllCharData)
    25201761        {
    2521             XMLSize_t normLength = length;
    2522             const XMLCh * normContent = content;
    2523 
    2524             if (fGrammarType == Grammar::SchemaGrammarType)
    2525             {
    2526                 DatatypeValidator * tempDV =
    2527                     fSchemaValidator->getCurrentDatatypeValidator();
    2528 
    2529                 if (tempDV)
    2530                 {
    2531                     if (tempDV->getWSFacet() != DatatypeValidator::PRESERVE)
     1762            if (length)
     1763            {
     1764                XMLSize_t normLength = length;
     1765                const XMLCh * normContent = content;
     1766                bool normalized = false;
     1767
     1768                if (fGrammarType == Grammar::SchemaGrammarType)
     1769                {
     1770                    DatatypeValidator * dv = fSchemaValidator->getCurrentDatatypeValidator();
     1771                    if (dv && dv->getWSFacet() != DatatypeValidator::PRESERVE)
    25321772                    {
    25331773                        // normalize the character according to schema whitespace facet
    2534                         fSchemaValidator->normalizeWhiteSpace(tempDV, content, fWSNormalizeBuf);
     1774                        fSchemaValidator->normalizeWhiteSpace(dv->getWSFacet(), content, fWSNormalizeBuf, length, false);
    25351775                        normContent = fWSNormalizeBuf.getRawBuffer();
    25361776                        normLength = fWSNormalizeBuf.getLen();
     1777                        if (fNormalizeData)
     1778                        {
     1779                            content = normContent;
     1780                            length = normLength;
     1781                            normalized = true;
     1782                        }
    25371783                    }
    2538                 }
    2539                 // tell the schema validation about the character data for checkContent later
    2540                 fSchemaValidator->setDatatypeBuffer(normContent);
    2541 
    2542                 // call all active identity constraints
    2543                 if (toCheckIdentityConstraint() && fICHandler->getMatcherCount())
    2544                 {
    2545                     fContent.append(normContent, normLength);
    2546                 }
    2547             }
    2548 
    2549             if (fDocHandler)
    2550             {
    2551                 if (fNormalizeData)
    2552                 {
    2553                     fDocHandler->docCharacters(normContent, normLength, false);
    2554                 }
    2555                 else
    2556                 {
    2557                     fDocHandler->docCharacters(content, length, false);
    2558                 }
    2559             }
    2560             return;
     1784
     1785                    // tell the schema validation about the character data for checkContent later
     1786                    fSchemaValidator->setDatatypeBuffer(normContent);
     1787
     1788                    // call all active identity constraints
     1789                    if (toCheckIdentityConstraint() && fICHandler->getMatcherCount())
     1790                    {
     1791                        fContent.append(normContent, normLength);
     1792                    }
     1793                }
     1794
     1795                parser.writeContent(content, length, write | normalized);
     1796            }
    25611797        }
    25621798        else if (charOpts == XMLElementDecl::SpacesOk)
    25631799        {
    2564             if (XMLString::isAllSpaces(content, length))
    2565             {
    2566                 if (fDocHandler)
    2567                 {
    2568                     fDocHandler->ignorableWhitespace(content, length, false);
    2569                 }
    2570                 return;
    2571             }
    2572         }
    2573         // either there is an error or no char data is allowed
    2574         fValidator->emitError(XMLValid::NoCharDataInCM);
    2575     }
    2576     else
    2577     {
    2578 
    2579         // Always assume it's just char data if we're not validating
    2580         if (fDocHandler)
    2581         {
    2582             fDocHandler->docCharacters(content, length, false);
    2583         }
     1800            if (length == 0)
     1801            {
     1802                // do nothing
     1803            }
     1804            else if (XMLStringU::isWhitespace(content, length))
     1805            {
     1806                // XML 1.0 Section 2.9
     1807
     1808                // The standalone document declaration MUST have the value "no" if any external markup declarations contain declarations of
     1809                // element types with element content, if white space occurs directly within any instance of those types.
     1810
     1811                if (unlikely(fStandalone && fValidate))
     1812                {
     1813                    elemDecl = fElemStack.topElement()->fThisElement;
     1814                    if (unlikely(elemDecl->isExternal()))
     1815                    {
     1816                        fValidator->emitError(XMLValid::NoWSForStandalone);
     1817                    }
     1818                }
     1819                parser.writeIgnorableWhitespace(content, length, write);
     1820            }
     1821            else
     1822            {
     1823                contentModelError = 1;
     1824            }
     1825        }
     1826        else // if (charOpts == XMLElementDecl::NoCharData)
     1827        {
     1828            contentModelError = (length) || (flags & (HasCommentOrProcessingInstruction | ContainsEntityReference));
     1829        }
     1830
     1831        if (unlikely(contentModelError))
     1832        {
     1833            XMLValid::Codes errorCode = XMLValid::NoCharDataInCM;
     1834            if (unlikely(fGrammarType == Grammar::DTDGrammarType))
     1835            {
     1836                const DTDElementDecl::ModelTypes modelType = ((const DTDElementDecl*)elemDecl)->getModelType();
     1837
     1838                // XML1.0-3rd
     1839                // Validity Constraint:
     1840
     1841                // The declaration matches EMPTY and the element has no content (not even entity references, comments, PIs or white space).
     1842                if (unlikely(((flags & HasCommentOrProcessingInstruction) || length) && modelType == DTDElementDecl::Empty))
     1843                {
     1844                    errorCode = XMLValid::EmptyElemHasContent;
     1845                }