buffered_istream.tpp

Go to the documentation of this file.
00001 /*
00002   CLAW - a C++ Library Absolutely Wonderful
00003 
00004   CLAW is a free library without any particular aim but being useful to 
00005   anyone.
00006 
00007   Copyright (C) 2005-2008 Julien Jorge
00008 
00009   This library is free software; you can redistribute it and/or
00010   modify it under the terms of the GNU Lesser General Public
00011   License as published by the Free Software Foundation; either
00012   version 2.1 of the License, or (at your option) any later version.
00013 
00014   This library is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017   Lesser General Public License for more details.
00018 
00019   You should have received a copy of the GNU Lesser General Public
00020   License along with this library; if not, write to the Free Software
00021   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023   contact: julien_jorge@yahoo.fr
00024 */
00030 #include <cassert>
00031 
00032 /*----------------------------------------------------------------------------*/
00037 template<typename Stream>
00038 claw::buffered_istream<Stream>::buffered_istream( stream_type& f )
00039   : m_stream(f), m_begin(NULL), m_end(NULL), m_current(NULL),
00040     m_buffer_size(1024)
00041 {
00042   m_begin = new char[m_buffer_size];
00043   m_end = m_begin;
00044   m_current = m_end;
00045 } // buffered_istream::buffered_istream()
00046 
00047 /*----------------------------------------------------------------------------*/
00051 template<typename Stream>
00052 claw::buffered_istream<Stream>::~buffered_istream()
00053 {
00054   close();
00055 
00056   if (m_begin)
00057     delete[] m_begin;
00058 } // buffered_istream::~buffered_istream()
00059 
00060 /*----------------------------------------------------------------------------*/
00064 template<typename Stream>
00065 unsigned int claw::buffered_istream<Stream>::remaining() const
00066 {
00067   return m_end - m_current;
00068 } // buffered_istream::remaining()
00069 
00070 /*----------------------------------------------------------------------------*/
00076 template<typename Stream>
00077 bool claw::buffered_istream<Stream>::read_more( unsigned int n )
00078 {
00079   if ( n <= remaining() )
00080     return true;
00081 
00082   unsigned int r = remaining();
00083 
00084   // we'll reach the end of the buffer
00085   if ( m_current + n > m_begin + m_buffer_size )
00086     {
00087       // try to avoid reallocation
00088       if (n <= m_buffer_size)
00089         std::copy(m_current, m_end, m_begin);
00090       else // not enough space in the buffer
00091         {
00092           m_buffer_size = n;
00093 
00094           char* new_buffer = new char[m_buffer_size];
00095 
00096           std::copy(m_current, m_end, new_buffer);
00097 
00098           delete[] m_begin;
00099 
00100           m_begin = new_buffer;
00101         }
00102 
00103       m_current = m_begin;
00104       m_end = m_current + r;
00105     }
00106 
00107   m_stream.read( m_end, n-r );
00108   m_end += m_stream.gcount();
00109 
00110   return !!m_stream;
00111 } // buffered_istream::read_more()
00112 
00113 /*----------------------------------------------------------------------------*/
00117 template<typename Stream>
00118 const char* claw::buffered_istream<Stream>::get_buffer() const
00119 {
00120   return m_current;
00121 } // buffered_istream::get_buffer()
00122 
00123 /*----------------------------------------------------------------------------*/
00127 template<typename Stream>
00128 char claw::buffered_istream<Stream>::get_next()
00129 {
00130   assert( remaining() >= 1 );
00131 
00132   char result = *m_current;
00133   ++m_current;
00134 
00135   return result;
00136 } // buffered_istream::get_next()
00137 
00138 /*----------------------------------------------------------------------------*/
00144 template<typename Stream>
00145 bool claw::buffered_istream<Stream>::read( char* buf, unsigned int n )
00146 {
00147   while ( (n != 0) && !!(*this) )
00148     {
00149       if ( n > remaining() )
00150         read_more(m_buffer_size);
00151 
00152       unsigned int len = std::min(n, remaining());
00153 
00154       std::copy( m_current, m_current + len, buf );
00155       buf += len;
00156       n -= len;
00157       m_current += len;
00158     }
00159 
00160   return n==0;
00161 } // buffered_istream::read()
00162 
00163 /*----------------------------------------------------------------------------*/
00168 template<typename Stream>
00169 void claw::buffered_istream<Stream>::move( unsigned int n )
00170 {
00171   assert( m_current + n <= m_end );
00172   m_current += n;
00173 } // buffered_istream::move()
00174 
00175 /*----------------------------------------------------------------------------*/
00182 template<typename Stream>
00183 void claw::buffered_istream<Stream>::close()
00184 {
00185   m_stream.seekg( m_current - m_end, std::ios_base::cur );
00186   m_current = m_begin;
00187   m_end = m_begin;
00188 } // buffered_istream::close()
00189 
00190 /*----------------------------------------------------------------------------*/
00194 template<typename Stream>
00195 claw::buffered_istream<Stream>::operator bool() const
00196 {
00197   return m_stream || (remaining() > 0);
00198 } // buffered_istream::operator bool()

Generated on 9 Nov 2009 for CLAW Library (a C++ Library Absolutely Wonderful) by  doxygen 1.6.1