1 // String based streams -*- C++ -*- 2 3 // Copyright (C) 1997, 1998, 1999, 2002 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.7 String-based streams 32 // 33 34 /** @file sstream 35 * This is a Standard C++ Library header. You should @c #include this header 36 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 37 */ 38 39 #ifndef _CPP_SSTREAM 40 #define _CPP_SSTREAM 1 41 42 #pragma GCC system_header 43 44 #include <istream> 45 #include <ostream> 46 47 namespace std 48 { 49 template<typename _CharT, typename _Traits, typename _Alloc> 50 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 51 { 52 public: 53 // Types: 54 typedef _CharT char_type; 55 typedef _Traits traits_type; 56 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 57 // 251. basic_stringbuf missing allocator_type 58 typedef _Alloc allocator_type; 59 #endif 60 typedef typename traits_type::int_type int_type; 61 typedef typename traits_type::pos_type pos_type; 62 typedef typename traits_type::off_type off_type; 63 64 // Non-standard Types: 65 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 66 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 67 typedef typename __string_type::size_type __size_type; 68 69 protected: 70 // Data Members: 71 __string_type _M_string; 72 73 public: 74 // Constructors: 75 explicit 76 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 77 : __streambuf_type(), _M_string() 78 { _M_stringbuf_init(__mode); } 79 80 explicit 81 basic_stringbuf(const __string_type& __str, 82 ios_base::openmode __mode = ios_base::in | ios_base::out) 83 : __streambuf_type(), _M_string(__str.data(), __str.size()) 84 { _M_stringbuf_init(__mode); } 85 86 // Get and set: 87 __string_type 88 str() const 89 { 90 if (_M_mode & ios_base::out) 91 { 92 // This is the deal: _M_string.size() is a value that 93 // represents the size of the initial string that makes 94 // _M_string, and may not be the correct size of the 95 // current stringbuf internal buffer. 96 __size_type __len = _M_string.size(); 97 if (_M_out_cur > _M_out_beg) 98 __len = max(__size_type(_M_out_end - _M_out_beg), __len); 99 return __string_type(_M_out_beg, _M_out_beg + __len); 100 } 101 else 102 return _M_string; 103 } 104 105 void 106 str(const __string_type& __s) 107 { 108 _M_string = __s; 109 _M_stringbuf_init(_M_mode); 110 } 111 112 protected: 113 // Common initialization code for both ctors goes here. 114 void 115 _M_stringbuf_init(ios_base::openmode __mode) 116 { 117 // _M_buf_size is a convenient alias for "what the streambuf 118 // thinks the allocated size of the string really is." This is 119 // necessary as ostringstreams are implemented with the 120 // streambufs having control of the allocation and 121 // re-allocation of the internal string object, _M_string. 122 _M_buf_size = _M_string.size(); 123 124 // NB: Start ostringstream buffers at 512 bytes. This is an 125 // experimental value (pronounced "arbitrary" in some of the 126 // hipper english-speaking countries), and can be changed to 127 // suit particular needs. 128 _M_buf_size_opt = 512; 129 _M_mode = __mode; 130 if (_M_mode & (ios_base::ate | ios_base::app)) 131 _M_really_sync(0, _M_buf_size); 132 else 133 _M_really_sync(0, 0); 134 } 135 136 // Overridden virtual functions: 137 virtual int_type 138 underflow() 139 { 140 if (_M_in_cur && _M_in_cur < _M_in_end) 141 return traits_type::to_int_type(*gptr()); 142 else 143 return traits_type::eof(); 144 } 145 146 virtual int_type 147 pbackfail(int_type __c = traits_type::eof()); 148 149 virtual int_type 150 overflow(int_type __c = traits_type::eof()); 151 152 virtual __streambuf_type* 153 setbuf(char_type* __s, streamsize __n) 154 { 155 if (__s && __n) 156 { 157 _M_string = __string_type(__s, __n); 158 _M_really_sync(0, 0); 159 } 160 return this; 161 } 162 163 virtual pos_type 164 seekoff(off_type __off, ios_base::seekdir __way, 165 ios_base::openmode __mode = ios_base::in | ios_base::out); 166 167 virtual pos_type 168 seekpos(pos_type __sp, 169 ios_base::openmode __mode = ios_base::in | ios_base::out); 170 171 // Internal function for correctly updating the internal buffer 172 // for a particular _M_string, due to initialization or 173 // re-sizing of an existing _M_string. 174 // Assumes: contents of _M_string and internal buffer match exactly. 175 // __i == _M_in_cur - _M_in_beg 176 // __o == _M_out_cur - _M_out_beg 177 virtual int 178 _M_really_sync(__size_type __i, __size_type __o) 179 { 180 char_type* __base = const_cast<char_type*>(_M_string.data()); 181 bool __testin = _M_mode & ios_base::in; 182 bool __testout = _M_mode & ios_base::out; 183 __size_type __len = _M_string.size(); 184 185 _M_buf = __base; 186 if (__testin) 187 this->setg(__base, __base + __i, __base + __len); 188 if (__testout) 189 { 190 this->setp(__base, __base + __len); 191 _M_out_cur += __o; 192 } 193 return 0; 194 } 195 }; 196 197 198 // 27.7.2 Template class basic_istringstream 199 template<typename _CharT, typename _Traits, typename _Alloc> 200 class basic_istringstream : public basic_istream<_CharT, _Traits> 201 { 202 public: 203 // Types: 204 typedef _CharT char_type; 205 typedef _Traits traits_type; 206 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 207 // 251. basic_stringbuf missing allocator_type 208 typedef _Alloc allocator_type; 209 #endif 210 typedef typename traits_type::int_type int_type; 211 typedef typename traits_type::pos_type pos_type; 212 typedef typename traits_type::off_type off_type; 213 214 // Non-standard types: 215 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 216 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 217 typedef basic_istream<char_type, traits_type> __istream_type; 218 219 private: 220 __stringbuf_type _M_stringbuf; 221 222 public: 223 // Constructors: 224 explicit 225 basic_istringstream(ios_base::openmode __mode = ios_base::in) 226 : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in) 227 { this->init(&_M_stringbuf); } 228 229 explicit 230 basic_istringstream(const __string_type& __str, 231 ios_base::openmode __mode = ios_base::in) 232 : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in) 233 { this->init(&_M_stringbuf); } 234 235 ~basic_istringstream() 236 { } 237 238 // Members: 239 __stringbuf_type* 240 rdbuf() const 241 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 242 243 __string_type 244 str() const 245 { return _M_stringbuf.str(); } 246 247 void 248 str(const __string_type& __s) 249 { _M_stringbuf.str(__s); } 250 }; 251 252 253 // 27.7.3 Template class basic_ostringstream 254 template <typename _CharT, typename _Traits, typename _Alloc> 255 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 256 { 257 public: 258 // Types: 259 typedef _CharT char_type; 260 typedef _Traits traits_type; 261 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 262 // 251. basic_stringbuf missing allocator_type 263 typedef _Alloc allocator_type; 264 #endif 265 typedef typename traits_type::int_type int_type; 266 typedef typename traits_type::pos_type pos_type; 267 typedef typename traits_type::off_type off_type; 268 269 // Non-standard types: 270 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 271 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 272 typedef basic_ostream<char_type, traits_type> __ostream_type; 273 274 private: 275 __stringbuf_type _M_stringbuf; 276 277 public: 278 // Constructors/destructor: 279 explicit 280 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 281 : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out) 282 { this->init(&_M_stringbuf); } 283 284 explicit 285 basic_ostringstream(const __string_type& __str, 286 ios_base::openmode __mode = ios_base::out) 287 : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out) 288 { this->init(&_M_stringbuf); } 289 290 ~basic_ostringstream() 291 { } 292 293 // Members: 294 __stringbuf_type* 295 rdbuf() const 296 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 297 298 __string_type 299 str() const 300 { return _M_stringbuf.str(); } 301 302 void 303 str(const __string_type& __s) 304 { _M_stringbuf.str(__s); } 305 }; 306 307 308 // 27.7.4 Template class basic_stringstream 309 template <typename _CharT, typename _Traits, typename _Alloc> 310 class basic_stringstream : public basic_iostream<_CharT, _Traits> 311 { 312 public: 313 // Types: 314 typedef _CharT char_type; 315 typedef _Traits traits_type; 316 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 317 // 251. basic_stringbuf missing allocator_type 318 typedef _Alloc allocator_type; 319 #endif 320 typedef typename traits_type::int_type int_type; 321 typedef typename traits_type::pos_type pos_type; 322 typedef typename traits_type::off_type off_type; 323 324 // Non-standard Types: 325 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 326 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 327 typedef basic_iostream<char_type, traits_type> __iostream_type; 328 329 private: 330 __stringbuf_type _M_stringbuf; 331 332 public: 333 // Constructors/destructors 334 explicit 335 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 336 : __iostream_type(NULL), _M_stringbuf(__m) 337 { this->init(&_M_stringbuf); } 338 339 explicit 340 basic_stringstream(const __string_type& __str, 341 ios_base::openmode __m = ios_base::out | ios_base::in) 342 : __iostream_type(NULL), _M_stringbuf(__str, __m) 343 { this->init(&_M_stringbuf); } 344 345 ~basic_stringstream() 346 { } 347 348 // Members: 349 __stringbuf_type* 350 rdbuf() const 351 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 352 353 __string_type 354 str() const 355 { return _M_stringbuf.str(); } 356 357 void 358 str(const __string_type& __s) 359 { _M_stringbuf.str(__s); } 360 }; 361 } // namespace std 362 363 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT 364 # define export 365 #endif 366 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS 367 # include <bits/sstream.tcc> 368 #endif 369 370 #endif 371