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]