GME  13
UnionToken.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  * 
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  * 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: UnionToken.cpp 678395 2008-07-21 11:40:41Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/util/regx/UnionToken.hpp>
00026 #include <xercesc/framework/XMLBuffer.hpp>
00027 #include <xercesc/util/regx/RegxUtil.hpp>
00028 #include <xercesc/util/regx/TokenFactory.hpp>
00029 #include <xercesc/util/regx/StringToken.hpp>
00030 
00031 XERCES_CPP_NAMESPACE_BEGIN
00032 
00033 // ---------------------------------------------------------------------------
00034 //  Static member data initialization
00035 // ---------------------------------------------------------------------------
00036 const unsigned short UnionToken::INITIALSIZE = 8;
00037 
00038 // ---------------------------------------------------------------------------
00039 //  UnionToken: Constructors and Destructors
00040 // ---------------------------------------------------------------------------
00041 UnionToken::UnionToken(const Token::tokType tkType, MemoryManager* const manager)
00042     : Token(tkType, manager)
00043     , fChildren(0)
00044 {
00045 
00046 }
00047 
00048 UnionToken::~UnionToken() {
00049 
00050     delete fChildren;
00051 }
00052 
00053 
00054 // ---------------------------------------------------------------------------
00055 //  UnionToken: Children manipulation methods
00056 // ---------------------------------------------------------------------------
00057 void UnionToken::addChild(Token* const child, TokenFactory* const tokFactory) {
00058 
00059     if (child == 0)
00060         return;
00061 
00062     if (fChildren == 0)
00063         fChildren = new (tokFactory->getMemoryManager()) RefVectorOf<Token>(INITIALSIZE, false, tokFactory->getMemoryManager());
00064 
00065     if (getTokenType() == T_UNION) {
00066 
00067         fChildren->addElement(child);
00068         return;
00069     }
00070 
00071     Token::tokType childType = child->getTokenType();
00072     if (childType == T_CONCAT) {
00073 
00074         XMLSize_t childSize = child->size();
00075         for (XMLSize_t i = 0; i < childSize; i++) {
00076 
00077             addChild(child->getChild(i), tokFactory);
00078         }
00079 
00080         return;
00081     }
00082 
00083     XMLSize_t childrenSize = fChildren->size();
00084     if (childrenSize == 0) {
00085 
00086         fChildren->addElement(child);
00087         return;
00088     }
00089 
00090     Token* previousTok = fChildren->elementAt(childrenSize - 1);
00091     Token::tokType previousType = previousTok->getTokenType();
00092 
00093     if (!((previousType == T_CHAR || previousType == T_STRING)
00094           && (childType == T_CHAR || childType == T_STRING))) {
00095 
00096         fChildren->addElement(child);
00097         return;
00098     }
00099 
00100     // Continue
00101     XMLBuffer stringBuf(1023, tokFactory->getMemoryManager());
00102 
00103     if (previousType == T_CHAR) {
00104 
00105         XMLInt32 ch = previousTok->getChar();
00106 
00107         if (ch >= 0x10000) {
00108 
00109             XMLCh* chSurrogate = RegxUtil::decomposeToSurrogates(ch, tokFactory->getMemoryManager());
00110             stringBuf.append(chSurrogate);
00111             tokFactory->getMemoryManager()->deallocate(chSurrogate);//delete [] chSurrogate;
00112         }
00113         else {
00114             stringBuf.append((XMLCh) ch);
00115         }
00116 
00117         previousTok = tokFactory->createString(0);
00118         fChildren->setElementAt(previousTok, childrenSize - 1);
00119     }
00120     else {
00121         stringBuf.append(previousTok->getString());
00122     }
00123 
00124     if (childType == T_CHAR) {
00125 
00126         XMLInt32 ch = child->getChar();
00127 
00128         if (ch >= 0x10000) {
00129 
00130             XMLCh* chSurrogate = RegxUtil::decomposeToSurrogates(ch, tokFactory->getMemoryManager());
00131             stringBuf.append(chSurrogate);
00132             tokFactory->getMemoryManager()->deallocate(chSurrogate);//delete [] chSurrogate;
00133         }
00134         else {
00135             stringBuf.append((XMLCh) ch);
00136         }
00137     }
00138     else {
00139         stringBuf.append(child->getString());
00140     }
00141 
00142     ((StringToken*) previousTok)->setString(stringBuf.getRawBuffer());
00143 }
00144 
00145 XERCES_CPP_NAMESPACE_END
00146