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 }