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 // Cannot use _M_string = __s, since v3 strings are COW. 109 _M_string.assign(__s.data(), __s.size()); 110 _M_stringbuf_init(_M_mode); 111 } 112 113 protected: 114 // Common initialization code for both ctors goes here. 115 void 116 _M_stringbuf_init(ios_base::openmode __mode) 117 { 118 // _M_buf_size is a convenient alias for "what the streambuf 119 // thinks the allocated size of the string really is." This is 120 // necessary as ostringstreams are implemented with the 121 // streambufs having control of the allocation and 122 // re-allocation of the internal string object, _M_string. 123 _M_buf_size = _M_string.size(); 124 125 // NB: Start ostringstream buffers at 512 bytes. This is an 126 // experimental value (pronounced "arbitrary" in some of the 127 // hipper english-speaking countries), and can be changed to 128 // suit particular needs. 129 _M_buf_size_opt = 512; 130 _M_mode = __mode; 131 if (_M_mode & (ios_base::ate | ios_base::app)) 132 _M_really_sync(0, _M_buf_size); 133 else 134 _M_really_sync(0, 0); 135 } 136 137 // Overridden virtual functions: 138 virtual int_type 139 underflow() 140 { 141 if (_M_in_cur && _M_in_cur < _M_in_end) 142 return traits_type::to_int_type(*gptr()); 143 else 144 return traits_type::eof(); 145 } 146 147 virtual int_type 148 pbackfail(int_type __c = traits_type::eof()); 149 150 virtual int_type 151 overflow(int_type __c = traits_type::eof()); 152 153 virtual __streambuf_type* 154 setbuf(char_type* __s, streamsize __n) 155 { 156 if (__s && __n) 157 { 158 _M_string = __string_type(__s, __n); 159 _M_really_sync(0, 0); 160 } 161 return this; 162 } 163 164 virtual pos_type 165 seekoff(off_type __off, ios_base::seekdir __way, 166 ios_base::openmode __mode = ios_base::in | ios_base::out); 167 168 virtual pos_type 169 seekpos(pos_type __sp, 170 ios_base::openmode __mode = ios_base::in | ios_base::out); 171 172 // Internal function for correctly updating the internal buffer 173 // for a particular _M_string, due to initialization or 174 // re-sizing of an existing _M_string. 175 // Assumes: contents of _M_string and internal buffer match exactly. 176 // __i == _M_in_cur - _M_in_beg 177 // __o == _M_out_cur - _M_out_beg 178 virtual int 179 _M_really_sync(__size_type __i, __size_type __o) 180 { 181 char_type* __base = const_cast<char_type*>(_M_string.data()); 182 bool __testin = _M_mode & ios_base::in; 183 bool __testout = _M_mode & ios_base::out; 184 __size_type __len = _M_string.size(); 185 186 _M_buf = __base; 187 if (__testin) 188 this->setg(__base, __base + __i, __base + __len); 189 if (__testout) 190 { 191 this->setp(__base, __base + __len); 192 _M_out_cur += __o; 193 } 194 return 0; 195 } 196 }; 197 198 199 // 27.7.2 Template class basic_istringstream 200 template<typename _CharT, typename _Traits, typename _Alloc> 201 class basic_istringstream : public basic_istream<_CharT, _Traits> 202 { 203 public: 204 // Types: 205 typedef _CharT char_type; 206 typedef _Traits traits_type; 207 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 208 // 251. basic_stringbuf missing allocator_type 209 typedef _Alloc allocator_type; 210 #endif 211 typedef typename traits_type::int_type int_type; 212 typedef typename traits_type::pos_type pos_type; 213 typedef typename traits_type::off_type off_type; 214 215 // Non-standard types: 216 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 217 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 218 typedef basic_istream<char_type, traits_type> __istream_type; 219 220 private: 221 __stringbuf_type _M_stringbuf; 222 223 public: 224 // Constructors: 225 explicit 226 basic_istringstream(ios_base::openmode __mode = ios_base::in) 227 : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in) 228 { this->init(&_M_stringbuf); } 229 230 explicit 231 basic_istringstream(const __string_type& __str, 232 ios_base::openmode __mode = ios_base::in) 233 : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in) 234 { this->init(&_M_stringbuf); } 235 236 ~basic_istringstream() 237 { } 238 239 // Members: 240 __stringbuf_type* 241 rdbuf() const 242 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 243 244 __string_type 245 str() const 246 { return _M_stringbuf.str(); } 247 248 void 249 str(const __string_type& __s) 250 { _M_stringbuf.str(__s); } 251 }; 252 253 254 // 27.7.3 Template class basic_ostringstream 255 template <typename _CharT, typename _Traits, typename _Alloc> 256 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 257 { 258 public: 259 // Types: 260 typedef _CharT char_type; 261 typedef _Traits traits_type; 262 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 263 // 251. basic_stringbuf missing allocator_type 264 typedef _Alloc allocator_type; 265 #endif 266 typedef typename traits_type::int_type int_type; 267 typedef typename traits_type::pos_type pos_type; 268 typedef typename traits_type::off_type off_type; 269 270 // Non-standard types: 271 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 272 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 273 typedef basic_ostream<char_type, traits_type> __ostream_type; 274 275 private: 276 __stringbuf_type _M_stringbuf; 277 278 public: 279 // Constructors/destructor: 280 explicit 281 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 282 : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out) 283 { this->init(&_M_stringbuf); } 284 285 explicit 286 basic_ostringstream(const __string_type& __str, 287 ios_base::openmode __mode = ios_base::out) 288 : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out) 289 { this->init(&_M_stringbuf); } 290 291 ~basic_ostringstream() 292 { } 293 294 // Members: 295 __stringbuf_type* 296 rdbuf() const 297 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 298 299 __string_type 300 str() const 301 { return _M_stringbuf.str(); } 302 303 void 304 str(const __string_type& __s) 305 { _M_stringbuf.str(__s); } 306 }; 307 308 309 // 27.7.4 Template class basic_stringstream 310 template <typename _CharT, typename _Traits, typename _Alloc> 311 class basic_stringstream : public basic_iostream<_CharT, _Traits> 312 { 313 public: 314 // Types: 315 typedef _CharT char_type; 316 typedef _Traits traits_type; 317 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 318 // 251. basic_stringbuf missing allocator_type 319 typedef _Alloc allocator_type; 320 #endif 321 typedef typename traits_type::int_type int_type; 322 typedef typename traits_type::pos_type pos_type; 323 typedef typename traits_type::off_type off_type; 324 325 // Non-standard Types: 326 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 327 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 328 typedef basic_iostream<char_type, traits_type> __iostream_type; 329 330 private: 331 __stringbuf_type _M_stringbuf; 332 333 public: 334 // Constructors/destructors 335 explicit 336 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 337 : __iostream_type(NULL), _M_stringbuf(__m) 338 { this->init(&_M_stringbuf); } 339 340 explicit 341 basic_stringstream(const __string_type& __str, 342 ios_base::openmode __m = ios_base::out | ios_base::in) 343 : __iostream_type(NULL), _M_stringbuf(__str, __m) 344 { this->init(&_M_stringbuf); } 345 346 ~basic_stringstream() 347 { } 348 349 // Members: 350 __stringbuf_type* 351 rdbuf() const 352 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 353 354 __string_type 355 str() const 356 { return _M_stringbuf.str(); } 357 358 void 359 str(const __string_type& __s) 360 { _M_stringbuf.str(__s); } 361 }; 362 } // namespace std 363 364 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT 365 # define export 366 #endif 367 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS 368 # include <bits/sstream.tcc> 369 #endif 370 371 #endif 372