BaseStreamBuffer.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00032 
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/BaseStreamBuffer.hpp"
00040 #include "blocxx/Exception.hpp"
00041 #include "blocxx/String.hpp"
00042 #include "blocxx/Assertion.hpp"
00043 #include <iostream> // for cerr
00044 #include <cstring> // for memcpy
00045 
00046 namespace BLOCXX_NAMESPACE
00047 {
00048 
00049 BaseStreamBuffer::BaseStreamBuffer(size_t bufSize,
00050       const char* direction_)
00051    : m_bufSize(bufSize), m_inputBuffer(NULL), m_outputBuffer(NULL)
00052 {
00053    String direction(direction_);
00054    if (direction.equals("in") || direction.equals("io"))
00055    {
00056       m_inputBuffer = new char[m_bufSize];
00057       initGetBuffer();
00058    }
00059    if (direction.equals("out") || direction.equals("io"))
00060    {
00061       m_outputBuffer = new char[m_bufSize];
00062       initPutBuffer();
00063    }
00064 }
00066 void
00067 BaseStreamBuffer::initBuffers()
00068 {
00069    initPutBuffer();
00070    initGetBuffer();
00071 }
00073 void
00074 BaseStreamBuffer::initPutBuffer()
00075 {
00076    setp(m_outputBuffer, m_outputBuffer + m_bufSize);
00077 }
00079 void
00080 BaseStreamBuffer::initGetBuffer()
00081 {
00082    setg(m_inputBuffer, m_inputBuffer, m_inputBuffer);
00083 }
00085 BaseStreamBuffer::~BaseStreamBuffer()
00086 {
00087    delete [] m_inputBuffer;
00088    delete [] m_outputBuffer;
00089 }
00091 int
00092 BaseStreamBuffer::sync()
00093 {
00094    return buffer_out();
00095 }
00097 int
00098 BaseStreamBuffer::buffer_out()
00099 {
00100    // NOTE: If an exception escapes this function, __terminate will be called
00101    // for gcc 2.95.2
00102 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00103    try
00104    {
00105 #endif
00106       int cnt = pptr() - pbase();
00107       int retval = buffer_to_device(m_outputBuffer, cnt);
00108       pbump(-cnt);
00109       return retval;
00110 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00111    }
00112    catch (const Exception& e)
00113    {
00114       std::cerr << "Caught Exception in BaseStreamBuffer::buffer_out(): " << e << std::endl;
00115       return EOF;
00116    }
00117    catch (const std::exception& e)
00118    {
00119       std::cerr << "Caught std::exception in BaseStreamBuffer::buffer_out(): " << e.what() << std::endl;
00120       return EOF;
00121    }
00122    catch (...)
00123    {
00124       std::cerr << "Caught unknown exception in BaseStreamBuffer::buffer_out()" << std::endl;
00125       return EOF;
00126    }
00127 #endif
00128 }
00130 int
00131 BaseStreamBuffer::overflow(int c)
00132 {
00133    if (buffer_out() < 0)
00134    {
00135       return EOF;
00136    }
00137    else
00138    {
00139       if (c != EOF)
00140       {
00141          return sputc(c);
00142       }
00143       else
00144       {
00145          return c;
00146       }
00147    }
00148 }
00150 std::streamsize
00151 BaseStreamBuffer::xsputn(const char* s, std::streamsize n)
00152 {
00153    if (n < epptr() - pptr())
00154    {
00155       memcpy(pptr(), s, n * sizeof(char));
00156       pbump(n);
00157       return n;
00158    }
00159    else
00160    {
00161       for (std::streamsize i = 0; i < n; i++)
00162       {
00163          if (sputc(s[i]) == EOF)
00164          {
00165             return i;
00166          }
00167       }
00168       return n;
00169    }
00170 }
00172 int
00173 BaseStreamBuffer::underflow()
00174 {
00175    // NOTE: If an exception escapes this function, __terminate will be called
00176    // for gcc 2.95.2
00177 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00178    try
00179    {
00180 #endif
00181       if (gptr() < egptr())
00182       {
00183          return static_cast<unsigned char>(*gptr());  // need a static_cast so a -1 doesn't turn into an EOF
00184       }
00185       if (buffer_in() < 0)
00186       {
00187          return EOF;
00188       }
00189       else
00190       {
00191          return static_cast<unsigned char>(*gptr());  // need a static_cast so a -1 doesn't turn into an EOF
00192       }
00193 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00194    }
00195    catch (const Exception& e)
00196    {
00197       std::cerr << "Caught Exception in BaseStreamBuffer::underflow(): " << e << std::endl;
00198       return EOF;
00199    }
00200    catch (const std::exception& e)
00201    {
00202       std::cerr << "Caught std::exception in BaseStreamBuffer::underflow(): " << e.what() << std::endl;
00203       return EOF;
00204    }
00205    catch (...)
00206    {
00207       std::cerr << "Caught unknown exception in BaseStreamBuffer::underflow()" << std::endl;
00208       return EOF;
00209    }
00210 #endif
00211 }
00213 int
00214 BaseStreamBuffer::buffer_in()
00215 {
00216    int retval = buffer_from_device(m_inputBuffer,
00217          m_bufSize);
00218    if (retval <= 0)
00219    {
00220       setg(0,0,0);
00221       return -1;
00222    }
00223    else
00224    {
00225       setg(m_inputBuffer, m_inputBuffer, m_inputBuffer + retval);
00226       return retval;
00227    }
00228 }
00230 int
00231 BaseStreamBuffer::buffer_to_device(const char* c, int n)
00232 {
00233    BLOCXX_ASSERT("Not implemented, should overwrite" == 0);
00234    return -1; // make the compiler happy
00235 }
00237 int
00238 BaseStreamBuffer::buffer_from_device(char* c, int n)
00239 {
00240    BLOCXX_ASSERT("Not implemented, should overwrite" == 0);
00241    return -1; // make the compiler happy
00242 }
00243 
00244 } // end namespace BLOCXX_NAMESPACE
00245 

Generated on Fri Jun 16 15:39:08 2006 for blocxx by  doxygen 1.4.6