domstringpool.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 195 行

CPP
195
字号
/* * Copyright 2001-2002,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: DOMStringPool.cpp,v 1.9 2004/09/08 13:55:52 peiyongz Exp $ */#include <xercesc/util/XMLString.hpp>#include <xercesc/util/PlatformUtils.hpp>#include "DOMStringPool.hpp"#include "DOMDocumentImpl.hpp"XERCES_CPP_NAMESPACE_BEGIN////  DStringPoolEntry - one of these structs is allocated for each//                      XMLCh String in the pool.  Each slot in the//                      hash table array itself is a pointer to the head//                      of a singly-linked list of these structs.////                      Although this struct is delcared with a string length of one,//                      the factory method allocates enough storage to hold the full//                      string length.//struct DOMStringPoolEntry{    DOMStringPoolEntry    *fNext;    XMLCh                 fString[1];};//// createSPE - factory method for creating sting pool entry structs.//             Allocates sufficient storage to hold the entire string//static DOMStringPoolEntry *createSPE(const XMLCh *str, DOMDocumentImpl *doc){    //  Compute size to allocate.  Note that there's 1 char of string declared in the    //       struct, so we don't need to add one again to account for the trailing null.    //    size_t sizeToAllocate = sizeof(DOMStringPoolEntry) + XMLString::stringLen(str)*sizeof(XMLCh);    DOMStringPoolEntry *newSPE = (DOMStringPoolEntry *)doc->allocate(sizeToAllocate);    newSPE->fNext = 0;    XMLCh * nonConstStr = (XMLCh *)newSPE->fString;    XMLString::copyString(nonConstStr, str);    return newSPE;}DOMStringPool::DOMStringPool(int hashTableSize, DOMDocumentImpl *doc):   fDoc(doc),   fHashTableSize(hashTableSize){    // needed to get access to the doc's storage allocator.    //fHashTable = new (fDoc) DOMStringPoolEntry *[hashTableSize];    void* p = doc->allocate(sizeof(DOMStringPoolEntry*) * hashTableSize);    fHashTable = (DOMStringPoolEntry**) p;    for (int i=0; i<fHashTableSize; i++)        fHashTable[i] = 0;}//  Destructor.    Nothing to do, since storage all belongs to the document.//DOMStringPool::~DOMStringPool(){}const XMLCh *DOMStringPool::getPooledString(const XMLCh *in){    DOMStringPoolEntry    **pspe;    DOMStringPoolEntry    *spe;    int    inHash     = XMLString::hash(in, fHashTableSize, fDoc->getMemoryManager());    pspe = &fHashTable[inHash];    while (*pspe != 0)    {        if (XMLString::equals((*pspe)->fString, in))            return (*pspe)->fString;        pspe = &((*pspe)->fNext);    }    // This string hasn't been seen before.  Add it to the pool.    *pspe = spe = createSPE(in, fDoc);    return spe->fString;}// -----------------------------------------------------------------------//  DOMBuffer: Constructors// -----------------------------------------------------------------------DOMBuffer::DOMBuffer(DOMDocumentImpl *doc, int capacity) :    fBuffer(0)    , fIndex(0)    , fCapacity(capacity)    , fDoc(doc){    // Buffer is one larger than capacity, to allow for zero term    fBuffer = (XMLCh*) doc->allocate((fCapacity+1)*sizeof(XMLCh));    // Keep it null terminated    fBuffer[0] = XMLCh(0);}DOMBuffer::DOMBuffer(DOMDocumentImpl *doc, const XMLCh* string) :    fBuffer(0)    , fIndex(0)    , fCapacity(0)    , fDoc(doc){    unsigned int actualCount = XMLString::stringLen(string);    fCapacity = actualCount + 15;    // Buffer is one larger than capacity, to allow for zero term    fBuffer = (XMLCh*) doc->allocate((fCapacity+1)*sizeof(XMLCh));    memcpy(fBuffer, string, actualCount * sizeof(XMLCh));    fIndex = actualCount;    // Keep it null terminated    fBuffer[fIndex] = 0;}// ---------------------------------------------------------------------------//  DOMBuffer: Buffer management// ---------------------------------------------------------------------------void DOMBuffer::append(const XMLCh* const chars, const unsigned int count){    unsigned int actualCount = count;    if (!count)        actualCount = XMLString::stringLen(chars);    if (fIndex + actualCount >= fCapacity)        expandCapacity(actualCount);    memcpy(&fBuffer[fIndex], chars, actualCount * sizeof(XMLCh));    fIndex += actualCount;    // Keep it null terminated    fBuffer[fIndex] = 0;}void DOMBuffer::set(const XMLCh* const chars, const unsigned int count){    unsigned int actualCount = count;    if (!count)        actualCount = XMLString::stringLen(chars);    fIndex = 0;    if (fIndex + actualCount >= fCapacity)        expandCapacity(actualCount);    memcpy(fBuffer, chars, actualCount * sizeof(XMLCh));    fIndex = actualCount;    // Keep it null terminated    fBuffer[fIndex] = 0;}// ---------------------------------------------------------------------------//  DOMBuffer: Private helper methods// ---------------------------------------------------------------------------void DOMBuffer::expandCapacity(const unsigned int extraNeeded){    //not enough room. Calc new capacity and allocate new buffer    const unsigned int newCap = (unsigned int)((fIndex + extraNeeded) * 1.25);    XMLCh* newBuf = (XMLCh*) fDoc->allocate((newCap+1)*sizeof(XMLCh));    // Copy over the old stuff    memcpy(newBuf, fBuffer, fCapacity * sizeof(XMLCh));    // revisit: Leave the old buffer in document heap, yes, this is a leak, but live with it!    // store new stuff    fBuffer = newBuf;    fCapacity = newCap;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?