2 CLAW - a C++ Library Absolutely Wonderful
4 CLAW is a free library without any particular aim but being useful to
7 Copyright (C) 2005-2011 Julien Jorge
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 contact: julien.jorge@gamned.org
26 * \file buffered_istream.tpp
27 * \brief Implementation of the claw::buffered_istream class.
28 * \author Julien Jorge
32 /*----------------------------------------------------------------------------*/
35 * \param f The file associated to the stream.
37 template<typename Stream>
38 claw::buffered_istream<Stream>::buffered_istream( stream_type& f )
39 : m_stream(f), m_begin(NULL), m_end(NULL), m_current(NULL),
42 m_begin = new char[m_buffer_size];
45 } // buffered_istream::buffered_istream()
47 /*----------------------------------------------------------------------------*/
51 template<typename Stream>
52 claw::buffered_istream<Stream>::~buffered_istream()
58 } // buffered_istream::~buffered_istream()
60 /*----------------------------------------------------------------------------*/
62 * \brief Tell how many bytes are ready in the buffer.
64 template<typename Stream>
65 unsigned int claw::buffered_istream<Stream>::remaining() const
67 return m_end - m_current;
68 } // buffered_istream::remaining()
70 /*----------------------------------------------------------------------------*/
72 * \brief Increase the number of ready bytes to a given number.
73 * \param n The number of bytes you need.
74 * \remark This method reads n - remaining() bytes from the file.
76 template<typename Stream>
77 bool claw::buffered_istream<Stream>::read_more( unsigned int n )
79 if ( n <= remaining() )
82 unsigned int r = remaining();
84 // we'll reach the end of the buffer
85 if ( m_current + n > m_begin + m_buffer_size )
87 // try to avoid reallocation
88 if (n <= m_buffer_size)
89 std::copy(m_current, m_end, m_begin);
90 else // not enough space in the buffer
94 char* new_buffer = new char[m_buffer_size];
96 std::copy(m_current, m_end, new_buffer);
100 m_begin = new_buffer;
104 m_end = m_current + r;
107 m_stream.read( m_end, n-r );
108 m_end += m_stream.gcount();
111 } // buffered_istream::read_more()
113 /*----------------------------------------------------------------------------*/
115 * \brief Get the input buffer.
117 template<typename Stream>
118 const char* claw::buffered_istream<Stream>::get_buffer() const
121 } // buffered_istream::get_buffer()
123 /*----------------------------------------------------------------------------*/
125 * \brief Get the next value in the buffer and move one byte forward.
127 template<typename Stream>
128 char claw::buffered_istream<Stream>::get_next()
130 assert( remaining() >= 1 );
132 char result = *m_current;
136 } // buffered_istream::get_next()
138 /*----------------------------------------------------------------------------*/
140 * \brief Read a range of data.
141 * \param buf The buffer in which we write the read data.
142 * \param n The number of bytes to read.
144 template<typename Stream>
145 bool claw::buffered_istream<Stream>::read( char* buf, unsigned int n )
147 while ( (n != 0) && !!(*this) )
149 if ( n > remaining() )
150 read_more(m_buffer_size);
152 unsigned int len = std::min(n, remaining());
154 std::copy( m_current, m_current + len, buf );
161 } // buffered_istream::read()
163 /*----------------------------------------------------------------------------*/
165 * \brief Move some bytes forward.
166 * \param n The number of bytes to skip.
168 template<typename Stream>
169 void claw::buffered_istream<Stream>::move( unsigned int n )
171 assert( m_current + n <= m_end );
173 } // buffered_istream::move()
175 /*----------------------------------------------------------------------------*/
177 * \brief Closes this buffer (not the stream).
179 * The cursor of the stream is repositioned according to the remaining data, and
180 * the buffer is cleared.
182 template<typename Stream>
183 void claw::buffered_istream<Stream>::close()
185 m_stream.seekg( m_current - m_end, std::ios_base::cur );
188 } // buffered_istream::close()
190 /*----------------------------------------------------------------------------*/
192 * \brief Tell if there is still datas in the buffer/stream.
194 template<typename Stream>
195 claw::buffered_istream<Stream>::operator bool() const
197 return m_stream || (remaining() > 0);
198 } // buffered_istream::operator bool()