1 // String based streams -*- C++ -*- 2 3 // Copyright (C) 1997, 1998, 1999, 2002, 2003 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 // [27.7.1] template class basic_stringbuf 50 /** 51 * @brief The actual work of input and output (for std::string). 52 * 53 * This class associates either or both of its input and output sequences 54 * with a sequence of characters, which can be initialized from, or made 55 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 56 * 57 * For this class, open modes (of type @c ios_base::openmode) have 58 * @c in set if the input sequence can be read, and @c out set if the 59 * output sequence can be written. 60 */ 61 template<typename _CharT, typename _Traits, typename _Alloc> 62 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 63 { 64 public: 65 // Types: 66 typedef _CharT char_type; 67 typedef _Traits traits_type; 68 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 69 // 251. basic_stringbuf missing allocator_type 70 typedef _Alloc allocator_type; 71 #endif 72 typedef typename traits_type::int_type int_type; 73 typedef typename traits_type::pos_type pos_type; 74 typedef typename traits_type::off_type off_type; 75 76 //@{ 77 /** 78 * @if maint 79 * @doctodo 80 * @endif 81 */ 82 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 83 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 84 typedef typename __string_type::size_type __size_type; 85 //@} 86 87 protected: 88 // Data Members: 89 /** 90 * @if maint 91 * @doctodo 92 * @endif 93 */ 94 __string_type _M_string; 95 96 public: 97 // Constructors: 98 /** 99 * @brief Starts with an empty string buffer. 100 * @param mode Whether the buffer can read, or write, or both. 101 * 102 * The default constructor initializes the parent class using its 103 * own default ctor. 104 */ 105 explicit 106 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) __streambuf_type()107 : __streambuf_type(), _M_string() 108 { _M_stringbuf_init(__mode); } 109 110 /** 111 * @brief Starts with an existing string buffer. 112 * @param str A string to copy as a starting buffer. 113 * @param mode Whether the buffer can read, or write, or both. 114 * 115 * This constructor initializes the parent class using its 116 * own default ctor. 117 */ 118 explicit 119 basic_stringbuf(const __string_type& __str, 120 ios_base::openmode __mode = ios_base::in | ios_base::out) __streambuf_type()121 : __streambuf_type(), _M_string(__str.data(), __str.size()) 122 { _M_stringbuf_init(__mode); } 123 124 // Get and set: 125 /** 126 * @brief Copying out the string buffer. 127 * @return A copy of one of the underlying sequences. 128 * 129 * "If the buffer is only created in input mode, the underlying 130 * character sequence is equal to the input sequence; otherwise, it 131 * is equal to the output sequence." [27.7.1.2]/1 132 */ 133 __string_type str()134 str() const 135 { 136 if (_M_mode & ios_base::out) 137 { 138 // This is the deal: _M_string.size() is a value that 139 // represents the size of the initial string that makes 140 // _M_string, and may not be the correct size of the 141 // current stringbuf internal buffer. 142 __size_type __len = _M_string.size(); 143 if (_M_out_end > _M_out_beg) 144 __len = max(__size_type(_M_out_end - _M_out_beg), __len); 145 return __string_type(_M_out_beg, _M_out_beg + __len); 146 } 147 else 148 return _M_string; 149 } 150 151 /** 152 * @brief Setting a new buffer. 153 * @param s The string to use as a new sequence. 154 * 155 * Deallocates any previous stored sequence, then copies @a s to 156 * use as a new one. 157 */ 158 void str(const __string_type & __s)159 str(const __string_type& __s) 160 { 161 // Cannot use _M_string = __s, since v3 strings are COW. 162 _M_string.assign(__s.data(), __s.size()); 163 _M_stringbuf_init(_M_mode); 164 } 165 166 protected: 167 // Common initialization code for both ctors goes here. 168 /** 169 * @if maint 170 * @doctodo 171 * @endif 172 */ 173 void _M_stringbuf_init(ios_base::openmode __mode)174 _M_stringbuf_init(ios_base::openmode __mode) 175 { 176 // _M_buf_size is a convenient alias for "what the streambuf 177 // thinks the allocated size of the string really is." This is 178 // necessary as ostringstreams are implemented with the 179 // streambufs having control of the allocation and 180 // re-allocation of the internal string object, _M_string. 181 _M_buf_size = _M_string.size(); 182 183 // NB: Start ostringstream buffers at 512 bytes. This is an 184 // experimental value (pronounced "arbitrary" in some of the 185 // hipper english-speaking countries), and can be changed to 186 // suit particular needs. 187 _M_buf_size_opt = 512; 188 _M_mode = __mode; 189 if (_M_mode & (ios_base::ate | ios_base::app)) 190 _M_really_sync(0, _M_buf_size); 191 else 192 _M_really_sync(0, 0); 193 } 194 195 // Overridden virtual functions: 196 // [documentation is inherited] 197 virtual int_type underflow()198 underflow() 199 { 200 if (_M_in_cur && _M_in_cur < _M_in_end) 201 return traits_type::to_int_type(*gptr()); 202 else 203 return traits_type::eof(); 204 } 205 206 // [documentation is inherited] 207 virtual int_type 208 pbackfail(int_type __c = traits_type::eof()); 209 210 // [documentation is inherited] 211 virtual int_type 212 overflow(int_type __c = traits_type::eof()); 213 214 /** 215 * @brief Manipulates the buffer. 216 * @param s Pointer to a buffer area. 217 * @param n Size of @a s. 218 * @return @c this 219 * 220 * If no buffer has already been created, and both @a s and @a n are 221 * non-zero, then @c s is used as a buffer; see 222 * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 223 * for more. 224 */ 225 virtual __streambuf_type* setbuf(char_type * __s,streamsize __n)226 setbuf(char_type* __s, streamsize __n) 227 { 228 if (__s && __n) 229 { 230 _M_string = __string_type(__s, __n); 231 _M_really_sync(0, 0); 232 } 233 return this; 234 } 235 236 // [documentation is inherited] 237 virtual pos_type 238 seekoff(off_type __off, ios_base::seekdir __way, 239 ios_base::openmode __mode = ios_base::in | ios_base::out); 240 241 // [documentation is inherited] 242 virtual pos_type 243 seekpos(pos_type __sp, 244 ios_base::openmode __mode = ios_base::in | ios_base::out); 245 246 // Internal function for correctly updating the internal buffer 247 // for a particular _M_string, due to initialization or 248 // re-sizing of an existing _M_string. 249 // Assumes: contents of _M_string and internal buffer match exactly. 250 // __i == _M_in_cur - _M_in_beg 251 // __o == _M_out_cur - _M_out_beg 252 /** 253 * @if maint 254 * @doctodo 255 * @endif 256 */ 257 virtual int _M_really_sync(__size_type __i,__size_type __o)258 _M_really_sync(__size_type __i, __size_type __o) 259 { 260 char_type* __base = const_cast<char_type*>(_M_string.data()); 261 bool __testin = _M_mode & ios_base::in; 262 bool __testout = _M_mode & ios_base::out; 263 __size_type __len = _M_string.size(); 264 265 _M_buf = __base; 266 if (__testin) 267 this->setg(__base, __base + __i, __base + __len); 268 if (__testout) 269 { 270 this->setp(__base, __base + __len); 271 _M_out_cur += __o; 272 } 273 return 0; 274 } 275 }; 276 277 278 // [27.7.2] Template class basic_istringstream 279 /** 280 * @brief Controlling input for std::string. 281 * 282 * This class supports reading from objects of type std::basic_string, 283 * using the inherited functions from std::basic_istream. To control 284 * the associated sequence, an instance of std::basic_stringbuf is used, 285 * which this page refers to as @c sb. 286 */ 287 template<typename _CharT, typename _Traits, typename _Alloc> 288 class basic_istringstream : public basic_istream<_CharT, _Traits> 289 { 290 public: 291 // Types: 292 typedef _CharT char_type; 293 typedef _Traits traits_type; 294 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 295 // 251. basic_stringbuf missing allocator_type 296 typedef _Alloc allocator_type; 297 #endif 298 typedef typename traits_type::int_type int_type; 299 typedef typename traits_type::pos_type pos_type; 300 typedef typename traits_type::off_type off_type; 301 302 // Non-standard types: 303 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 304 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 305 typedef basic_istream<char_type, traits_type> __istream_type; 306 307 private: 308 /** 309 * @if maint 310 * @doctodo 311 * @endif 312 */ 313 __stringbuf_type _M_stringbuf; 314 315 public: 316 // Constructors: 317 /** 318 * @brief Default constructor starts with an empty string buffer. 319 * @param mode Whether the buffer can read, or write, or both. 320 * 321 * @c ios_base::in is automatically included in @a mode. 322 * 323 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 324 * class initializer. Does not allocate any buffer. 325 * 326 * @if maint 327 * That's a lie. We initialize the base class with NULL, because the 328 * string class does its own memory management. 329 * @endif 330 */ 331 explicit 332 basic_istringstream(ios_base::openmode __mode = ios_base::in) __istream_type(NULL)333 : __istream_type(NULL), _M_stringbuf(__mode | ios_base::in) 334 { this->init(&_M_stringbuf); } 335 336 /** 337 * @brief Starts with an existing string buffer. 338 * @param str A string to copy as a starting buffer. 339 * @param mode Whether the buffer can read, or write, or both. 340 * 341 * @c ios_base::in is automatically included in @a mode. 342 * 343 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 344 * to the base class initializer. 345 * 346 * @if maint 347 * That's a lie. We initialize the base class with NULL, because the 348 * string class does its own memory management. 349 * @endif 350 */ 351 explicit 352 basic_istringstream(const __string_type& __str, 353 ios_base::openmode __mode = ios_base::in) __istream_type(NULL)354 : __istream_type(NULL), _M_stringbuf(__str, __mode | ios_base::in) 355 { this->init(&_M_stringbuf); } 356 357 /** 358 * @brief The destructor does nothing. 359 * 360 * The buffer is deallocated by the stringbuf object, not the 361 * formatting stream. 362 */ ~basic_istringstream()363 ~basic_istringstream() 364 { } 365 366 // Members: 367 /** 368 * @brief Accessing the underlying buffer. 369 * @return The current basic_stringbuf buffer. 370 * 371 * This hides both signatures of std::basic_ios::rdbuf(). 372 */ 373 __stringbuf_type* rdbuf()374 rdbuf() const 375 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 376 377 /** 378 * @brief Copying out the string buffer. 379 * @return @c rdbuf()->str() 380 */ 381 __string_type str()382 str() const 383 { return _M_stringbuf.str(); } 384 385 /** 386 * @brief Setting a new buffer. 387 * @param s The string to use as a new sequence. 388 * 389 * Calls @c rdbuf()->str(s). 390 */ 391 void str(const __string_type & __s)392 str(const __string_type& __s) 393 { _M_stringbuf.str(__s); } 394 }; 395 396 397 // [27.7.3] Template class basic_ostringstream 398 /** 399 * @brief Controlling output for std::string. 400 * 401 * This class supports writing to objects of type std::basic_string, 402 * using the inherited functions from std::basic_ostream. To control 403 * the associated sequence, an instance of std::basic_stringbuf is used, 404 * which this page refers to as @c sb. 405 */ 406 template <typename _CharT, typename _Traits, typename _Alloc> 407 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 408 { 409 public: 410 // Types: 411 typedef _CharT char_type; 412 typedef _Traits traits_type; 413 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 414 // 251. basic_stringbuf missing allocator_type 415 typedef _Alloc allocator_type; 416 #endif 417 typedef typename traits_type::int_type int_type; 418 typedef typename traits_type::pos_type pos_type; 419 typedef typename traits_type::off_type off_type; 420 421 // Non-standard types: 422 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 423 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 424 typedef basic_ostream<char_type, traits_type> __ostream_type; 425 426 private: 427 /** 428 * @if maint 429 * @doctodo 430 * @endif 431 */ 432 __stringbuf_type _M_stringbuf; 433 434 public: 435 // Constructors/destructor: 436 /** 437 * @brief Default constructor starts with an empty string buffer. 438 * @param mode Whether the buffer can read, or write, or both. 439 * 440 * @c ios_base::out is automatically included in @a mode. 441 * 442 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 443 * class initializer. Does not allocate any buffer. 444 * 445 * @if maint 446 * That's a lie. We initialize the base class with NULL, because the 447 * string class does its own memory management. 448 * @endif 449 */ 450 explicit 451 basic_ostringstream(ios_base::openmode __mode = ios_base::out) __ostream_type(NULL)452 : __ostream_type(NULL), _M_stringbuf(__mode | ios_base::out) 453 { this->init(&_M_stringbuf); } 454 455 /** 456 * @brief Starts with an existing string buffer. 457 * @param str A string to copy as a starting buffer. 458 * @param mode Whether the buffer can read, or write, or both. 459 * 460 * @c ios_base::out is automatically included in @a mode. 461 * 462 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 463 * to the base class initializer. 464 * 465 * @if maint 466 * That's a lie. We initialize the base class with NULL, because the 467 * string class does its own memory management. 468 * @endif 469 */ 470 explicit 471 basic_ostringstream(const __string_type& __str, 472 ios_base::openmode __mode = ios_base::out) __ostream_type(NULL)473 : __ostream_type(NULL), _M_stringbuf(__str, __mode | ios_base::out) 474 { this->init(&_M_stringbuf); } 475 476 /** 477 * @brief The destructor does nothing. 478 * 479 * The buffer is deallocated by the stringbuf object, not the 480 * formatting stream. 481 */ ~basic_ostringstream()482 ~basic_ostringstream() 483 { } 484 485 // Members: 486 /** 487 * @brief Accessing the underlying buffer. 488 * @return The current basic_stringbuf buffer. 489 * 490 * This hides both signatures of std::basic_ios::rdbuf(). 491 */ 492 __stringbuf_type* rdbuf()493 rdbuf() const 494 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 495 496 /** 497 * @brief Copying out the string buffer. 498 * @return @c rdbuf()->str() 499 */ 500 __string_type str()501 str() const 502 { return _M_stringbuf.str(); } 503 504 /** 505 * @brief Setting a new buffer. 506 * @param s The string to use as a new sequence. 507 * 508 * Calls @c rdbuf()->str(s). 509 */ 510 void str(const __string_type & __s)511 str(const __string_type& __s) 512 { _M_stringbuf.str(__s); } 513 }; 514 515 516 // [27.7.4] Template class basic_stringstream 517 /** 518 * @brief Controlling input and output for std::string. 519 * 520 * This class supports reading from and writing to objects of type 521 * std::basic_string, using the inherited functions from 522 * std::basic_iostream. To control the associated sequence, an instance 523 * of std::basic_stringbuf is used, which this page refers to as @c sb. 524 */ 525 template <typename _CharT, typename _Traits, typename _Alloc> 526 class basic_stringstream : public basic_iostream<_CharT, _Traits> 527 { 528 public: 529 // Types: 530 typedef _CharT char_type; 531 typedef _Traits traits_type; 532 #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 533 // 251. basic_stringbuf missing allocator_type 534 typedef _Alloc allocator_type; 535 #endif 536 typedef typename traits_type::int_type int_type; 537 typedef typename traits_type::pos_type pos_type; 538 typedef typename traits_type::off_type off_type; 539 540 // Non-standard Types: 541 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 542 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 543 typedef basic_iostream<char_type, traits_type> __iostream_type; 544 545 private: 546 /** 547 * @if maint 548 * @doctodo 549 * @endif 550 */ 551 __stringbuf_type _M_stringbuf; 552 553 public: 554 // Constructors/destructors 555 /** 556 * @brief Default constructor starts with an empty string buffer. 557 * @param mode Whether the buffer can read, or write, or both. 558 * 559 * Initializes @c sb using @c mode, and passes @c &sb to the base 560 * class initializer. Does not allocate any buffer. 561 * 562 * @if maint 563 * That's a lie. We initialize the base class with NULL, because the 564 * string class does its own memory management. 565 * @endif 566 */ 567 explicit 568 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) __iostream_type(NULL)569 : __iostream_type(NULL), _M_stringbuf(__m) 570 { this->init(&_M_stringbuf); } 571 572 /** 573 * @brief Starts with an existing string buffer. 574 * @param str A string to copy as a starting buffer. 575 * @param mode Whether the buffer can read, or write, or both. 576 * 577 * Initializes @c sb using @a str and @c mode, and passes @c &sb 578 * to the base class initializer. 579 * 580 * @if maint 581 * That's a lie. We initialize the base class with NULL, because the 582 * string class does its own memory management. 583 * @endif 584 */ 585 explicit 586 basic_stringstream(const __string_type& __str, 587 ios_base::openmode __m = ios_base::out | ios_base::in) __iostream_type(NULL)588 : __iostream_type(NULL), _M_stringbuf(__str, __m) 589 { this->init(&_M_stringbuf); } 590 591 /** 592 * @brief The destructor does nothing. 593 * 594 * The buffer is deallocated by the stringbuf object, not the 595 * formatting stream. 596 */ ~basic_stringstream()597 ~basic_stringstream() 598 { } 599 600 // Members: 601 /** 602 * @brief Accessing the underlying buffer. 603 * @return The current basic_stringbuf buffer. 604 * 605 * This hides both signatures of std::basic_ios::rdbuf(). 606 */ 607 __stringbuf_type* rdbuf()608 rdbuf() const 609 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 610 611 /** 612 * @brief Copying out the string buffer. 613 * @return @c rdbuf()->str() 614 */ 615 __string_type str()616 str() const 617 { return _M_stringbuf.str(); } 618 619 /** 620 * @brief Setting a new buffer. 621 * @param s The string to use as a new sequence. 622 * 623 * Calls @c rdbuf()->str(s). 624 */ 625 void str(const __string_type & __s)626 str(const __string_type& __s) 627 { _M_stringbuf.str(__s); } 628 }; 629 } // namespace std 630 631 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT 632 # define export 633 #endif 634 #ifdef _GLIBCPP_FULLY_COMPLIANT_HEADERS 635 # include <bits/sstream.tcc> 636 #endif 637 638 #endif 639