You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by tn...@apache.org on 2002/08/08 16:15:47 UTC
cvs commit: xml-xerces/c/src/xercesc/dom/impl DOMCDATASectionImpl.cpp DOMCharacterDataImpl.cpp DOMCharacterDataImpl.hpp DOMCommentImpl.cpp DOMDocumentImpl.cpp DOMDocumentImpl.hpp DOMDocumentTypeImpl.hpp DOMElementImpl.cpp DOMStringPool.cpp DOMStringPool.hpp DOMTextImpl.cpp
tng 2002/08/08 07:15:47
Modified: c/src/xercesc/dom/impl DOMCDATASectionImpl.cpp
DOMCharacterDataImpl.cpp DOMCharacterDataImpl.hpp
DOMCommentImpl.cpp DOMDocumentImpl.cpp
DOMDocumentImpl.hpp DOMDocumentTypeImpl.hpp
DOMElementImpl.cpp DOMStringPool.cpp
DOMStringPool.hpp DOMTextImpl.cpp
Log:
DOM Fix: Recycle node value buffer to avoid memory growth.
Revision Changes Path
1.7 +5 -6 xml-xerces/c/src/xercesc/dom/impl/DOMCDATASectionImpl.cpp
Index: DOMCDATASectionImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCDATASectionImpl.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DOMCDATASectionImpl.cpp 15 Jul 2002 19:24:32 -0000 1.6
+++ DOMCDATASectionImpl.cpp 8 Aug 2002 14:15:47 -0000 1.7
@@ -63,6 +63,7 @@
#include "DOMRangeImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
+#include "DOMStringPool.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
@@ -125,7 +126,7 @@
throw DOMException(
DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
}
- XMLSize_t len = XMLString::stringLen(fCharacterData.fData);
+ XMLSize_t len = fCharacterData.fDataBuf->getLen();
if (offset > len || offset < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
@@ -137,10 +138,7 @@
if (parent != 0)
parent->insertBefore(newText, getNextSibling());
- XMLCh *wData = (XMLCh *)(fCharacterData.fData); // Cast off const.
- wData[offset] = 0; // revisit - could change a string that
- // application code has. Do we want to do this?
-
+ fCharacterData.fDataBuf->chop(offset);
if (this->getOwnerDocument() != 0) {
Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
@@ -183,6 +181,7 @@
if (doc) {
fParent.release();
+ fCharacterData.releaseBuffer();
doc->release(this, DOMDocumentImpl::CDATA_SECTION_OBJECT);
}
else {
1.3 +43 -24 xml-xerces/c/src/xercesc/dom/impl/DOMCharacterDataImpl.cpp
Index: DOMCharacterDataImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCharacterDataImpl.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DOMCharacterDataImpl.cpp 27 May 2002 18:12:19 -0000 1.2
+++ DOMCharacterDataImpl.cpp 8 Aug 2002 14:15:47 -0000 1.3
@@ -64,19 +64,37 @@
#include "DOMRangeImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMCasts.hpp"
-#include <xercesc/framework/XMLBuffer.hpp>
+#include "DOMStringPool.hpp"
#include <xercesc/util/XMLUniDefs.hpp>
DOMCharacterDataImpl::DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat)
+ : fDoc(0)
+ , fDataBuf(0)
{
- this->fData = ((DOMDocumentImpl *)doc)->getPooledString(dat);
+ fDoc = (DOMDocumentImpl*)doc;
+
+ fDataBuf = fDoc->popBuffer();
+ if (!fDataBuf)
+ fDataBuf = new (fDoc) DOMBuffer(fDoc, dat);
+ else
+ fDataBuf->set(dat);
+
};
DOMCharacterDataImpl::DOMCharacterDataImpl(const DOMCharacterDataImpl &other)
+ : fDoc(0)
+ , fDataBuf(0)
{
- fData = other.fData;
+ fDoc = (DOMDocumentImpl*)other.fDoc;
+
+ fDataBuf = fDoc->popBuffer();
+ if (!fDataBuf)
+ fDataBuf = new (fDoc) DOMBuffer(fDoc, other.fDataBuf->getRawBuffer());
+ else
+ fDataBuf->set(other.fDataBuf->getRawBuffer());
+
};
@@ -86,7 +104,7 @@
const XMLCh * DOMCharacterDataImpl::getNodeValue() const
{
- return fData;
+ return fDataBuf->getRawBuffer();
};
@@ -95,7 +113,7 @@
if (castToNodeImpl(node)->isReadOnly())
throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR,
0);
- fData = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(value);
+ fDataBuf->set(value);
if (node->getOwnerDocument() != 0) {
Ranges* ranges = ((DOMDocumentImpl *)node->getOwnerDocument())->getRanges();
@@ -117,11 +135,7 @@
throw DOMException(
DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
-
- XMLBuffer temp;
- temp.set(fData);
- temp.append(dat);
- fData = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(temp.getRawBuffer());
+ fDataBuf->append(dat);
};
@@ -134,7 +148,7 @@
// when parameter values are bad.
//
- XMLSize_t len = XMLString::stringLen(this->fData);
+ XMLSize_t len = this->fDataBuf->getLen();
if (offset > len || offset < 0 || count < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
@@ -159,10 +173,10 @@
else
newString = temp;
- XMLString::copyNString(newString, fData, offset);
- XMLString::copyString(newString+offset, fData+offset+count);
+ XMLString::copyNString(newString, fDataBuf->getRawBuffer(), offset);
+ XMLString::copyString(newString+offset, fDataBuf->getRawBuffer()+offset+count);
- fData = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(newString);
+ fDataBuf->set(newString);
if (newLen >= 3999)
delete[] newString;
@@ -188,7 +202,7 @@
const XMLCh *DOMCharacterDataImpl::getData() const
{
- return fData;
+ return fDataBuf->getRawBuffer();
};
@@ -197,7 +211,7 @@
//
XMLSize_t DOMCharacterDataImpl::getLength() const
{
- return XMLString::stringLen(fData);
+ return fDataBuf->getLen();
};
@@ -212,7 +226,7 @@
// when parameter values are bad.
//
- XMLSize_t len = XMLString::stringLen(this->fData);
+ XMLSize_t len = fDataBuf->getLen();
if (offset > len || offset < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
@@ -227,11 +241,11 @@
else
newString = temp;
- XMLString::copyNString(newString, fData, offset);
+ XMLString::copyNString(newString, fDataBuf->getRawBuffer(), offset);
XMLString::copyNString(newString+offset, dat, datLen);
- XMLString::copyString(newString+offset+datLen, fData+offset);
+ XMLString::copyString(newString+offset+datLen, fDataBuf->getRawBuffer()+offset);
- fData = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(newString);
+ fDataBuf->set(newString);
if (newLen >= 3999)
delete[] newString;
@@ -257,7 +271,7 @@
{
if (castToNodeImpl(node)->isReadOnly())
throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
- fData = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(arg);
+ fDataBuf->set(arg);
};
@@ -273,7 +287,7 @@
//
- XMLSize_t len = XMLString::stringLen(fData);
+ XMLSize_t len = fDataBuf->getLen();
if (offset > len || offset < 0 || count < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
@@ -286,7 +300,7 @@
else
newString = temp;
- XMLString::copyNString(newString, fData+offset, count);
+ XMLString::copyNString(newString, fDataBuf->getRawBuffer()+offset, count);
newString[count] = chNull;
const XMLCh* retString = ((DOMDocumentImpl *)node->getOwnerDocument())->getPooledString(newString);
@@ -295,6 +309,11 @@
delete[] newString;
return retString;
+
};
+
+void DOMCharacterDataImpl::releaseBuffer() {
+ fDoc->releaseBuffer(fDataBuf);
+}
1.3 +7 -2 xml-xerces/c/src/xercesc/dom/impl/DOMCharacterDataImpl.hpp
Index: DOMCharacterDataImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCharacterDataImpl.hpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DOMCharacterDataImpl.hpp 27 May 2002 18:12:19 -0000 1.2
+++ DOMCharacterDataImpl.hpp 8 Aug 2002 14:15:47 -0000 1.3
@@ -75,6 +75,8 @@
class DOMNode;
class DOMDocument;
+class DOMDocumentImpl;
+class DOMBuffer;
// Instances of DOMCharacterDataImpl appear as members of node types
// that implement the DOMCharacterData interfaces.
@@ -83,7 +85,9 @@
class CDOM_EXPORT DOMCharacterDataImpl
{
public:
- const XMLCh *fData;
+ DOMBuffer* fDataBuf;
+ // for the buffer bid
+ DOMDocumentImpl* fDoc;
public:
DOMCharacterDataImpl(DOMDocument *doc, const XMLCh *dat);
@@ -102,6 +106,7 @@
const XMLCh* substringData(const DOMNode *node, XMLSize_t offset, XMLSize_t count) const;
+ void releaseBuffer();
};
1.7 +4 -2 xml-xerces/c/src/xercesc/dom/impl/DOMCommentImpl.cpp
Index: DOMCommentImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCommentImpl.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DOMCommentImpl.cpp 15 Jul 2002 19:22:22 -0000 1.6
+++ DOMCommentImpl.cpp 8 Aug 2002 14:15:47 -0000 1.7
@@ -112,8 +112,10 @@
throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
- if (doc)
+ if (doc) {
+ fCharacterData.releaseBuffer();
doc->release(this, DOMDocumentImpl::COMMENT_OBJECT);
+ }
else {
// shouldn't reach here
throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
1.15 +26 -4 xml-xerces/c/src/xercesc/dom/impl/DOMDocumentImpl.cpp
Index: DOMDocumentImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMDocumentImpl.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- DOMDocumentImpl.cpp 1 Aug 2002 14:09:25 -0000 1.14
+++ DOMDocumentImpl.cpp 8 Aug 2002 14:15:47 -0000 1.15
@@ -123,7 +123,8 @@
fStandalone(false),
fDocumentURI(0),
fUserDataTable(0),
- fRecycleNodePtr(0)
+ fRecycleNodePtr(0),
+ fRecycleBufferPtr(0)
{
fNamePool = new (this) DOMStringPool(257, this);
};
@@ -151,9 +152,11 @@
fStandalone(false),
fDocumentURI(0),
fUserDataTable(0),
- fRecycleNodePtr(0)
+ fRecycleNodePtr(0),
+ fRecycleBufferPtr(0)
{
fNamePool = new (this) DOMStringPool(257, this);
+
try {
setDocumentType(doctype);
@@ -208,6 +211,10 @@
delete fRecycleNodePtr;
}
+ if (fRecycleBufferPtr) {
+ delete fRecycleBufferPtr;
+ }
+
// Delete the heap for this document. This uncerimoniously yanks the storage
// out from under all of the nodes in the document. Destructors are NOT called.
this->deleteHeap();
@@ -690,7 +697,6 @@
// just lying around naked in DocumentImpl.
//
//-----------------------------------------------------------------------
-
XMLCh * DOMDocumentImpl::cloneString(const XMLCh *src)
{
if (!src) return 0;
@@ -1213,6 +1219,22 @@
fRecycleNodePtr->operator[](type) = new RefStackOf<DOMNode> (15, false);
fRecycleNodePtr->operator[](type)->push(object);
+}
+
+void DOMDocumentImpl::releaseBuffer(DOMBuffer* buffer)
+{
+ if (!fRecycleBufferPtr)
+ fRecycleBufferPtr = new RefStackOf<DOMBuffer> (15, false);
+
+ fRecycleBufferPtr->push(buffer);
+}
+
+DOMBuffer* DOMDocumentImpl::popBuffer()
+{
+ if (!fRecycleBufferPtr || fRecycleBufferPtr->empty())
+ return 0;
+
+ return fRecycleBufferPtr->pop();
}
1.8 +58 -61 xml-xerces/c/src/xercesc/dom/impl/DOMDocumentImpl.hpp
Index: DOMDocumentImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMDocumentImpl.hpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DOMDocumentImpl.hpp 15 Jul 2002 19:29:53 -0000 1.7
+++ DOMDocumentImpl.hpp 8 Aug 2002 14:15:47 -0000 1.8
@@ -91,7 +91,6 @@
class DOMDeepNodeListImpl;
class DOMDocumentFragmentImpl;
class DOMDocumentTypeImpl;
-class IDDStringPool;
class DOMElementImpl;
class DOMEntityImpl;
class DOMEntityReferenceImpl;
@@ -108,6 +107,7 @@
class DOMRangeImpl;
class DOMParentNode;
class DOMStringPool;
+class DOMBuffer;
typedef RefVectorOf<DOMRangeImpl> Ranges;
typedef KeyRefPair<void, DOMUserDataHandler> DOMUserDataRecord;
@@ -139,67 +139,10 @@
// -----------------------------------------------------------------------
// data
// -----------------------------------------------------------------------
-
-
DOMNodeImpl fNode; // Implements common node functionality.
DOMParentNode fParent; // Implements common parent node functionality
-
- DOMDocumentType* fDocType;
- DOMElement* fDocElement;
- DOMStringPool* fNamePool;
DOMNodeIDMap* fNodeIDMap; // for use by GetElementsById().
- Ranges* fRanges;
-
- int fChanges;
-
- bool errorChecking; // Bypass error checking.
-
- // New data introduced in DOM Level 3
- XMLCh* fActualEncoding;
- XMLCh* fEncoding;
- bool fStandalone;
- XMLCh* fVersion;
- XMLCh* fDocumentURI;
-
- RefHashTableOf<DOMNodeUserDataTable>* fUserDataTable;
-
-
- // Per-Document heap Variables.
- // The heap consists of one or more biggish blocks which are
- // sub-allocated for individual allocations of nodes, strings, etc.
- // The big blocks form a linked list, allowing them to be located for deletion.
- //
- // There is no provision for deleting suballocated blocks, other than
- // deleting the entire heap when the document is deleted.
- //
- // There is no header on individual sub-allocated blocks.
- // The header on big blocks consists only of a single back pointer to
- // the previously allocated big block (our linked list of big blocks)
- //
- //
- // revisit - this heap should be encapsulated into its own
- // class, rather than hanging naked on Document.
- //
- void* fCurrentBlock;
- char* fFreePtr;
- XMLSize_t fFreeBytesRemaining;
-
- // To recycle the DOMNode pointer
- RefArrayOf<DOMNodePtr>* fRecycleNodePtr;
-
- friend class DOMNodeImpl;
- friend class DOMNodeIteratorImpl;
- friend class DOMTreeWalkerImpl;
- friend class DOMRangeImpl;
- friend class IDXercesDOMParser;
-
-
-
- void setDocumentType(DOMDocumentType *doctype);
-
-
-
public:
DOMDocumentImpl();
DOMDocumentImpl(const XMLCh* namespaceURI, //DOM Level 2
@@ -207,6 +150,8 @@
DOMDocumentType* doctype);
virtual ~DOMDocumentImpl();
+ void setDocumentType(DOMDocumentType *doctype);
+
// Add all functions that are pure virutal in DOMNODE
DOMNODE_FUNCTIONS;
@@ -348,14 +293,14 @@
// a document, and is not recovered until the
// document itself is deleted.
//
-
void* allocate(size_t amount);
void* allocate(size_t amount, NodeObjectType type);
XMLCh* cloneString(const XMLCh *src);
const XMLCh* getPooledString(const XMLCh *src);
void deleteHeap();
void release(DOMNode* object, NodeObjectType type);
-
+ void releaseBuffer(DOMBuffer* buffer);
+ DOMBuffer* popBuffer();
// Factory methods for getting/creating node lists.
// Because nothing is ever deleted, the implementation caches and recycles
@@ -371,14 +316,66 @@
virtual DOMNode* importNode(DOMNode *source, bool deep, bool cloningNode);
private:
+ // -----------------------------------------------------------------------
+ // data
+ // -----------------------------------------------------------------------
+ // New data introduced in DOM Level 3
+ XMLCh* fActualEncoding;
+ XMLCh* fEncoding;
+ bool fStandalone;
+ XMLCh* fVersion;
+ XMLCh* fDocumentURI;
+
+ RefHashTableOf<DOMNodeUserDataTable>* fUserDataTable;
+
+
+ // Per-Document heap Variables.
+ // The heap consists of one or more biggish blocks which are
+ // sub-allocated for individual allocations of nodes, strings, etc.
+ // The big blocks form a linked list, allowing them to be located for deletion.
+ //
+ // There is no provision for deleting suballocated blocks, other than
+ // deleting the entire heap when the document is deleted.
+ //
+ // There is no header on individual sub-allocated blocks.
+ // The header on big blocks consists only of a single back pointer to
+ // the previously allocated big block (our linked list of big blocks)
+ //
+ //
+ // revisit - this heap should be encapsulated into its own
+ // class, rather than hanging naked on Document.
+ //
+ void* fCurrentBlock;
+ char* fFreePtr;
+ XMLSize_t fFreeBytesRemaining;
+
+ // To recycle the DOMNode pointer
+ RefArrayOf<DOMNodePtr>* fRecycleNodePtr;
+
+ // To recycle DOMBuffer pointer
+ RefStackOf<DOMBuffer>* fRecycleBufferPtr;
+
+ // Pool of DOMNodeList for getElementsByTagName
DOMDeepNodeListPool<DOMDeepNodeListImpl>* fNodeListPool;
+ // Other data
+ DOMDocumentType* fDocType;
+ DOMElement* fDocElement;
+ DOMStringPool* fNamePool;
+
+ Ranges* fRanges;
+
+ int fChanges;
+ bool errorChecking; // Bypass error checking.
+
};
+// ---------------------------------------------------------------------------
//
// Operator new. Global overloaded version, lets any object be allocated on
// the heap owned by a document.
//
+// ---------------------------------------------------------------------------
inline void * operator new(size_t amt, DOMDocument *doc, DOMDocumentImpl::NodeObjectType type)
{
// revist. Probably should be a checked cast.
1.7 +1 -2 xml-xerces/c/src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp
Index: DOMDocumentTypeImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMDocumentTypeImpl.hpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DOMDocumentTypeImpl.hpp 26 Jul 2002 20:31:23 -0000 1.6
+++ DOMDocumentTypeImpl.hpp 8 Aug 2002 14:15:47 -0000 1.7
@@ -73,7 +73,6 @@
#include <xercesc/util/XercesDefs.hpp>
-#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"
1.10 +3 -3 xml-xerces/c/src/xercesc/dom/impl/DOMElementImpl.cpp
Index: DOMElementImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMElementImpl.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DOMElementImpl.cpp 26 Jul 2002 20:28:03 -0000 1.9
+++ DOMElementImpl.cpp 8 Aug 2002 14:15:47 -0000 1.10
@@ -83,7 +83,7 @@
: fNode(ownerDoc), fParent(ownerDoc), fAttributes(0), fDefaultAttributes(0)
{
DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
- fName = docImpl->fNamePool->getPooledString(eName);
+ fName = docImpl->getPooledString(eName);
setupDefaultAttributes();
if (!fDefaultAttributes) {
fDefaultAttributes = new (getOwnerDocument()) DOMAttrMapImpl(this);
@@ -551,7 +551,7 @@
DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
if (!namespaceURI || !*namespaceURI) {
- fName = doc->fNamePool->getPooledString(name);
+ fName = doc->getPooledString(name);
fAttributes->reconcileDefaultAttributes(getDefaultAttributes());
return this;
1.2 +79 -1 xml-xerces/c/src/xercesc/dom/impl/DOMStringPool.cpp
Index: DOMStringPool.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMStringPool.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DOMStringPool.cpp 21 May 2002 20:29:32 -0000 1.1
+++ DOMStringPool.cpp 8 Aug 2002 14:15:47 -0000 1.2
@@ -140,5 +140,83 @@
};
+// -----------------------------------------------------------------------
+// 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;
+}
+
+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;
+}
+
+
+// ---------------------------------------------------------------------------
+// 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 = new (fDoc) XMLCh[newCap+1];
+
+ // 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;
+}
1.2 +96 -1 xml-xerces/c/src/xercesc/dom/impl/DOMStringPool.hpp
Index: DOMStringPool.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMStringPool.hpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DOMStringPool.hpp 21 May 2002 20:29:32 -0000 1.1
+++ DOMStringPool.hpp 8 Aug 2002 14:15:47 -0000 1.2
@@ -103,4 +103,99 @@
};
+
+//
+// DOMBuffer is a lightweight text buffer
+// The buffer is not nul terminated until some asks to see the raw buffer
+// contents. This also avoids overhead during append operations.
+class DOMBuffer
+{
+public :
+ // -----------------------------------------------------------------------
+ // Constructors and Destructor
+ // -----------------------------------------------------------------------
+ DOMBuffer(DOMDocumentImpl *doc, int capacity = 31);
+
+ DOMBuffer(DOMDocumentImpl *doc, const XMLCh* string);
+
+ ~DOMBuffer()
+ {
+ }
+
+ // -----------------------------------------------------------------------
+ // Buffer Management
+ // -----------------------------------------------------------------------
+ void append
+ (
+ const XMLCh* const chars
+ , const unsigned int count = 0
+ );
+
+ const XMLCh* getRawBuffer() const
+ {
+ fBuffer[fIndex] = 0;
+ return fBuffer;
+ }
+
+ void reset()
+ {
+ fIndex = 0;
+ fBuffer[0] = 0;
+ }
+
+ void set
+ (
+ const XMLCh* const chars
+ , const unsigned int count = 0
+ );
+
+ void chop
+ (
+ const unsigned int count
+ )
+ {
+ fBuffer[count] = 0;
+ fIndex = count;
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Getters
+ // -----------------------------------------------------------------------
+ unsigned int getLen() const
+ {
+ return fIndex;
+ }
+
+ // -----------------------------------------------------------------------
+ // Private helpers
+ // -----------------------------------------------------------------------
+ void expandCapacity(const unsigned int extraNeeded);
+
+
+private :
+ // -----------------------------------------------------------------------
+ // Private data members
+ //
+ // fBuffer
+ // The pointer to the buffer data. Its grown as needed. Its always
+ // one larger than fCapacity, to leave room for the null terminator.
+ //
+ // fIndex
+ // The current index into the buffer, as characters are appended
+ // to it. If its zero, then the buffer is empty.
+ //
+ // fCapacity
+ // The current capacity of the buffer. Its actually always one
+ // larger, to leave room for the null terminator.
+ //
+ // fDoc
+ // For allocating memory
+ // -----------------------------------------------------------------------
+ XMLCh* fBuffer;
+ unsigned int fIndex;
+ unsigned int fCapacity;
+ DOMDocumentImpl* fDoc;
+};
+
#endif
1.7 +7 -7 xml-xerces/c/src/xercesc/dom/impl/DOMTextImpl.cpp
Index: DOMTextImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMTextImpl.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DOMTextImpl.cpp 15 Jul 2002 19:18:17 -0000 1.6
+++ DOMTextImpl.cpp 8 Aug 2002 14:15:47 -0000 1.7
@@ -65,6 +65,7 @@
#include <xercesc/dom/DOMNode.hpp>
#include "DOMDocumentImpl.hpp"
+#include "DOMStringPool.hpp"
#include "DOMTextImpl.hpp"
#include "DOMCharacterDataImpl.hpp"
#include "DOMChildNode.hpp"
@@ -117,7 +118,7 @@
throw DOMException(
DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
}
- XMLSize_t len = XMLString::stringLen(fCharacterData.fData);
+ XMLSize_t len = fCharacterData.fDataBuf->getLen();
if (offset > len || offset < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
@@ -129,10 +130,7 @@
if (parent != 0)
parent->insertBefore(newText, getNextSibling());
- XMLCh *wData = (XMLCh *)(fCharacterData.fData); // Cast off const.
- wData[offset] = 0; // revisit - could change a string that
- // application code has. Do we want to do this?
-
+ fCharacterData.fDataBuf->chop(offset);
if (this->getOwnerDocument() != 0) {
Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
@@ -185,8 +183,10 @@
throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
- if (doc)
+ if (doc) {
+ fCharacterData.releaseBuffer();
doc->release(this, DOMDocumentImpl::TEXT_OBJECT);
+ }
else {
// shouldn't reach here
throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org