diff --git a/src/xercesc/framework/LocalFileFormatTarget.cpp b/src/xercesc/framework/LocalFileFormatTarget.cpp index d800bfee322fe99ae6f50866132e00e909b24933..84b3d61caa0797c286853db0a23ed63390edee18 100644 --- a/src/xercesc/framework/LocalFileFormatTarget.cpp +++ b/src/xercesc/framework/LocalFileFormatTarget.cpp @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -28,12 +28,14 @@ XERCES_CPP_NAMESPACE_BEGIN +const XMLSize_t MAX_BUFFER_SIZE = 65536; + LocalFileFormatTarget::LocalFileFormatTarget( const XMLCh* const fileName , MemoryManager* const manager) : fSource(0) , fDataBuf(0) , fIndex(0) -, fCapacity(1023) +, fCapacity(1024) , fMemoryManager(manager) { fSource = XMLPlatformUtils::openFileToWrite(fileName, manager); @@ -41,15 +43,8 @@ LocalFileFormatTarget::LocalFileFormatTarget( const XMLCh* const fileName if (fSource == (FileHandle) XERCES_Invalid_File_Handle) ThrowXMLwithMemMgr1(IOException, XMLExcepts::File_CouldNotOpenFile, fileName, fMemoryManager); - // Buffer is one larger than capacity, to allow for zero term - fDataBuf = (XMLByte*) fMemoryManager->allocate - ( - (fCapacity+4) * sizeof(XMLByte) - );//new XMLByte[fCapacity+4]; - - // Keep it null terminated - fDataBuf[0] = XMLByte(0); - + fDataBuf = (XMLByte*) fMemoryManager->allocate ( + fCapacity * sizeof(XMLByte)); } LocalFileFormatTarget::LocalFileFormatTarget( const char* const fileName @@ -57,7 +52,7 @@ LocalFileFormatTarget::LocalFileFormatTarget( const char* const fileName : fSource(0) , fDataBuf(0) , fIndex(0) -, fCapacity(1023) +, fCapacity(1024) , fMemoryManager(manager) { fSource = XMLPlatformUtils::openFileToWrite(fileName, manager); @@ -65,14 +60,8 @@ LocalFileFormatTarget::LocalFileFormatTarget( const char* const fileName if (fSource == (FileHandle) XERCES_Invalid_File_Handle) ThrowXMLwithMemMgr1(IOException, XMLExcepts::File_CouldNotOpenFile, fileName, fMemoryManager); - // Buffer is one larger than capacity, to allow for zero term - fDataBuf = (XMLByte*) fMemoryManager->allocate - ( - (fCapacity+4) * sizeof(XMLByte) - );//new XMLByte[fCapacity+4]; - - // Keep it null terminated - fDataBuf[0] = XMLByte(0); + fDataBuf = (XMLByte*) fMemoryManager->allocate ( + fCapacity * sizeof(XMLByte)); } LocalFileFormatTarget::~LocalFileFormatTarget() @@ -80,10 +69,10 @@ LocalFileFormatTarget::~LocalFileFormatTarget() try { // flush remaining buffer before destroy - flushBuffer(); + XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager); if (fSource) - XMLPlatformUtils::closeFile(fSource, fMemoryManager); + XMLPlatformUtils::closeFile(fSource, fMemoryManager); } catch (...) { @@ -95,86 +84,58 @@ LocalFileFormatTarget::~LocalFileFormatTarget() void LocalFileFormatTarget::flush() { - flushBuffer(); + XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager); + fIndex = 0; } void LocalFileFormatTarget::writeChars(const XMLByte* const toWrite - , const XMLSize_t count - , XMLFormatter * const ) + , const XMLSize_t count + , XMLFormatter * const) { - if (count) { - if (insureCapacity(count)) - { - memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte)); - fIndex += count; - } - else + if (count) + { + if (count < MAX_BUFFER_SIZE) + { + // If we don't have enough space, see if we can grow the buffer. + // + if (fIndex + count > fCapacity && fCapacity < MAX_BUFFER_SIZE) + insureCapacity (count); + + // If still not enough space, flush the buffer. + // + if (fIndex + count > fCapacity) { - //flush whatever we have in the buffer and the incoming byte stream - flushBuffer(); - XMLPlatformUtils::writeBufferToFile(fSource, count, toWrite, fMemoryManager); + XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager); + fIndex = 0; } + + memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte)); + fIndex += count; + } + else + XMLPlatformUtils::writeBufferToFile(fSource, count, toWrite, fMemoryManager); } return; } -void LocalFileFormatTarget::flushBuffer() -{ - // Exception thrown in writeBufferToFile, if any, will be propagated to - // the XMLFormatter and then to the DOMLSSerializer, which may notify - // application through DOMErrorHandler, if any. - XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager); - fIndex = 0; - fDataBuf[0] = 0; - fDataBuf[fIndex + 1] = 0; - fDataBuf[fIndex + 2] = 0; - fDataBuf[fIndex + 3] = 0; -} - -/*** - * - * if the current capacity is not enough, and we can not have - * enough memory for the new buffer, we got to notify the caller - * - ***/ -bool LocalFileFormatTarget::insureCapacity(const XMLSize_t extraNeeded) +void LocalFileFormatTarget::insureCapacity(const XMLSize_t extraNeeded) { - // If we can handle it, do nothing yet - if (fIndex + extraNeeded < fCapacity) - return true; + XMLSize_t newCap = fCapacity * 2; - // Oops, not enough room. Calc new capacity and allocate new buffer - const XMLSize_t newCap = ((fIndex + extraNeeded) * 2); - XMLByte* newBuf = 0; - - try - { - newBuf = (XMLByte*) fMemoryManager->allocate - ( - (newCap+4) * sizeof(XMLByte) - );//new XMLByte[newCap+4]; - } - catch(const OutOfMemoryException&) - { - return false; - } + while (fIndex + extraNeeded > newCap) + newCap *= 2; - assert(newBuf); + XMLByte* newBuf = (XMLByte*) fMemoryManager->allocate ( + newCap * sizeof(XMLByte)); // Copy over the old stuff - memcpy(newBuf, fDataBuf, fCapacity * sizeof(XMLByte) + 4); + memcpy(newBuf, fDataBuf, fIndex * sizeof(XMLByte)); // Clean up old buffer and store new stuff - fMemoryManager->deallocate(fDataBuf); //delete [] fDataBuf; + fMemoryManager->deallocate(fDataBuf); fDataBuf = newBuf; fCapacity = newCap; - - // flush the buffer too - flushBuffer(); - return true; } XERCES_CPP_NAMESPACE_END - - diff --git a/src/xercesc/framework/LocalFileFormatTarget.hpp b/src/xercesc/framework/LocalFileFormatTarget.hpp index c8aa2c5f3ff71820e076d0a61626563d997505b9..53095b0c3050b5b21ce9ca774065543a64671d83 100644 --- a/src/xercesc/framework/LocalFileFormatTarget.hpp +++ b/src/xercesc/framework/LocalFileFormatTarget.hpp @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -65,8 +65,7 @@ private: // ----------------------------------------------------------------------- // Private helpers // ----------------------------------------------------------------------- - void flushBuffer(); - bool insureCapacity(const XMLSize_t extraNeeded); + void insureCapacity(const XMLSize_t extraNeeded); // ----------------------------------------------------------------------- // Private data members @@ -98,4 +97,3 @@ private: XERCES_CPP_NAMESPACE_END #endif - diff --git a/src/xercesc/framework/MemBufFormatTarget.cpp b/src/xercesc/framework/MemBufFormatTarget.cpp index 2f94050b2630776ba46ddc141ec9ff71d6836d54..74a8245abe104f4375241e8170c3476379da8d0d 100644 --- a/src/xercesc/framework/MemBufFormatTarget.cpp +++ b/src/xercesc/framework/MemBufFormatTarget.cpp @@ -5,9 +5,9 @@ * The ASF licenses this file to You 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. @@ -52,10 +52,13 @@ void MemBufFormatTarget::writeChars(const XMLByte* const toWrite , XMLFormatter * const) { - if (count) { + if (count) + { + if (fIndex + count >= fCapacity) insureCapacity(count); - memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte)); - fIndex += count; + + memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte)); + fIndex += count; } } @@ -83,10 +86,6 @@ void MemBufFormatTarget::reset() // --------------------------------------------------------------------------- void MemBufFormatTarget::insureCapacity(const XMLSize_t extraNeeded) { - // If we can handle it, do nothing yet - if (fIndex + extraNeeded < fCapacity) - return; - // Oops, not enough room. Calc new capacity and allocate new buffer const XMLSize_t newCap = ((fIndex + extraNeeded) * 2); XMLByte* newBuf = (XMLByte*) fMemoryManager->allocate @@ -95,7 +94,7 @@ void MemBufFormatTarget::insureCapacity(const XMLSize_t extraNeeded) );//new XMLByte[newCap+4]; // Copy over the old stuff - memcpy(newBuf, fDataBuf, fCapacity * sizeof(XMLByte) + 4); + memcpy(newBuf, fDataBuf, fIndex * sizeof(XMLByte)); // Clean up old buffer and store new stuff fMemoryManager->deallocate(fDataBuf); //delete [] fDataBuf; @@ -104,4 +103,3 @@ void MemBufFormatTarget::insureCapacity(const XMLSize_t extraNeeded) } XERCES_CPP_NAMESPACE_END -