Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
// Stream buffer classes -*- C++ -*-
2
 
3
// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 2, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// You should have received a copy of the GNU General Public License along
17
// with this library; see the file COPYING.  If not, write to the Free
18
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19
// USA.
20
 
21
// As a special exception, you may use this file as part of a free software
22
// library without restriction.  Specifically, if other files instantiate
23
// templates or use macros or inline functions from this file, or you compile
24
// this file and link it with other files to produce an executable, this
25
// file does not by itself cause the resulting executable to be covered by
26
// the GNU General Public License.  This exception does not however
27
// invalidate any other reasons why the executable file might be covered by
28
// the GNU General Public License.
29
 
30
//
31
// ISO C++ 14882: 27.5  Stream buffers
32
//
33
 
34
#ifndef _CPP_BITS_STREAMBUF_TCC
35
#define _CPP_BITS_STREAMBUF_TCC 1
36
 
37
namespace std {
38
 
39
  template
40
    basic_streambuf<_CharT, _Traits>::int_type
41
    basic_streambuf<_CharT, _Traits>::
42
    sbumpc()
43
    {
44
      int_type __ret;
45
      if (_M_in_cur && _M_in_cur < _M_in_end)
46
	{
47
	  char_type __c = *gptr();
48
	  _M_in_cur_move(1);
49
	  __ret = traits_type::to_int_type(__c);
50
	}
51
      else
52
	__ret = this->uflow();
53
      return __ret;
54
    }
55
 
56
  template
57
    basic_streambuf<_CharT, _Traits>::int_type
58
    basic_streambuf<_CharT, _Traits>::
59
    sputbackc(char_type __c)
60
    {
61
      int_type __ret;
62
      bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur;
63
      bool __testne = _M_in_cur && !traits_type::eq(__c, this->gptr()[-1]);
64
      if (!__testpos || __testne)
65
	__ret = pbackfail(traits_type::to_int_type(__c));
66
      else
67
	{
68
	  _M_in_cur_move(-1);
69
	  __ret = traits_type::to_int_type(*this->gptr());
70
	}
71
      return __ret;
72
    }
73
 
74
  template
75
    basic_streambuf<_CharT, _Traits>::int_type
76
    basic_streambuf<_CharT, _Traits>::
77
    sungetc()
78
    {
79
      int_type __ret;
80
      if (_M_in_cur && _M_in_beg < _M_in_cur)
81
	{
82
	  _M_in_cur_move(-1);
83
	  __ret = traits_type::to_int_type(*_M_in_cur);
84
	}
85
      else
86
	__ret = this->pbackfail();
87
      return __ret;
88
    }
89
 
90
  // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
91
  // allocated space, and on certain (rare but entirely legal)
92
  // situations, there will be no allocated space yet the internal
93
  // buffers will still be valid. (This happens if setp is used to set
94
  // the internal buffer to say some externally-allocated sequence.)
95
  template
96
    basic_streambuf<_CharT, _Traits>::int_type
97
    basic_streambuf<_CharT, _Traits>::
98
    sputc(char_type __c)
99
    {
100
      int_type __ret;
101
      if (_M_out_buf_size())
102
	{
103
	  *_M_out_cur = __c;
104
	  _M_out_cur_move(1);
105
	  __ret = traits_type::to_int_type(__c);
106
	}
107
      else
108
	__ret = this->overflow(traits_type::to_int_type(__c));
109
      return __ret;
110
    }
111
 
112
  template
113
    streamsize
114
    basic_streambuf<_CharT, _Traits>::
115
    xsgetn(char_type* __s, streamsize __n)
116
    {
117
      streamsize __ret = 0;
118
      while (__ret < __n)
119
	{
120
	  size_t __buf_len = _M_in_end - _M_in_cur;
121
	  if (__buf_len > 0)
122
	    {
123
	      size_t __remaining = __n - __ret;
124
	      size_t __len = min(__buf_len, __remaining);
125
	      traits_type::copy(__s, _M_in_cur, __len);
126
	      __ret += __len;
127
	      __s += __len;
128
	      _M_in_cur_move(__len);
129
	    }
130
 
131
	  if (__ret < __n)
132
	    {
133
	      int_type __c = this->uflow();
134
	      if (__c != traits_type::eof())
135
		{
136
		  traits_type::assign(*__s++, traits_type::to_char_type(__c));
137
		  ++__ret;
138
		}
139
	      else
140
		break;
141
	    }
142
	}
143
      return __ret;
144
    }
145
 
146
  // Don't test against _M_buf + _M_buf_size, because _M_buf reflects
147
  // allocated space, and on certain (rare but entirely legal)
148
  // situations, there will be no allocated space yet the internal
149
  // buffers will still be valid. (This happens if setp is used to set
150
  // the internal buffer to say some externally-allocated sequence.)
151
  template
152
    streamsize
153
    basic_streambuf<_CharT, _Traits>::
154
    xsputn(const char_type* __s, streamsize __n)
155
    {
156
      streamsize __ret = 0;
157
      while (__ret < __n)
158
	{
159
	  off_type __buf_len = _M_out_buf_size();
160
	  if (__buf_len > 0)
161
	    {
162
	      off_type __remaining = __n - __ret;
163
	      off_type __len = min(__buf_len, __remaining);
164
	      traits_type::copy(_M_out_cur, __s, __len);
165
	      __ret += __len;
166
	      __s += __len;
167
	      _M_out_cur_move(__len);
168
	    }
169
 
170
	  if (__ret < __n)
171
	    {
172
	      int_type __c = this->overflow(traits_type::to_int_type(*__s));
173
	      if (__c != traits_type::eof())
174
		{
175
		  ++__ret;
176
		  ++__s;
177
		}
178
	      else
179
		break;
180
	    }
181
	}
182
      return __ret;
183
    }
184
 
185
  // Conceivably, this could be used to implement buffer-to-buffer
186
  // copies, if this was ever desired in an un-ambiguous way by the
187
  // standard. If so, then checks for __ios being zero would be
188
  // necessary.
189
  template
190
    streamsize
191
    __copy_streambufs(basic_ios<_CharT, _Traits>& __ios,
192
		      basic_streambuf<_CharT, _Traits>* __sbin,
193
		      basic_streambuf<_CharT, _Traits>* __sbout)
194
  {
195
      typedef typename _Traits::int_type	int_type;
196
 
197
      streamsize __ret = 0;
198
      streamsize __bufsize = __sbin->in_avail();
199
      streamsize __xtrct;
200
      bool __testput = __sbout->_M_mode & ios_base::out;
201
      try {
202
	while (__testput && __bufsize != -1)
203
	  {
204
	    __xtrct = __sbout->sputn(__sbin->gptr(), __bufsize);
205
	    __ret += __xtrct;
206
	    __sbin->_M_in_cur_move(__xtrct);
207
	    if (__xtrct == __bufsize)
208
	      {
209
		int_type __c = __sbin->sgetc();
210
		if (__c == _Traits::eof())
211
		  {
212
		    __ios.setstate(ios_base::eofbit);
213
		    break;
214
		  }
215
		__bufsize = __sbin->in_avail();
216
	      }
217
	    else
218
	      break;
219
	  }
220
      }
221
      catch(exception& __fail) {
222
	if ((__ios.exceptions() & ios_base::failbit) != 0)
223
	  __throw_exception_again;
224
      }
225
      return __ret;
226
    }
227
} // namespace std
228
 
229
#endif // _CPP_BITS_STREAMBUF_TCC
230