OW_TempFileStream.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 // gptr() && !pptr() == input mode
00037 // !gptr() && pptr() == output mode
00038 // pptr() && gptr() should never happen
00039 // !gptr() && !pptr() should never happen
00040 // pptr() should never be 0 unless we're gone to file.
00041 #include "OW_config.h"
00042 #include "OW_TempFileStream.hpp"
00043 #include "OW_TmpFile.hpp"
00044 #include "OW_Assertion.hpp"
00045 #include <cstring>
00046 
00047 namespace OW_NAMESPACE
00048 {
00049 
00050 using std::iostream;
00052 TempFileBuffer::TempFileBuffer(size_t bufSize)
00053    : m_bufSize(bufSize)
00054    , m_buffer(new char[m_bufSize])
00055    , m_tempFile(NULL)
00056    , m_readPos(0)
00057    , m_writePos(0)
00058    , m_isEOF(false)
00059 {
00060    setg(0,0,0); // start out in output mode.
00061    initPutBuffer();
00062 }
00064 TempFileBuffer::TempFileBuffer(String const& filename, size_t bufSize)
00065    : m_bufSize(bufSize)
00066    , m_buffer(new char[m_bufSize])
00067    , m_tempFile(new TmpFile(filename))
00068    , m_readPos(0)
00069    , m_writePos(0)
00070    , m_isEOF(false)
00071 {
00072    m_tempFile->seek(0, SEEK_END);
00073    m_writePos = m_tempFile->tell();
00074    m_tempFile->rewind();
00075    setp(0,0); // start out in input mode.
00076    initGetBuffer();
00077 }
00079 void
00080 TempFileBuffer::initBuffers()
00081 {
00082    initPutBuffer();
00083    initGetBuffer();
00084 }
00086 void
00087 TempFileBuffer::initPutBuffer()
00088 {
00089    setp(m_buffer, m_buffer + m_bufSize);
00090 }
00092 void
00093 TempFileBuffer::initGetBuffer()
00094 {
00095    setg(m_buffer, m_buffer, m_buffer);
00096 }
00098 TempFileBuffer::~TempFileBuffer()
00099 {
00100    delete [] m_buffer;
00101    delete m_tempFile;
00102 }
00104 int
00105 TempFileBuffer::buffer_out()
00106 {
00107    int cnt = pptr() - pbase();
00108    int retval = buffer_to_device(m_buffer, cnt);
00109    initPutBuffer();
00110    return retval;
00111 }
00113 int
00114 TempFileBuffer::overflow(int c)
00115 {
00116    if (pptr()) // buffer is full
00117    {
00118       if (buffer_out() < 0)
00119       {
00120          return EOF;
00121       }
00122    }
00123    else  // switching from input to output
00124    {
00125       if (!m_tempFile)
00126       {
00127          initPutBuffer();
00128          pbump(m_writePos);
00129          m_readPos = gptr() - eback();
00130       }
00131       else
00132       {
00133          m_readPos = m_tempFile->tell() - (egptr() - gptr());
00134          m_tempFile->seek(m_writePos);
00135          initPutBuffer();
00136       }
00137       setg(0,0,0);
00138    }
00139    if (c != EOF)
00140    {
00141       return sputc(c);
00142    }
00143    else
00144    {
00145       return c;
00146    }
00147 }
00149 std::streamsize
00150 TempFileBuffer::xsputn(const char* s, std::streamsize n)
00151 {
00152    if (n < epptr() - pptr())
00153    {
00154       memcpy(pptr(), s, n * sizeof(char));
00155       pbump(n);
00156       return n;
00157    }
00158    else
00159    {
00160       for (std::streamsize i = 0; i < n; i++)
00161       {
00162          if (sputc(s[i]) == EOF)
00163          {
00164             return i;
00165          }
00166       }
00167       return n;
00168    }
00169 }
00171 int
00172 TempFileBuffer::underflow()
00173 {
00174    if (m_isEOF)
00175    {
00176       return EOF;
00177    }
00178    if (gptr()) // need to fill buffer
00179    {
00180       if (buffer_in() < 0)
00181       {
00182          return EOF;
00183       }
00184    }
00185    else // we're in output mode; switch to input mode
00186    {
00187       if (m_tempFile)
00188       {
00189          buffer_out();
00190          m_writePos = m_tempFile->tell();
00191          m_tempFile->seek(m_readPos);
00192          if (buffer_in() < 0)
00193          {
00194             return EOF;
00195          }
00196       }
00197       else
00198       {
00199          m_writePos = pptr() - pbase();
00200          setg(m_buffer, m_buffer + m_readPos, pptr());
00201       }
00202       setp(0,0);
00203    }
00204    return static_cast<unsigned char>(*gptr());
00205 }
00207 int
00208 TempFileBuffer::buffer_in()
00209 {
00210    int retval = buffer_from_device(m_buffer, m_bufSize);
00211    if (retval <= 0)
00212    {
00213       setg(0,0,0);
00214       m_isEOF = true;
00215       return -1;
00216    }
00217    else
00218    {
00219       setg(m_buffer, m_buffer, m_buffer + retval);
00220       return retval;
00221    }
00222 }
00224 int
00225 TempFileBuffer::buffer_to_device(const char* c, int n)
00226 {
00227    if (!m_tempFile)
00228    {
00229       m_tempFile = new TmpFile;
00230    }
00231    return static_cast<int>(m_tempFile->write(c, n));
00232 }
00234 int
00235 TempFileBuffer::buffer_from_device(char* c, int n)
00236 {
00237    if (!m_tempFile)
00238    {
00239       return -1;
00240    }
00241    else
00242    {
00243       return static_cast<int>(m_tempFile->read(c, n));
00244    }
00245 }
00247 std::streamsize
00248 TempFileBuffer::getSize()
00249 {
00250    if (gptr() && !m_tempFile)
00251    {
00252       return egptr() - eback();
00253    }
00254    std::streamsize rval = m_writePos;
00255    if (m_tempFile)
00256    {
00257       rval = m_tempFile->getSize();
00258    }
00259    if (pptr())
00260    {
00261       rval += pptr() - pbase();
00262    }
00263    return rval;
00264 }
00266 void
00267 TempFileBuffer::rewind()
00268 {
00269    m_readPos = 0;
00270    if (m_tempFile)
00271    {
00272       if (pptr())
00273       {
00274          m_writePos += pptr() - pbase();
00275          buffer_out();
00276       }
00277       m_tempFile->seek(0);
00278       initGetBuffer();
00279    }
00280    else
00281    {
00282       if (pptr())
00283       {
00284          m_writePos = pptr() - pbase();
00285       }
00286       else if (gptr())
00287       {
00288          m_writePos = egptr() - eback();
00289       }
00290       setg(m_buffer, m_buffer, m_buffer + m_writePos);
00291    }
00292    setp(0,0);
00293    m_isEOF = false;
00294 }
00296 void
00297 TempFileBuffer::reset()
00298 {
00299    delete m_tempFile;
00300    m_tempFile = NULL;
00301    m_writePos = m_readPos = 0;
00302    setg(0,0,0);
00303    initPutBuffer();
00304    m_isEOF = false;
00305 }
00307 String
00308 TempFileBuffer::releaseFile()
00309 {
00310    buffer_out();  // Flush the buffer and cause the temp file to be written
00311                // if it's not already being used.
00312    String rval = m_tempFile->releaseFile();
00313    reset();
00314    return rval;
00315 }
00317 bool
00318 TempFileBuffer::usingTempFile() const
00319 {
00320    return m_tempFile != 0;
00321 }
00323 TempFileStream::TempFileStream(size_t bufSize)
00324 : std::basic_iostream<char, std::char_traits<char> >(new TempFileBuffer(bufSize))
00325 , m_buffer(dynamic_cast<TempFileBuffer*>(rdbuf()))
00326 {
00327 }
00329 TempFileStream::TempFileStream(String const& filename, size_t bufSize)
00330 : std::basic_iostream<char, std::char_traits<char> >(new TempFileBuffer(filename, bufSize))
00331 , m_buffer(dynamic_cast<TempFileBuffer*>(rdbuf()))
00332 {
00333 }
00335 void
00336 TempFileStream::rewind()
00337 {
00338    m_buffer->rewind();
00339    // clear eof bit
00340    clear(rdstate() & ~std::ios::eofbit);
00341 }
00343 void
00344 TempFileStream::reset()
00345 {
00346    m_buffer->reset();
00347    clear();
00348 }
00350 String
00351 TempFileStream::releaseFile()
00352 {
00353    String rval = m_buffer->releaseFile();
00354    clear();
00355    return rval;
00356 }
00358 bool
00359 TempFileStream::usingTempFile() const
00360 {
00361    return m_buffer->usingTempFile();
00362 }
00363 
00364 } // end namespace OW_NAMESPACE
00365 

Generated on Thu Feb 9 08:48:16 2006 for openwbem by  doxygen 1.4.6