Only allow allow rotations by a constant amount.
[official-gcc.git] / libstdc++-v3 / bits / sstream.tcc
blob5c737b4fa2e5888c20b96f8fcc6b7bc50dd587e7
1 // String based streams -*- C++ -*-
3 // Copyright (C) 1997-1999 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.
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.
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.
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.
31 // ISO C++ 14882: 27.7  String-based streams
34 #ifndef _CPP_BITS_SSTREAM_TCC
35 #define _CPP_BITS_SSTREAM_TCC   1
37 #include <bits/std_sstream.h>
39 namespace std {
41   template <class _CharT, class _Traits, class _Alloc>
42     basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 
43     basic_stringbuf<_CharT, _Traits, _Alloc>::
44     pbackfail(int_type __c)
45     {
46       int_type __ret = traits_type::eof();
47       bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
48       bool __testpos = _M_in_cur && _M_in_beg < _M_in_cur; 
49       
50       // Try to put back __c into input sequence in one of three ways.
51       // Order these tests done in is unspecified by the standard.
52       if (__testpos)
53         {
54           if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])
55               && !__testeof)
56             {
57               --_M_in_cur;
58               __ret = __c;
59             }
60           else if (!__testeof)
61             {
62               --_M_in_cur;
63               *_M_in_cur = traits_type::to_char_type(__c);
64               __ret = __c;
65             }
66           else if (__testeof)
67             {
68               --_M_in_cur;
69               __ret = traits_type::not_eof(__c);
70             }
71         }
72       return __ret;
73     }
74   
75   template <class _CharT, class _Traits, class _Alloc>
76     basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 
77     basic_stringbuf<_CharT, _Traits, _Alloc>::
78     overflow(int_type __c)
79     {
80       int_type __ret = traits_type::eof();
81       bool __testeof = traits_type::eq_int_type(__c, __ret);
82       bool __testwrite = _M_out_cur < _M_buf + _M_buf_size;
83       bool __testout = _M_mode & ios_base::out;
85       // Try to append __c into output sequence in one of two ways.
86       // Order these tests done in is unspecified by the standard.
87       if (__testout)
88         {
89           if (!__testeof)
90             {
91               __size_type __len = max(_M_buf_size, _M_buf_size_opt);
92               __len *= 2;
94               if (__testwrite)
95                 __ret = this->sputc(__c);
96               else if (__len <= _M_string.max_size())
97                 {
98                   // Force-allocate, re-sync.
99                   _M_string = this->str();
100                   _M_string.reserve(__len);
101                   _M_buf_size = static_cast<int_type>(__len);
102                   _M_really_sync(_M_in_cur - _M_in_beg, 
103                                  _M_out_cur - _M_out_beg);
104                   *_M_out_cur = traits_type::to_char_type(__c);
105                   _M_out_cur_move(1);
106                   __ret = __c;
107                 }
108             }
109           else
110             __ret = traits_type::not_eof(__c);
111         }
112       return __ret;
113     }
115   template <class _CharT, class _Traits, class _Alloc>
116     basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
117     basic_stringbuf<_CharT, _Traits, _Alloc>::
118     seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
119     {
120       pos_type __ret =  pos_type(off_type(-1)); 
121       bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
122       bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
123       bool __testboth = __testin && __testout && __way != ios_base::cur;
124       
125       if (_M_buf_size && ((__testin != __testout) || __testboth))
126         {
127           char_type* __beg = _M_buf;
128           char_type* __curi = NULL;
129           char_type* __curo = NULL;
130           char_type* __endi = NULL;
131           char_type* __endo = NULL;
133           if (__testin)
134             {
135               __curi = this->gptr();
136               __endi = this->egptr();
137             }
138           if (__testout)
139             {
140               __curo = this->pptr();
141               __endo = this->epptr();
142             }
144           off_type __newoffi = 0;
145           off_type __newoffo = 0;
146           if (__way == ios_base::cur)
147             {
148               __newoffi = __curi - __beg;
149               __newoffo = __curo - __beg;
150             }
151           else if (__way == ios_base::end)
152             {
153               __newoffi = __endi - __beg;
154               __newoffo = __endo - __beg;
155             }
157           if (__testin
158               && __newoffi + __off >= 0 && __endi - __beg >= __newoffi + __off)
159             {
160               _M_in_cur = __beg + __newoffi + __off;
161               __ret = pos_type(__newoffi);
162             }
163           if (__testout
164               && __newoffo + __off >= 0 && __endo - __beg >= __newoffo + __off)
165             {
166               _M_out_cur_move(__newoffo + __off - (_M_out_cur - __beg));
167               __ret = pos_type(__newoffo);
168             }
169         }
170       return __ret;
171     }
173   template <class _CharT, class _Traits, class _Alloc>
174     basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type
175     basic_stringbuf<_CharT, _Traits, _Alloc>::
176     seekpos(pos_type __sp, ios_base::openmode __mode)
177     {
178       pos_type __ret =  pos_type(off_type(-1)); 
179       off_type __pos = __sp._M_position();
180       char_type* __beg = NULL;
181       char_type* __end = NULL;
182       bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
183       bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
184       
185       if (__testin)
186         {
187           __beg = this->eback();
188           __end = this->egptr();
189         }
190       if (__testout)
191         {
192           __beg = this->pbase();
193           __end = _M_buf + _M_buf_size;
194         }
196       if (0 <= __pos && __pos <= __end - __beg)
197         {
198           // Need to set both of these if applicable
199           if (__testin)
200             _M_in_cur = _M_in_beg + __pos;
201           if (__testout)
202             _M_out_cur_move((__pos) - (_M_out_cur - __beg));
203           __ret = pos_type(off_type(__pos));
204         }
205       
206       return __ret;
207     }
209 } // namespace std
211 #endif  /* _CPP_BITS_SSTREAM_TCC */