Ignore:
Timestamp:
Jan 12, 2013, 12:21:29 PM (6 years ago)
Author:
cameron
Message:

Fixes default attribute+namespace resolution; hashing

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icXML/icXML-devel/src/icxmlc/XMLSymbolTable.cpp

    r2774 r2807  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLSymbolTable.cpp 224 2012-12-12 03:31:56Z nigelm $
     9 * @version $Id: XMLSymbolTable.cpp 243 2013-01-12 00:31:44Z nigelm $
    1010 *
    1111 */
     
    1717#include <icxercesc/internal/XMLScanner.hpp>
    1818#include <icxercesc/framework/XMLBuffer.hpp>
    19 // #include <icxercesc/internal/XMLReader.hpp>
    2019#include <icxercesc/validators/schema/SchemaSymbols.hpp>
     20#include <xercesc/validators/common/Grammar.hpp>
     21#include <xercesc/validators/DTD/DTDGrammar.hpp>
    2122#include <icxmlc/XMLConfig.hpp>
    2223
     
    3435    entry.fRawSymbol = fSymbolPool.insert(key, length);
    3536
    36     DEBUG_SYMBOL_MESSAGE("XMLSymbolTable::add(" << entry.fRawSymbol << ',' << length << ')')
    37 
    3837    XMLBuffer symbol(length, fMemoryManager);
    3938    fTranscoder->transcodeFrom(key, length, symbol);
    4039    const XMLCh * symbolName = symbol.getRawBuffer();
     40    const XMLSize_t symbolLength = symbol.getLen();
    4141
    4242    /// VERIFY THAT THE CHARACTERS IN THE SYMBOL ARE LEGAL ACCORDING TO XML SPECIFICATIONS
     
    4646    }
    4747
    48 
    4948    entry.fQName = new QName(symbolName, XMLNamespaceResolver::fEmptyUriId, fMemoryManager);
    5049
    51     entry.fName = entry.fQName->getRawName();
    52 
    53     if (fScanner->getDoNamespaces())
    54     {
    55         const XMLSize_t length = symbol.getLen();
    56         int colon;
    57         entry.fPrefixId = fNamespaceResolver->resolvePrefixId(symbolName, length, colon);
    58         if (entry.fPrefixId < XMLNamespaceResolver::fPredefinedCount)
    59         {
    60             switch (entry.fPrefixId)
    61             {
    62                 case XMLNamespaceResolver::fEmptyUriId:
    63                     if (unlikely(XMLStringU::isXMLNS(symbolName)))
    64                     {
    65                         entry.fFlags |= XMLSymbol::XMLNS;
    66                     }
    67                     break;
    68                 case XMLNamespaceResolver::fXMLUriId:
    69                     entry.fFlags |= XMLSymbol::XML;
    70                     break;
    71                 case XMLNamespaceResolver::fXMLNSUriId:
    72                     entry.fFlags |= XMLSymbol::XMLNS;
    73                     ++colon;
    74                     entry.fPrefixId = fNamespaceResolver->resolvePrefixId(&symbolName[colon], length - colon);
    75                     if (unlikely(entry.fPrefixId == XMLNamespaceResolver::fXMLNSUriId))
    76                     {
    77                         fScanner->emitError(XMLErrs::NoUseOfxmlnsAsPrefix);
    78                     }
    79                     break;
    80             }
    81         }
    82     }
     50    doNamespaceResolution(symbolName,  symbolLength, entry);
     51
     52    checkForDefaultAttributes(entry);
     53
     54    DEBUG_SYMBOL_MESSAGE(" -- add(" << &entry << ')');
    8355
    8456    return fSymbolTable.add(entry);
     
    11082    entry.fQName = new QName(symbolName, XMLNamespaceResolver::fEmptyUriId, fMemoryManager);
    11183
    112     entry.fName = entry.fQName->getRawName();
    113 
    114     int colon;
    115     entry.fPrefixId = fNamespaceResolver->resolvePrefixId(symbolName, length, colon);
    116     if (entry.fPrefixId < XMLNamespaceResolver::fPredefinedCount)
     84    doNamespaceResolution(symbolName, length, entry);
     85
     86    checkForDefaultAttributes(entry);
     87
     88    XMLString::release(&symbolName, fMemoryManager);
     89
     90    DEBUG_SYMBOL_MESSAGE(" -- addInternal(" << &entry << ')');
     91
     92    return fSymbolTable.add(entry);
     93}
     94
     95#if __GNUC__
     96#warning "What if the symbol is an element but contains default attributes with the same name? revise slightly if the DTD specification allows that"
     97#endif
     98
     99IDISA_ALWAYS_INLINE
     100void XMLSymbolTable::doNamespaceResolution(const XMLCh * name, const XMLSize_t length, XMLSymbol & entry)
     101{
     102    int colon = -1;
     103    if (fScanner->getDoNamespaces())
     104    {       
     105        entry.fPrefixId = fNamespaceResolver->addOrFindPrefixId(name, length, colon);
     106        if (entry.fPrefixId < XMLNamespaceResolver::fPredefinedCount)
     107        {
     108            switch (entry.fPrefixId)
     109            {
     110                case XMLNamespaceResolver::fEmptyUriId:
     111                    if (unlikely(XMLStringU::isXMLNS(name)))
     112                    {
     113                        #ifndef BIND_ALL_XMLNS_SYMBOLS_TO_THE_XMLNS_NAMESPACE
     114                        entry.fFlags |= XMLSymbol::XMLNS;
     115                        #else
     116                        entry.fPrefixId = XMLNamespaceResolver::fXMLNSUriId;
     117                        #endif
     118                        entry.fLocalPartId = XMLNamespaceResolver::fEmptyUriId;
     119                        return;
     120                    }
     121                    break;
     122
     123                case XMLNamespaceResolver::fXMLUriId:
     124                    break;
     125
     126                case XMLNamespaceResolver::fXMLNSUriId:
     127                    #ifndef BIND_ALL_XMLNS_SYMBOLS_TO_THE_XMLNS_NAMESPACE
     128                    entry.fFlags |= XMLSymbol::XMLNS;
     129                    #endif
     130                    // Resolve the Declared Prefix Id
     131                    entry.fLocalPartId = fNamespaceResolver->addOrFindPrefixId(&name[colon + 1], length - colon - 1);
     132                    if (unlikely(entry.fLocalPartId == XMLNamespaceResolver::fXMLNSUriId))
     133                    {
     134                        fScanner->emitError(XMLErrs::NoUseOfxmlnsAsPrefix);
     135                    }
     136                    return;
     137            }
     138        }
     139        entry.fLocalPartId = fNamespaceResolver->addOrFindLocalPartId(&name[colon + 1], length - colon - 1);       
     140    }
     141}
     142
     143IDISA_ALWAYS_INLINE
     144void XMLSymbolTable::checkForDefaultAttributes(XMLSymbol & entry)
     145{
     146#ifndef IGNORE_DEFAULT_ATTRIBUTES
     147    if (!fScanner->getHasNoDTD())
    117148    {
    118         switch (entry.fPrefixId)
     149    Grammar * grammar = (Grammar*)fScanner->getDTDGrammar();
     150
     151    if (unlikely(grammar != 0))
     152    {       
     153        const DTDElementDecl * decl = (const DTDElementDecl *)
     154            entry.getElemDecl(XMLNamespaceResolver::fEmptyUriId, Grammar::TOP_LEVEL_SCOPE, grammar);
     155
     156        if (decl)
    119157        {
    120             case XMLNamespaceResolver::fEmptyUriId:
    121                 if (unlikely(XMLStringU::isXMLNS(symbolName)))
     158            DEBUG_SYMBOL_MESSAGE(" -- found DTD decl for " << &entry);
     159
     160            XMLAttDefList & attDefList = decl->getAttDefList();
     161            DynamicArray<XMLElementDefaultAttribute, 16> defaultAttributes;
     162            XMLSize_t defaultAttributeCount = 0;
     163
     164            for(XMLSize_t i = 0; i < attDefList.getAttDefCount(); i++)
     165            {
     166                const XMLAttDef & curDef = attDefList.getAttDef(i);
     167                const XMLAttDef::DefAttTypes defType = curDef.getDefaultType();
     168
     169                DEBUG_SYMBOL_MESSAGE(" -- declared attribute: " << &curDef << " defType=" << XMLAttDef::getDefAttTypeString(defType, fMemoryManager));
     170
     171                // is this attribute potentially defaulted in?
     172                if ((defType == XMLAttDef::Default) || (defType == XMLAttDef::Fixed))
     173                {                   
     174                    if (unlikely(defaultAttributeCount == defaultAttributes.capacity()))
     175                    {
     176                        defaultAttributes.expand(defaultAttributes.capacity());
     177                    }
     178
     179                    XMLElementDefaultAttribute & attr = defaultAttributes[defaultAttributeCount++];
     180                    attr.fGid = addOrFindInternal(curDef.getFullName(), XMLString::stringLen(curDef.getFullName()));
     181                    attr.fValue = curDef.getValue();
     182                    attr.fValueLen = XMLString::stringLen(curDef.getValue());
     183                    // flag this table as having at least one default attribute
     184                    fHasDefaultAttributes = 1;
     185                }
     186            }
     187
     188
     189            DEBUG_SYMBOL_MESSAGE(" -- defaultAttributeCount: " << defaultAttributeCount);
     190
     191            if (unlikely(defaultAttributeCount != 0))
     192            {
     193                entry.fDefaultAttributeList = fDefaultAttributePool.allocate(defaultAttributeCount);
     194                Array<XMLElementDefaultAttribute>::copy(&defaultAttributes[0], entry.fDefaultAttributeList, defaultAttributeCount);
     195
     196                for (XMLSize_t i = 1; i < defaultAttributeCount; i++)
    122197                {
    123                     entry.fFlags |= XMLSymbol::XMLNS;
     198                    entry.fDefaultAttributeList[i - 1].fNext = &entry.fDefaultAttributeList[i];
    124199                }
    125                 break;
    126             case XMLNamespaceResolver::fXMLUriId:
    127                 entry.fFlags |= XMLSymbol::XML;
    128                 break;
    129             case XMLNamespaceResolver::fXMLNSUriId:
    130                 entry.fFlags |= XMLSymbol::XMLNS;
    131                 ++colon;
    132                 entry.fPrefixId = fNamespaceResolver->resolvePrefixId(&symbolName[colon], length - colon);
    133                 break;
     200                entry.fDefaultAttributeList[defaultAttributeCount - 1].fNext = 0;
     201            }
    134202        }
    135203    }
    136 
    137     return fSymbolTable.add(entry);
    138 }
    139 
     204    }
     205#endif
     206}
    140207
    141208XERCES_CPP_NAMESPACE_END
Note: See TracChangeset for help on using the changeset viewer.