Claw  1.7.3
buffered_istream.tpp
Go to the documentation of this file.
1 /*
2  CLAW - a C++ Library Absolutely Wonderful
3 
4  CLAW is a free library without any particular aim but being useful to
5  anyone.
6 
7  Copyright (C) 2005-2011 Julien Jorge
8 
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.
13 
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.
18 
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
22 
23  contact: julien.jorge@gamned.org
24 */
30 #include <cassert>
31 
32 /*----------------------------------------------------------------------------*/
37 template<typename Stream>
39  : m_stream(f), m_begin(NULL), m_end(NULL), m_current(NULL),
40  m_buffer_size(1024)
41 {
42  m_begin = new char[m_buffer_size];
43  m_end = m_begin;
44  m_current = m_end;
45 } // buffered_istream::buffered_istream()
46 
47 /*----------------------------------------------------------------------------*/
51 template<typename Stream>
53 {
54  close();
55 
56  if (m_begin)
57  delete[] m_begin;
58 } // buffered_istream::~buffered_istream()
59 
60 /*----------------------------------------------------------------------------*/
64 template<typename Stream>
66 {
67  return m_end - m_current;
68 } // buffered_istream::remaining()
69 
70 /*----------------------------------------------------------------------------*/
76 template<typename Stream>
78 {
79  if ( n <= remaining() )
80  return true;
81 
82  unsigned int r = remaining();
83 
84  // we'll reach the end of the buffer
85  if ( m_current + n > m_begin + m_buffer_size )
86  {
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
91  {
92  m_buffer_size = n;
93 
94  char* new_buffer = new char[m_buffer_size];
95 
96  std::copy(m_current, m_end, new_buffer);
97 
98  delete[] m_begin;
99 
100  m_begin = new_buffer;
101  }
102 
103  m_current = m_begin;
104  m_end = m_current + r;
105  }
106 
107  m_stream.read( m_end, n-r );
108  m_end += m_stream.gcount();
109 
110  return !!m_stream;
111 } // buffered_istream::read_more()
112 
113 /*----------------------------------------------------------------------------*/
117 template<typename Stream>
119 {
120  return m_current;
121 } // buffered_istream::get_buffer()
122 
123 /*----------------------------------------------------------------------------*/
127 template<typename Stream>
129 {
130  assert( remaining() >= 1 );
131 
132  char result = *m_current;
133  ++m_current;
134 
135  return result;
136 } // buffered_istream::get_next()
137 
138 /*----------------------------------------------------------------------------*/
144 template<typename Stream>
145 bool claw::buffered_istream<Stream>::read( char* buf, unsigned int n )
146 {
147  while ( (n != 0) && !!(*this) )
148  {
149  if ( n > remaining() )
150  read_more(m_buffer_size);
151 
152  unsigned int len = std::min(n, remaining());
153 
154  std::copy( m_current, m_current + len, buf );
155  buf += len;
156  n -= len;
157  m_current += len;
158  }
159 
160  return n==0;
161 } // buffered_istream::read()
162 
163 /*----------------------------------------------------------------------------*/
168 template<typename Stream>
170 {
171  assert( m_current + n <= m_end );
172  m_current += n;
173 } // buffered_istream::move()
174 
175 /*----------------------------------------------------------------------------*/
182 template<typename Stream>
184 {
185  m_stream.seekg( m_current - m_end, std::ios_base::cur );
186  m_current = m_begin;
187  m_end = m_begin;
188 } // buffered_istream::close()
189 
190 /*----------------------------------------------------------------------------*/
194 template<typename Stream>
196 {
197  return m_stream || (remaining() > 0);
198 } // buffered_istream::operator bool()