peiyongz 2004/09/29 11:59:18
Modified: c/src/xercesc/framework XMLBuffer.hpp XMLBuffer.cpp
Log:
[jira1207] --patch from Dan Rosen
Revision Changes Path
1.8 +56 -21 xml-xerces/c/src/xercesc/framework/XMLBuffer.hpp
Index: XMLBuffer.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/framework/XMLBuffer.hpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- XMLBuffer.hpp 8 Sep 2004 13:55:58 -0000 1.7
+++ XMLBuffer.hpp 29 Sep 2004 18:59:18 -0000 1.8
@@ -16,6 +16,9 @@
/*
* $Log$
+ * Revision 1.8 2004/09/29 18:59:18 peiyongz
+ * [jira1207] --patch from Dan Rosen
+ *
* Revision 1.7 2004/09/08 13:55:58 peiyongz
* Apache License Version 2.0
*
@@ -72,6 +75,8 @@
XERCES_CPP_NAMESPACE_BEGIN
+class XMLBufferFullHandler;
+
/**
* XMLBuffer is a lightweight, expandable Unicode text buffer. Since XML is
* inherently theoretically unbounded in terms of the sizes of things, we
@@ -91,13 +96,15 @@
/** @name Constructor */
//@{
- XMLBuffer(int capacity = 1023
+ XMLBuffer(const unsigned int capacity = 1023
, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager) :
fUsed(false)
, fIndex(0)
, fCapacity(capacity)
, fMemoryManager(manager)
+ , fFullHandler(0)
+ , fFullSize(0)
, fBuffer(0)
{
// Buffer is one larger than capacity, to allow for zero term
@@ -117,22 +124,32 @@
//@}
// -----------------------------------------------------------------------
+ // Buffer Full Handler Management
+ // -----------------------------------------------------------------------
+ void setFullHandler(XMLBufferFullHandler* handler, const unsigned int fullSize)
+ {
+ fFullHandler = handler;
+ fFullSize = fullSize;
+ }
+
+ // -----------------------------------------------------------------------
// Buffer Management
// -----------------------------------------------------------------------
void append(const XMLCh toAppend)
{
- if (fIndex == fCapacity)
- expand();
-
// Put in char and bump the index
+ if (fIndex == fCapacity)
+ insureCapacity(1);
fBuffer[fIndex++] = toAppend;
}
- void append
- (
- const XMLCh* const chars
- , const unsigned int count = 0
- );
+ void append (const XMLCh* const chars, const unsigned int count = 0);
+
+ void set (const XMLCh* const chars, const unsigned int count = 0)
+ {
+ fIndex = 0;
+ append(chars, count);
+ }
const XMLCh* getRawBuffer() const
{
@@ -152,13 +169,6 @@
fBuffer[0] = 0;
}
- void set
- (
- const XMLCh* const chars
- , const unsigned int count = 0
- );
-
-
// -----------------------------------------------------------------------
// Getters
// -----------------------------------------------------------------------
@@ -177,7 +187,6 @@
return (fIndex == 0);
}
-
// -----------------------------------------------------------------------
// Setters
// -----------------------------------------------------------------------
@@ -186,7 +195,6 @@
fUsed = newValue;
}
-
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
@@ -199,11 +207,9 @@
// -----------------------------------------------------------------------
friend class XMLBufBid;
-
// -----------------------------------------------------------------------
// Private helpers
// -----------------------------------------------------------------------
- void expand();
void insureCapacity(const unsigned int extraNeeded);
@@ -224,12 +230,41 @@
//
// fUsed
// Indicates whether this buffer is in use or not.
+ //
+ // fFullHandler, fFullSize
+ // If fFullHandler is non-null, the buffer has a maximum size
+ // indicated by fFullSize. If writing to the buffer would exceed the
+ // buffer's maximum size, fFullHandler's bufferFull callback is
+ // invoked, to empty the buffer.
// -----------------------------------------------------------------------
bool fUsed;
unsigned int fIndex;
unsigned int fCapacity;
- MemoryManager* fMemoryManager;
+ MemoryManager* const fMemoryManager;
+ XMLBufferFullHandler* fFullHandler;
+ unsigned int fFullSize;
XMLCh* fBuffer;
+};
+
+/**
+ * XMLBufferFullHandler is a callback interface for clients of
+ * XMLBuffers that impose a size restriction (e.g. XMLScanner).
+ * Note that this is intended solely as a mix-in for internal
+ * use, and therefore does not derive from XMemory (to avoid
+ * the ambiguous base class problem).
+ */
+class XMLPARSER_EXPORT XMLBufferFullHandler
+{
+public :
+
+ /**
+ * Callback method, intended to allow clients of an XMLBuffer which has
+ * become full to empty it appropriately.
+ * @return true if the handler was able to empty the buffer (either
+ * partially or completely), otherwise false to indicate an error.
+ */
+ virtual bool bufferFull(XMLBuffer&) = 0;
+
};
XERCES_CPP_NAMESPACE_END
1.6 +31 -32 xml-xerces/c/src/xercesc/framework/XMLBuffer.cpp
Index: XMLBuffer.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/framework/XMLBuffer.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- XMLBuffer.cpp 8 Sep 2004 13:55:58 -0000 1.5
+++ XMLBuffer.cpp 29 Sep 2004 18:59:18 -0000 1.6
@@ -16,6 +16,9 @@
/**
* $Log$
+ * Revision 1.6 2004/09/29 18:59:18 peiyongz
+ * [jira1207] --patch from Dan Rosen
+ *
* Revision 1.5 2004/09/08 13:55:58 peiyongz
* Apache License Version 2.0
*
@@ -59,6 +62,7 @@
// ---------------------------------------------------------------------------
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/RuntimeException.hpp>
XERCES_CPP_NAMESPACE_BEGIN
@@ -75,45 +79,40 @@
fIndex += actualCount;
}
-void XMLBuffer::set(const XMLCh* const chars, const unsigned int count)
-{
- unsigned int actualCount = count;
- if (!count)
- actualCount = XMLString::stringLen(chars);
- fIndex = 0;
- insureCapacity(actualCount);
- memcpy(fBuffer, chars, actualCount * sizeof(XMLCh));
- fIndex = actualCount;
-}
-
-
-// ---------------------------------------------------------------------------
-// XMLBuffer: Private helper methods
-// ---------------------------------------------------------------------------
-void XMLBuffer::expand()
+void XMLBuffer::insureCapacity(const unsigned int extraNeeded)
{
- unsigned int newCap = (unsigned int)(fCapacity * 1.5);
-
- // Allocate the new buffer
- XMLCh* newBuf = (XMLCh*) fMemoryManager->allocate((newCap + 1) *
sizeof(XMLCh)); //new XMLCh[newCap + 1];
+ // If we can handle it, do nothing yet
+ if (fIndex + extraNeeded < fCapacity)
+ return;
- // Copy over the old stuff
- memcpy(newBuf, fBuffer, fCapacity * sizeof(XMLCh));
+ // If we can't handle it, try doubling the buffer size.
+ unsigned int newCap = (fIndex + extraNeeded) * 2;
- // Clean up old buffer and store new stuff
- fMemoryManager->deallocate(fBuffer); //delete [] fBuffer;
- fBuffer = newBuf;
- fCapacity = newCap;
+ // If a maximum size is set, and double the current buffer size exceeds that
+ // maximum, first check if the maximum size will accomodate the extra needed.
+ if (fFullHandler && (newCap > fFullSize))
+
+ // If the maximum buffer size accomodates the extra needed, resize to
+ // the maximum if we're not already there.
+ if (fIndex + extraNeeded <= fFullSize) {
+ if (fCapacity == fFullSize)
+ return;
+ newCap = fFullSize;
}
-void XMLBuffer::insureCapacity(const unsigned int extraNeeded)
-{
- // If we can handle it, do nothing yet
- if (fIndex + extraNeeded < fCapacity)
+ // Otherwise, allow the registered full-handler to try to empty the buffer.
+ // If it claims success, and we can accommodate the extra needed, we're
done.
+ // Note the order of evaluation: bufferFull() has the intentional
side-effect
+ // of modifying fIndex.
+ else if (fFullHandler->bufferFull(*this) && (fIndex + extraNeeded <=
fFullSize))
return;
- // Oops, not enough room. Calc new capacity and allocate new buffer
- const unsigned int newCap = (unsigned int)((fIndex + extraNeeded) * 2);
+ // Finally, if the full-handler failed, or the buffer still can't
accomodate the
+ // extra needed, we must fail.
+ else
+ ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Array_BadNewSize,
fMemoryManager);
+
+ // Allocate new buffer
XMLCh* newBuf = (XMLCh*) fMemoryManager->allocate((newCap+1) * sizeof(XMLCh));
//new XMLCh[newCap+1];
// Copy over the old stuff
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]