buffered_istream.tpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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 }
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 }
00059
00060
00064 template<typename Stream>
00065 unsigned int claw::buffered_istream<Stream>::remaining() const
00066 {
00067 return m_end - m_current;
00068 }
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
00085 if ( m_current + n > m_begin + m_buffer_size )
00086 {
00087
00088 if (n <= m_buffer_size)
00089 std::copy(m_current, m_end, m_begin);
00090 else
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 }
00112
00113
00117 template<typename Stream>
00118 const char* claw::buffered_istream<Stream>::get_buffer() const
00119 {
00120 return m_current;
00121 }
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 }
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 }
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 }
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 }
00189
00190
00194 template<typename Stream>
00195 claw::buffered_istream<Stream>::operator bool() const
00196 {
00197 return m_stream || (remaining() > 0);
00198 }