GME  13
BinMemOutputStream.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: BinMemOutputStream.cpp 932887 2010-04-11 13:04:59Z borisk $
00020  */
00021 
00022 #include <xercesc/internal/BinMemOutputStream.hpp>
00023 #include <xercesc/util/XMLString.hpp>
00024 #include <string.h>
00025 
00026 XERCES_CPP_NAMESPACE_BEGIN
00027 
00028 BinMemOutputStream::BinMemOutputStream( XMLSize_t            initCapacity
00029                                       , MemoryManager* const manager)
00030 : fMemoryManager(manager)
00031 , fDataBuf(0)
00032 , fIndex(0)
00033 , fCapacity(initCapacity)
00034 {
00035     // Buffer is one larger than capacity, to allow for zero term
00036     fDataBuf = (XMLByte*) fMemoryManager->allocate
00037     (
00038         (fCapacity + 4) * sizeof(XMLByte)
00039     );
00040 
00041     // Keep it null terminated
00042     fDataBuf[0] = XMLByte(0);
00043 }
00044 
00045 BinMemOutputStream::~BinMemOutputStream()
00046 {
00047     fMemoryManager->deallocate(fDataBuf);
00048 }
00049 
00050 void BinMemOutputStream::writeBytes( const XMLByte*     const      toGo
00051                                    , const XMLSize_t               maxToWrite)
00052 {
00053 
00054     if (maxToWrite) 
00055     {
00056         ensureCapacity(maxToWrite);
00057         memcpy(&fDataBuf[fIndex], toGo, maxToWrite * sizeof(XMLByte));
00058         fIndex += maxToWrite;
00059     }
00060 
00061 }
00062 
00063 const XMLByte* BinMemOutputStream::getRawBuffer() const
00064 {
00065     fDataBuf[fIndex] = 0;
00066     fDataBuf[fIndex + 1] = 0;
00067     fDataBuf[fIndex + 2] = 0;
00068     fDataBuf[fIndex + 3] = 0;
00069     return fDataBuf;
00070 }
00071 
00072 void BinMemOutputStream::reset()
00073 {
00074     fIndex = 0;
00075     for (int i = 0; i < 4; i++)
00076     {
00077         fDataBuf[fIndex + i] = 0;
00078     }
00079 }
00080 
00081 XMLFilePos BinMemOutputStream::curPos() const
00082 {
00083     return fIndex;
00084 }
00085 
00086 XMLFilePos BinMemOutputStream::getSize() const
00087 {
00088     return fCapacity;
00089 }
00090 
00091 // ---------------------------------------------------------------------------
00092 //  BinMemOutputStream: Private helper methods
00093 // ---------------------------------------------------------------------------
00094 void BinMemOutputStream::ensureCapacity(const XMLSize_t extraNeeded)
00095 {
00096     // If we can handle it, do nothing yet
00097     if (fIndex + extraNeeded < fCapacity)
00098         return;
00099 
00100     // Oops, not enough room. Calc new capacity and allocate new buffer
00101     const XMLSize_t newCap = ((fIndex + extraNeeded) * 2);
00102     XMLByte* newBuf = (XMLByte*) fMemoryManager->allocate
00103     (
00104         (newCap+4) * sizeof(XMLByte)
00105     );
00106 
00107     memset(newBuf, 0, (newCap+4) * sizeof(XMLByte));
00108 
00109     // Copy over the old stuff
00110     memcpy(newBuf, fDataBuf, fCapacity * sizeof(XMLByte) + 4);
00111 
00112     // Clean up old buffer and store new stuff
00113     fMemoryManager->deallocate(fDataBuf); 
00114     fDataBuf = newBuf;
00115     fCapacity = newCap;
00116 }
00117 
00118 
00119 XERCES_CPP_NAMESPACE_END
00120