GME  13
LocalFileFormatTarget.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  *
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: LocalFileFormatTarget.cpp 932887 2010-04-11 13:04:59Z borisk $
00020  */
00021 
00022 #include <xercesc/framework/LocalFileFormatTarget.hpp>
00023 #include <xercesc/framework/MemoryManager.hpp>
00024 #include <xercesc/util/IOException.hpp>
00025 #include <xercesc/util/OutOfMemoryException.hpp>
00026 #include <assert.h>
00027 #include <string.h>
00028 
00029 XERCES_CPP_NAMESPACE_BEGIN
00030 
00031 const XMLSize_t MAX_BUFFER_SIZE = 65536;
00032 
00033 LocalFileFormatTarget::LocalFileFormatTarget( const XMLCh* const   fileName
00034                                             , MemoryManager* const manager)
00035 : fSource(0)
00036 , fDataBuf(0)
00037 , fIndex(0)
00038 , fCapacity(1024)
00039 , fMemoryManager(manager)
00040 {
00041     fSource = XMLPlatformUtils::openFileToWrite(fileName, manager);
00042 
00043     if (fSource == (FileHandle) XERCES_Invalid_File_Handle)
00044         ThrowXMLwithMemMgr1(IOException, XMLExcepts::File_CouldNotOpenFile, fileName, fMemoryManager);
00045 
00046     fDataBuf = (XMLByte*) fMemoryManager->allocate (
00047       fCapacity * sizeof(XMLByte));
00048 }
00049 
00050 LocalFileFormatTarget::LocalFileFormatTarget( const char* const    fileName
00051                                             , MemoryManager* const manager)
00052 : fSource(0)
00053 , fDataBuf(0)
00054 , fIndex(0)
00055 , fCapacity(1024)
00056 , fMemoryManager(manager)
00057 {
00058     fSource = XMLPlatformUtils::openFileToWrite(fileName, manager);
00059 
00060     if (fSource == (FileHandle) XERCES_Invalid_File_Handle)
00061         ThrowXMLwithMemMgr1(IOException, XMLExcepts::File_CouldNotOpenFile, fileName, fMemoryManager);
00062 
00063     fDataBuf = (XMLByte*) fMemoryManager->allocate (
00064       fCapacity * sizeof(XMLByte));
00065 }
00066 
00067 LocalFileFormatTarget::~LocalFileFormatTarget()
00068 {
00069     try
00070     {
00071         // flush remaining buffer before destroy
00072         XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
00073 
00074         if (fSource)
00075           XMLPlatformUtils::closeFile(fSource, fMemoryManager);
00076     }
00077     catch (...)
00078     {
00079       // There is nothing we can do about it here.
00080     }
00081 
00082     fMemoryManager->deallocate(fDataBuf);//delete [] fDataBuf;
00083 }
00084 
00085 void LocalFileFormatTarget::flush()
00086 {
00087   XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
00088   fIndex = 0;
00089 }
00090 
00091 void LocalFileFormatTarget::writeChars(const XMLByte* const toWrite
00092                                      , const XMLSize_t count
00093                                      , XMLFormatter * const)
00094 {
00095     if (count)
00096     {
00097       if (count < MAX_BUFFER_SIZE)
00098       {
00099         // If we don't have enough space, see if we can grow the buffer.
00100         //
00101         if (fIndex + count > fCapacity && fCapacity < MAX_BUFFER_SIZE)
00102           ensureCapacity (count);
00103 
00104         // If still not enough space, flush the buffer.
00105         //
00106         if (fIndex + count > fCapacity)
00107         {
00108           XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
00109           fIndex = 0;
00110         }
00111 
00112         memcpy(&fDataBuf[fIndex], toWrite, count * sizeof(XMLByte));
00113         fIndex += count;
00114       }
00115       else
00116       {
00117         if (fIndex)
00118         {
00119           XMLPlatformUtils::writeBufferToFile(fSource, fIndex, fDataBuf, fMemoryManager);
00120           fIndex = 0;
00121         }
00122 
00123         XMLPlatformUtils::writeBufferToFile(fSource, count, toWrite, fMemoryManager);
00124       }
00125     }
00126 
00127     return;
00128 }
00129 
00130 void LocalFileFormatTarget::ensureCapacity(const XMLSize_t extraNeeded)
00131 {
00132     XMLSize_t newCap = fCapacity * 2;
00133 
00134     while (fIndex + extraNeeded > newCap)
00135       newCap *= 2;
00136 
00137     XMLByte* newBuf  = (XMLByte*) fMemoryManager->allocate (
00138       newCap * sizeof(XMLByte));
00139 
00140     // Copy over the old stuff
00141     memcpy(newBuf, fDataBuf, fIndex * sizeof(XMLByte));
00142 
00143     // Clean up old buffer and store new stuff
00144     fMemoryManager->deallocate(fDataBuf);
00145     fDataBuf = newBuf;
00146     fCapacity = newCap;
00147 }
00148 
00149 XERCES_CPP_NAMESPACE_END