CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5
|
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-2010 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()