GME  13
BaseRefVectorOf.c
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 //  Includes
00019 // ---------------------------------------------------------------------------
00020 #if defined(XERCES_TMPLSINC)
00021 #include <xercesc/util/BaseRefVectorOf.hpp>
00022 #endif
00023 
00024 XERCES_CPP_NAMESPACE_BEGIN
00025 
00026 // ---------------------------------------------------------------------------
00027 //  BaseRefVectorOf: Constructors and Destructor
00028 // ---------------------------------------------------------------------------
00029 template <class TElem>
00030 BaseRefVectorOf<TElem>::BaseRefVectorOf( const XMLSize_t maxElems
00031                                        , const bool adoptElems
00032                                        , MemoryManager* const manager) :
00033 
00034     fAdoptedElems(adoptElems)
00035     , fCurCount(0)
00036     , fMaxCount(maxElems)
00037     , fElemList(0)
00038     , fMemoryManager(manager)
00039 {
00040     // Allocate and initialize the array
00041     fElemList = (TElem**) fMemoryManager->allocate(maxElems * sizeof(TElem*));//new TElem*[maxElems];
00042     for (XMLSize_t index = 0; index < maxElems; index++)
00043         fElemList[index] = 0;
00044 }
00045 
00046 
00047 //implemented so code will link
00048 template <class TElem> BaseRefVectorOf<TElem>::~BaseRefVectorOf()
00049 {
00050 }
00051 
00052 
00053 // ---------------------------------------------------------------------------
00054 //  BaseRefVectorOf: Element management
00055 // ---------------------------------------------------------------------------
00056 template <class TElem> void BaseRefVectorOf<TElem>::addElement(TElem* const toAdd)
00057 {
00058     ensureExtraCapacity(1);
00059     fElemList[fCurCount] = toAdd;
00060     fCurCount++;
00061 }
00062 
00063 
00064 template <class TElem> void
00065 BaseRefVectorOf<TElem>::setElementAt(TElem* const toSet, const XMLSize_t setAt)
00066 {
00067     if (setAt >= fCurCount)
00068         ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
00069 
00070     if (fAdoptedElems)
00071         delete fElemList[setAt];
00072     fElemList[setAt] = toSet;
00073 }
00074 
00075 template <class TElem> void BaseRefVectorOf<TElem>::
00076 insertElementAt(TElem* const toInsert, const XMLSize_t insertAt)
00077 {
00078     if (insertAt == fCurCount)
00079     {
00080         addElement(toInsert);
00081         return;
00082     }
00083 
00084     if (insertAt > fCurCount)
00085         ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
00086 
00087     ensureExtraCapacity(1);
00088 
00089     // Make room for the newbie
00090     for (XMLSize_t index = fCurCount; index > insertAt; index--)
00091         fElemList[index] = fElemList[index-1];
00092 
00093     // And stick it in and bump the count
00094     fElemList[insertAt] = toInsert;
00095     fCurCount++;
00096 }
00097 
00098 template <class TElem> TElem* BaseRefVectorOf<TElem>::
00099 orphanElementAt(const XMLSize_t orphanAt)
00100 {
00101     if (orphanAt >= fCurCount)
00102         ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
00103 
00104     // Get the element we are going to orphan
00105     TElem* retVal = fElemList[orphanAt];
00106 
00107     // Optimize if its the last element
00108     if (orphanAt == fCurCount-1)
00109     {
00110         fElemList[orphanAt] = 0;
00111         fCurCount--;
00112         return retVal;
00113     }
00114 
00115     // Copy down every element above orphan point
00116     for (XMLSize_t index = orphanAt; index < fCurCount-1; index++)
00117         fElemList[index] = fElemList[index+1];
00118 
00119     // Keep unused elements zero for sanity's sake
00120     fElemList[fCurCount-1] = 0;
00121 
00122     // And bump down count
00123     fCurCount--;
00124 
00125     return retVal;
00126 }
00127 
00128 template <class TElem> void BaseRefVectorOf<TElem>::removeAllElements()
00129 {
00130     for (XMLSize_t index = 0; index < fCurCount; index++)
00131     {
00132         if (fAdoptedElems)
00133           delete fElemList[index];
00134 
00135         // Keep unused elements zero for sanity's sake
00136         fElemList[index] = 0;
00137     }
00138     fCurCount = 0;
00139 }
00140 
00141 template <class TElem> void BaseRefVectorOf<TElem>::
00142 removeElementAt(const XMLSize_t removeAt)
00143 {
00144     if (removeAt >= fCurCount)
00145         ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
00146 
00147     if (fAdoptedElems)
00148         delete fElemList[removeAt];
00149 
00150     // Optimize if its the last element
00151     if (removeAt == fCurCount-1)
00152     {
00153         fElemList[removeAt] = 0;
00154         fCurCount--;
00155         return;
00156     }
00157 
00158     // Copy down every element above remove point
00159     for (XMLSize_t index = removeAt; index < fCurCount-1; index++)
00160         fElemList[index] = fElemList[index+1];
00161 
00162     // Keep unused elements zero for sanity's sake
00163     fElemList[fCurCount-1] = 0;
00164 
00165     // And bump down count
00166     fCurCount--;
00167 }
00168 
00169 template <class TElem> void BaseRefVectorOf<TElem>::removeLastElement()
00170 {
00171     if (!fCurCount)
00172         return;
00173     fCurCount--;
00174 
00175     if (fAdoptedElems)
00176         delete fElemList[fCurCount];
00177 }
00178 
00179 template <class TElem>
00180 bool BaseRefVectorOf<TElem>::containsElement(const TElem* const toCheck) {
00181 
00182     for (XMLSize_t i = 0; i < fCurCount; i++) {
00183         if (fElemList[i] == toCheck) {
00184             return true;
00185         }
00186     }
00187 
00188     return false;
00189 }
00190 
00191 //
00192 // cleanup():
00193 //   similar to destructor
00194 //   called to cleanup the memory, in case destructor cannot be called
00195 //
00196 template <class TElem> void BaseRefVectorOf<TElem>::cleanup()
00197 {
00198     if (fAdoptedElems)
00199     {
00200         for (XMLSize_t index = 0; index < fCurCount; index++)
00201             delete fElemList[index];
00202     }
00203     fMemoryManager->deallocate(fElemList);//delete [] fElemList;
00204 }
00205 
00206 //
00207 // reinitialize():
00208 //   similar to constructor
00209 //   called to re-construct the fElemList from scratch again
00210 //
00211 template <class TElem> void BaseRefVectorOf<TElem>::reinitialize()
00212 {
00213     // reinitialize the array
00214     if (fElemList)
00215         cleanup();
00216 
00217     fElemList = (TElem**) fMemoryManager->allocate(fMaxCount * sizeof(TElem*));//new TElem*[fMaxCount];
00218     for (XMLSize_t index = 0; index < fMaxCount; index++)
00219         fElemList[index] = 0;
00220 
00221 }
00222 
00223 template <class TElem>
00224 MemoryManager* BaseRefVectorOf<TElem>::getMemoryManager() const
00225 {
00226     return fMemoryManager;
00227 }
00228 
00229 
00230 // ---------------------------------------------------------------------------
00231 //  BaseRefVectorOf: Getter methods
00232 // ---------------------------------------------------------------------------
00233 template <class TElem> XMLSize_t BaseRefVectorOf<TElem>::curCapacity() const
00234 {
00235     return fMaxCount;
00236 }
00237 
00238 template <class TElem> const TElem* BaseRefVectorOf<TElem>::
00239 elementAt(const XMLSize_t getAt) const
00240 {
00241     if (getAt >= fCurCount)
00242         ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
00243     return fElemList[getAt];
00244 }
00245 
00246 template <class TElem> TElem*
00247 BaseRefVectorOf<TElem>::elementAt(const XMLSize_t getAt)
00248 {
00249     if (getAt >= fCurCount)
00250         ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Vector_BadIndex, fMemoryManager);
00251     return fElemList[getAt];
00252 }
00253 
00254 template <class TElem> XMLSize_t BaseRefVectorOf<TElem>::size() const
00255 {
00256     return fCurCount;
00257 }
00258 
00259 
00260 // ---------------------------------------------------------------------------
00261 //  BaseRefVectorOf: Miscellaneous
00262 // ---------------------------------------------------------------------------
00263 template <class TElem> void BaseRefVectorOf<TElem>::
00264 ensureExtraCapacity(const XMLSize_t length)
00265 {
00266     XMLSize_t newMax = fCurCount + length;
00267 
00268     if (newMax <= fMaxCount)
00269         return;
00270 
00271         // Choose how much bigger based on the current size.
00272         // This will grow half as much again.
00273     if (newMax < fMaxCount + fMaxCount/2)
00274         newMax = fMaxCount + fMaxCount/2;
00275 
00276     // Allocate the new array and copy over the existing stuff
00277     TElem** newList = (TElem**) fMemoryManager->allocate
00278     (
00279         newMax * sizeof(TElem*)
00280     );//new TElem*[newMax];
00281     XMLSize_t index = 0;
00282     for (; index < fCurCount; index++)
00283         newList[index] = fElemList[index];
00284 
00285     // Zero out the rest of them
00286     for (; index < newMax; index++)
00287         newList[index] = 0;
00288 
00289     // Clean up the old array and update our members
00290     fMemoryManager->deallocate(fElemList);//delete [] fElemList;
00291     fElemList = newList;
00292     fMaxCount = newMax;
00293 }
00294 
00295 
00296 
00297 // ---------------------------------------------------------------------------
00298 //  AbstractBaseRefVectorEnumerator: Constructors and Destructor
00299 // ---------------------------------------------------------------------------
00300 template <class TElem> BaseRefVectorEnumerator<TElem>::
00301 BaseRefVectorEnumerator(        BaseRefVectorOf<TElem>* const   toEnum
00302                     , const bool                        adopt) :
00303     fAdopted(adopt)
00304     , fCurIndex(0)
00305     , fToEnum(toEnum)
00306 {
00307 }
00308 
00309 template <class TElem> BaseRefVectorEnumerator<TElem>::~BaseRefVectorEnumerator()
00310 {
00311     if (fAdopted)
00312         delete fToEnum;
00313 }
00314 
00315 template <class TElem> BaseRefVectorEnumerator<TElem>::
00316 BaseRefVectorEnumerator(const BaseRefVectorEnumerator<TElem>& toCopy) :
00317     XMLEnumerator<TElem>(toCopy)
00318     , XMemory(toCopy)
00319     , fAdopted(toCopy.fAdopted)
00320     , fCurIndex(toCopy.fCurIndex)
00321     , fToEnum(toCopy.fToEnum)    
00322 {
00323 }
00324 // ---------------------------------------------------------------------------
00325 //  RefBaseRefVectorEnumerator: Enum interface
00326 // ---------------------------------------------------------------------------
00327 template <class TElem> bool BaseRefVectorEnumerator<TElem>::hasMoreElements() const
00328 {
00329     if (fCurIndex >= fToEnum->size())
00330         return false;
00331     return true;
00332 }
00333 
00334 template <class TElem> TElem& BaseRefVectorEnumerator<TElem>::nextElement()
00335 {
00336     return *(fToEnum->elementAt(fCurIndex++));
00337 }
00338 
00339 template <class TElem> void BaseRefVectorEnumerator<TElem>::Reset()
00340 {
00341     fCurIndex = 0;
00342 }
00343 
00344 XERCES_CPP_NAMESPACE_END