Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:12

0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *      http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 /*
0019  * $Id$
0020  */
0021 
0022 
0023 // ---------------------------------------------------------------------------
0024 //  Includes
0025 // ---------------------------------------------------------------------------
0026 #if defined(XERCES_TMPLSINC)
0027 #include <xercesc/util/NameIdPool.hpp>
0028 #endif
0029 
0030 #include <xercesc/util/IllegalArgumentException.hpp>
0031 #include <xercesc/util/NoSuchElementException.hpp>
0032 #include <xercesc/util/RuntimeException.hpp>
0033 #include <new>
0034 #include <assert.h>
0035 
0036 XERCES_CPP_NAMESPACE_BEGIN
0037 
0038 // ---------------------------------------------------------------------------
0039 //  NameIdPool: Constructors and Destructor
0040 // ---------------------------------------------------------------------------
0041 template <class TElem>
0042 NameIdPool<TElem>::NameIdPool( const XMLSize_t      hashModulus
0043                              , const XMLSize_t      initSize
0044                              , MemoryManager* const manager) :
0045     fMemoryManager(manager)
0046     , fIdPtrs(0)
0047     , fIdPtrsCount(initSize)
0048     , fIdCounter(0)
0049     , fBucketList(hashModulus, manager)
0050 {
0051     if (!hashModulus)
0052         ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Pool_ZeroModulus, fMemoryManager);
0053 
0054     //
0055     //  Allocate the initial id pointers array. We don't have to zero them
0056     //  out since the fIdCounter value tells us which ones are valid. The
0057     //  zeroth element is never used (and represents an invalid pool id.)
0058     //
0059     if (!fIdPtrsCount)
0060         fIdPtrsCount = 256;
0061     fIdPtrs = (TElem**) fMemoryManager->allocate
0062     (
0063         fIdPtrsCount * sizeof(TElem*)
0064     );
0065     fIdPtrs[0] = 0;
0066 }
0067 
0068 template <class TElem> NameIdPool<TElem>::~NameIdPool()
0069 {
0070     //
0071     //  Delete the id pointers list. The stuff it points to will be cleaned
0072     //  up when we clean the bucket lists.
0073     //
0074     fMemoryManager->deallocate(fIdPtrs); //delete [] fIdPtrs;
0075 }
0076 
0077 
0078 // ---------------------------------------------------------------------------
0079 //  NameIdPool: Element management
0080 // ---------------------------------------------------------------------------
0081 template <class TElem>
0082 inline bool NameIdPool<TElem>::
0083 containsKey(const XMLCh* const key) const
0084 {
0085     if (fIdCounter == 0) return false;
0086     return fBucketList.containsKey(key);
0087 }
0088 
0089 
0090 template <class TElem> void NameIdPool<TElem>::removeAll()
0091 {
0092     if (fIdCounter == 0) return;
0093 
0094     fBucketList.removeAll();
0095 
0096     // Reset the id counter
0097     fIdCounter = 0;
0098 }
0099 
0100 
0101 // ---------------------------------------------------------------------------
0102 //  NameIdPool: Getters
0103 // ---------------------------------------------------------------------------
0104 template <class TElem>
0105 inline TElem* NameIdPool<TElem>::
0106 getByKey(const XMLCh* const key)
0107 {
0108     if (fIdCounter == 0) return 0;
0109     return fBucketList.get(key);
0110 }
0111 
0112 template <class TElem>
0113 inline const TElem* NameIdPool<TElem>::
0114 getByKey(const XMLCh* const key) const
0115 {
0116     if (fIdCounter == 0) return 0;
0117     return fBucketList.get(key);
0118 }
0119 
0120 template <class TElem>
0121 inline TElem* NameIdPool<TElem>::
0122 getById(const XMLSize_t elemId)
0123 {
0124     // If its either zero or beyond our current id, its an error
0125     if (!elemId || (elemId > fIdCounter))
0126         ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Pool_InvalidId, fMemoryManager);
0127 
0128     return fIdPtrs[elemId];
0129 }
0130 
0131 template <class TElem>
0132 inline const TElem* NameIdPool<TElem>::
0133 getById(const XMLSize_t elemId) const
0134 {
0135     // If its either zero or beyond our current id, its an error
0136     if (!elemId || (elemId > fIdCounter))
0137         ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Pool_InvalidId, fMemoryManager);
0138 
0139     return fIdPtrs[elemId];
0140 }
0141 
0142 template <class TElem>
0143 inline MemoryManager* NameIdPool<TElem>::getMemoryManager() const
0144 {
0145     return fMemoryManager;
0146 }
0147 
0148 // ---------------------------------------------------------------------------
0149 //  NameIdPool: Setters
0150 // ---------------------------------------------------------------------------
0151 template <class TElem>
0152 XMLSize_t NameIdPool<TElem>::put(TElem* const elemToAdopt)
0153 {
0154     // First see if the key exists already. If so, its an error
0155     if(containsKey(elemToAdopt->getKey()))
0156     {
0157         ThrowXMLwithMemMgr1
0158         (
0159             IllegalArgumentException
0160             , XMLExcepts::Pool_ElemAlreadyExists
0161             , elemToAdopt->getKey()
0162             , fMemoryManager
0163         );
0164     }
0165 
0166     fBucketList.put((void*)elemToAdopt->getKey(), elemToAdopt);
0167 
0168     //
0169     //  Give this new one the next available id and add to the pointer list.
0170     //  Expand the list if that is now required.
0171     //
0172     if (fIdCounter + 1 == fIdPtrsCount)
0173     {
0174         // Create a new count 1.5 times larger and allocate a new array
0175         XMLSize_t newCount = (XMLSize_t)(fIdPtrsCount * 1.5);
0176         TElem** newArray = (TElem**) fMemoryManager->allocate
0177         (
0178             newCount * sizeof(TElem*)
0179         ); //new TElem*[newCount];
0180 
0181         // Copy over the old contents to the new array
0182         memcpy(newArray, fIdPtrs, fIdPtrsCount * sizeof(TElem*));
0183 
0184         // Ok, toss the old array and store the new data
0185         fMemoryManager->deallocate(fIdPtrs); //delete [] fIdPtrs;
0186         fIdPtrs = newArray;
0187         fIdPtrsCount = newCount;
0188     }
0189     const XMLSize_t retId = ++fIdCounter;
0190     fIdPtrs[retId] = elemToAdopt;
0191 
0192     // Set the id on the passed element
0193     elemToAdopt->setId(retId);
0194 
0195     // Return the id that we gave to this element
0196     return retId;
0197 }
0198 
0199 
0200 // ---------------------------------------------------------------------------
0201 //  NameIdPoolEnumerator: Constructors and Destructor
0202 // ---------------------------------------------------------------------------
0203 template <class TElem> NameIdPoolEnumerator<TElem>::
0204 NameIdPoolEnumerator(NameIdPool<TElem>* const toEnum
0205                      , MemoryManager* const manager) :
0206 
0207     XMLEnumerator<TElem>()
0208     , fCurIndex(0)
0209     , fToEnum(toEnum)
0210     , fMemoryManager(manager)
0211 {
0212     Reset();
0213 }
0214 
0215 template <class TElem> NameIdPoolEnumerator<TElem>::
0216 NameIdPoolEnumerator(const NameIdPoolEnumerator<TElem>& toCopy) :
0217     XMLEnumerator<TElem>(toCopy)
0218     , XMemory(toCopy)
0219     , fCurIndex(toCopy.fCurIndex)
0220     , fToEnum(toCopy.fToEnum)
0221     , fMemoryManager(toCopy.fMemoryManager)
0222 {
0223 }
0224 
0225 template <class TElem> NameIdPoolEnumerator<TElem>::~NameIdPoolEnumerator()
0226 {
0227     // We don't own the pool being enumerated, so no cleanup required
0228 }
0229 
0230 
0231 // ---------------------------------------------------------------------------
0232 //  NameIdPoolEnumerator: Public operators
0233 // ---------------------------------------------------------------------------
0234 template <class TElem> NameIdPoolEnumerator<TElem>& NameIdPoolEnumerator<TElem>::
0235 operator=(const NameIdPoolEnumerator<TElem>& toAssign)
0236 {
0237     if (this == &toAssign)
0238         return *this;
0239     fMemoryManager = toAssign.fMemoryManager;
0240     fCurIndex      = toAssign.fCurIndex;
0241     fToEnum        = toAssign.fToEnum;
0242     return *this;
0243 }
0244 
0245 // ---------------------------------------------------------------------------
0246 //  NameIdPoolEnumerator: Enum interface
0247 // ---------------------------------------------------------------------------
0248 template <class TElem> bool NameIdPoolEnumerator<TElem>::
0249 hasMoreElements() const
0250 {
0251     // If our index is zero or past the end, then we are done
0252     if (!fCurIndex || (fCurIndex > fToEnum->fIdCounter))
0253         return false;
0254     return true;
0255 }
0256 
0257 template <class TElem> TElem& NameIdPoolEnumerator<TElem>::nextElement()
0258 {
0259     // If our index is zero or past the end, then we are done
0260     if (!fCurIndex || (fCurIndex > fToEnum->fIdCounter))
0261         ThrowXMLwithMemMgr(NoSuchElementException, XMLExcepts::Enum_NoMoreElements, fMemoryManager);
0262 
0263     // Return the current element and bump the index
0264     return *fToEnum->fIdPtrs[fCurIndex++];
0265 }
0266 
0267 
0268 template <class TElem> void NameIdPoolEnumerator<TElem>::Reset()
0269 {
0270     //
0271     //  Find the next available bucket element in the pool. We use the id
0272     //  array since its very easy to enumerator through by just maintaining
0273     //  an index. If the id counter is zero, then its empty and we leave the
0274     //  current index to zero.
0275     //
0276     fCurIndex = fToEnum->fIdCounter ? 1:0;
0277 }
0278 
0279 template <class TElem> XMLSize_t NameIdPoolEnumerator<TElem>::size() const
0280 {
0281     return fToEnum->fIdCounter;
0282 }
0283 
0284 XERCES_CPP_NAMESPACE_END