1 // String based streams -*- C++ -*- 2 3 // Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 2, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // You should have received a copy of the GNU General Public License along 18 // with this library; see the file COPYING. If not, write to the Free 19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20 // USA. 21 22 // As a special exception, you may use this file as part of a free software 23 // library without restriction. Specifically, if other files instantiate 24 // templates or use macros or inline functions from this file, or you compile 25 // this file and link it with other files to produce an executable, this 26 // file does not by itself cause the resulting executable to be covered by 27 // the GNU General Public License. This exception does not however 28 // invalidate any other reasons why the executable file might be covered by 29 // the GNU General Public License. 30 31 // 32 // ISO C++ 14882: 27.7 String-based streams 33 // 34 35 /** @file sstream 36 * This is a Standard C++ Library header. You should @c #include this header 37 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 38 */ 39 40 #ifndef _GLIBCXX_SSTREAM 41 #define _GLIBCXX_SSTREAM 1 42 43 #pragma GCC system_header 44 45 #include <istream> 46 #include <ostream> 47 48 namespace std 49 { 50 // [27.7.1] template class basic_stringbuf 51 /** 52 * @brief The actual work of input and output (for std::string). 53 * 54 * This class associates either or both of its input and output sequences 55 * with a sequence of characters, which can be initialized from, or made 56 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 57 * 58 * For this class, open modes (of type @c ios_base::openmode) have 59 * @c in set if the input sequence can be read, and @c out set if the 60 * output sequence can be written. 61 */ 62 template<typename _CharT, typename _Traits, typename _Alloc> 63 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 64 { 65 public: 66 // Types: 67 typedef _CharT char_type; 68 typedef _Traits traits_type; 69 // _GLIBCXX_RESOLVE_LIB_DEFECTS 70 // 251. basic_stringbuf missing allocator_type 71 typedef _Alloc allocator_type; 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 /** 89 * @if maint 90 * Place to stash in || out || in | out settings for current stringbuf. 91 * @endif 92 */ 93 ios_base::openmode _M_mode; 94 95 // Data Members: 96 /** 97 * @if maint 98 * @doctodo 99 * @endif 100 */ 101 __string_type _M_string; 102 103 public: 104 // Constructors: 105 /** 106 * @brief Starts with an empty string buffer. 107 * @param mode Whether the buffer can read, or write, or both. 108 * 109 * The default constructor initializes the parent class using its 110 * own default ctor. 111 */ 112 explicit 113 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 114 : __streambuf_type(), _M_mode(), _M_string() 115 { _M_stringbuf_init(__mode); } 116 117 /** 118 * @brief Starts with an existing string buffer. 119 * @param str A string to copy as a starting buffer. 120 * @param mode Whether the buffer can read, or write, or both. 121 * 122 * This constructor initializes the parent class using its 123 * own default ctor. 124 */ 125 explicit 126 basic_stringbuf(const __string_type& __str, 127 ios_base::openmode __mode = ios_base::in | ios_base::out) 128 : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) 129 { _M_stringbuf_init(__mode); } 130 131 // Get and set: 132 /** 133 * @brief Copying out the string buffer. 134 * @return A copy of one of the underlying sequences. 135 * 136 * "If the buffer is only created in input mode, the underlying 137 * character sequence is equal to the input sequence; otherwise, it 138 * is equal to the output sequence." [27.7.1.2]/1 139 */ 140 __string_type 141 str() const 142 { 143 const bool __testout = this->_M_mode & ios_base::out; 144 if (__testout) 145 { 146 // The current egptr() may not be the actual string end. 147 if (this->pptr() > this->egptr()) 148 return __string_type(this->pbase(), this->pptr()); 149 else 150 return __string_type(this->pbase(), this->egptr()); 151 } 152 else 153 return _M_string; 154 } 155 156 /** 157 * @brief Setting a new buffer. 158 * @param s The string to use as a new sequence. 159 * 160 * Deallocates any previous stored sequence, then copies @a s to 161 * use as a new one. 162 */ 163 void 164 str(const __string_type& __s) 165 { 166 // Cannot use _M_string = __s, since v3 strings are COW. 167 _M_string.assign(__s.data(), __s.size()); 168 _M_stringbuf_init(this->_M_mode); 169 } 170 171 protected: 172 // Common initialization code for both ctors goes here. 173 /** 174 * @if maint 175 * @doctodo 176 * @endif 177 */ 178 void 179 _M_stringbuf_init(ios_base::openmode __mode) 180 { 181 this->_M_mode = __mode; 182 183 __size_type __len = 0; 184 if (this->_M_mode & (ios_base::ate | ios_base::app)) 185 __len = _M_string.size(); 186 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 187 } 188 189 // [documentation is inherited] 190 virtual int_type 191 underflow(); 192 193 // [documentation is inherited] 194 virtual int_type 195 pbackfail(int_type __c = traits_type::eof()); 196 197 // [documentation is inherited] 198 virtual int_type 199 overflow(int_type __c = traits_type::eof()); 200 201 /** 202 * @brief Manipulates the buffer. 203 * @param s Pointer to a buffer area. 204 * @param n Size of @a s. 205 * @return @c this 206 * 207 * If no buffer has already been created, and both @a s and @a n are 208 * non-zero, then @c s is used as a buffer; see 209 * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 210 * for more. 211 */ 212 virtual __streambuf_type* 213 setbuf(char_type* __s, streamsize __n) 214 { 215 if (__s && __n >= 0) 216 { 217 // This is implementation-defined behavior, and assumes 218 // that an external char_type array of length __n exists 219 // and has been pre-allocated. If this is not the case, 220 // things will quickly blow up. 221 222 // Step 1: Destroy the current internal array. 223 _M_string = __string_type(__s, __n); 224 225 // Step 2: Use the external array. 226 _M_sync(__s, 0, 0); 227 } 228 return this; 229 } 230 231 // [documentation is inherited] 232 virtual pos_type 233 seekoff(off_type __off, ios_base::seekdir __way, 234 ios_base::openmode __mode = ios_base::in | ios_base::out); 235 236 // [documentation is inherited] 237 virtual pos_type 238 seekpos(pos_type __sp, 239 ios_base::openmode __mode = ios_base::in | ios_base::out); 240 241 // Internal function for correctly updating the internal buffer 242 // for a particular _M_string, due to initialization or 243 // re-sizing of an existing _M_string. 244 // Assumes: contents of _M_string and internal buffer match exactly. 245 // __i == _M_in_cur - _M_in_beg 246 // __o == _M_out_cur - _M_out_beg 247 /** 248 * @if maint 249 * @doctodo 250 * @endif 251 */ 252 void 253 _M_sync(char_type* __base, __size_type __i, __size_type __o) 254 { 255 const bool __testin = this->_M_mode & ios_base::in; 256 const bool __testout = this->_M_mode & ios_base::out; 257 const __size_type __len = _M_string.size(); 258 259 if (__testin) 260 this->setg(__base, __base + __i, __base + __len); 261 if (__testout) 262 { 263 this->setp(__base, __base + _M_string.capacity()); 264 this->pbump(__o); 265 // We need a pointer to the string end anyway, even when 266 // !__testin: in that case, however, for the correct 267 // functioning of the streambuf inlines all the get area 268 // pointers must be identical. 269 if (!__testin) 270 this->setg(__base + __len, __base + __len, __base + __len); 271 } 272 } 273 274 // Internal function for correctly updating egptr() to the actual 275 // string end. 276 void 277 _M_update_egptr() 278 { 279 const bool __testin = this->_M_mode & ios_base::in; 280 const bool __testout = this->_M_mode & ios_base::out; 281 282 if (__testout && this->pptr() > this->egptr()) 283 if (__testin) 284 this->setg(this->eback(), this->gptr(), this->pptr()); 285 else 286 this->setg(this->pptr(), this->pptr(), this->pptr()); 287 } 288 }; 289 290 291 // [27.7.2] Template class basic_istringstream 292 /** 293 * @brief Controlling input for std::string. 294 * 295 * This class supports reading from objects of type std::basic_string, 296 * using the inherited functions from std::basic_istream. To control 297 * the associated sequence, an instance of std::basic_stringbuf is used, 298 * which this page refers to as @c sb. 299 */ 300 template<typename _CharT, typename _Traits, typename _Alloc> 301 class basic_istringstream : public basic_istream<_CharT, _Traits> 302 { 303 public: 304 // Types: 305 typedef _CharT char_type; 306 typedef _Traits traits_type; 307 // _GLIBCXX_RESOLVE_LIB_DEFECTS 308 // 251. basic_stringbuf missing allocator_type 309 typedef _Alloc allocator_type; 310 typedef typename traits_type::int_type int_type; 311 typedef typename traits_type::pos_type pos_type; 312 typedef typename traits_type::off_type off_type; 313 314 // Non-standard types: 315 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 316 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 317 typedef basic_istream<char_type, traits_type> __istream_type; 318 319 private: 320 /** 321 * @if maint 322 * @doctodo 323 * @endif 324 */ 325 __stringbuf_type _M_stringbuf; 326 327 public: 328 // Constructors: 329 /** 330 * @brief Default constructor starts with an empty string buffer. 331 * @param mode Whether the buffer can read, or write, or both. 332 * 333 * @c ios_base::in is automatically included in @a mode. 334 * 335 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 336 * class initializer. Does not allocate any buffer. 337 * 338 * @if maint 339 * That's a lie. We initialize the base class with NULL, because the 340 * string class does its own memory management. 341 * @endif 342 */ 343 explicit 344 basic_istringstream(ios_base::openmode __mode = ios_base::in) 345 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 346 { this->init(&_M_stringbuf); } 347 348 /** 349 * @brief Starts with an existing string buffer. 350 * @param str A string to copy as a starting buffer. 351 * @param mode Whether the buffer can read, or write, or both. 352 * 353 * @c ios_base::in is automatically included in @a mode. 354 * 355 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 356 * to the base class initializer. 357 * 358 * @if maint 359 * That's a lie. We initialize the base class with NULL, because the 360 * string class does its own memory management. 361 * @endif 362 */ 363 explicit 364 basic_istringstream(const __string_type& __str, 365 ios_base::openmode __mode = ios_base::in) 366 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 367 { this->init(&_M_stringbuf); } 368 369 /** 370 * @brief The destructor does nothing. 371 * 372 * The buffer is deallocated by the stringbuf object, not the 373 * formatting stream. 374 */ 375 ~basic_istringstream() 376 { } 377 378 // Members: 379 /** 380 * @brief Accessing the underlying buffer. 381 * @return The current basic_stringbuf buffer. 382 * 383 * This hides both signatures of std::basic_ios::rdbuf(). 384 */ 385 __stringbuf_type* 386 rdbuf() const 387 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 388 389 /** 390 * @brief Copying out the string buffer. 391 * @return @c rdbuf()->str() 392 */ 393 __string_type 394 str() const 395 { return _M_stringbuf.str(); } 396 397 /** 398 * @brief Setting a new buffer. 399 * @param s The string to use as a new sequence. 400 * 401 * Calls @c rdbuf()->str(s). 402 */ 403 void 404 str(const __string_type& __s) 405 { _M_stringbuf.str(__s); } 406 }; 407 408 409 // [27.7.3] Template class basic_ostringstream 410 /** 411 * @brief Controlling output for std::string. 412 * 413 * This class supports writing to objects of type std::basic_string, 414 * using the inherited functions from std::basic_ostream. To control 415 * the associated sequence, an instance of std::basic_stringbuf is used, 416 * which this page refers to as @c sb. 417 */ 418 template <typename _CharT, typename _Traits, typename _Alloc> 419 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 420 { 421 public: 422 // Types: 423 typedef _CharT char_type; 424 typedef _Traits traits_type; 425 // _GLIBCXX_RESOLVE_LIB_DEFECTS 426 // 251. basic_stringbuf missing allocator_type 427 typedef _Alloc allocator_type; 428 typedef typename traits_type::int_type int_type; 429 typedef typename traits_type::pos_type pos_type; 430 typedef typename traits_type::off_type off_type; 431 432 // Non-standard types: 433 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 434 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 435 typedef basic_ostream<char_type, traits_type> __ostream_type; 436 437 private: 438 /** 439 * @if maint 440 * @doctodo 441 * @endif 442 */ 443 __stringbuf_type _M_stringbuf; 444 445 public: 446 // Constructors/destructor: 447 /** 448 * @brief Default constructor starts with an empty string buffer. 449 * @param mode Whether the buffer can read, or write, or both. 450 * 451 * @c ios_base::out is automatically included in @a mode. 452 * 453 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 454 * class initializer. Does not allocate any buffer. 455 * 456 * @if maint 457 * That's a lie. We initialize the base class with NULL, because the 458 * string class does its own memory management. 459 * @endif 460 */ 461 explicit 462 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 463 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 464 { this->init(&_M_stringbuf); } 465 466 /** 467 * @brief Starts with an existing string buffer. 468 * @param str A string to copy as a starting buffer. 469 * @param mode Whether the buffer can read, or write, or both. 470 * 471 * @c ios_base::out is automatically included in @a mode. 472 * 473 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 474 * to the base class initializer. 475 * 476 * @if maint 477 * That's a lie. We initialize the base class with NULL, because the 478 * string class does its own memory management. 479 * @endif 480 */ 481 explicit 482 basic_ostringstream(const __string_type& __str, 483 ios_base::openmode __mode = ios_base::out) 484 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 485 { this->init(&_M_stringbuf); } 486 487 /** 488 * @brief The destructor does nothing. 489 * 490 * The buffer is deallocated by the stringbuf object, not the 491 * formatting stream. 492 */ 493 ~basic_ostringstream() 494 { } 495 496 // Members: 497 /** 498 * @brief Accessing the underlying buffer. 499 * @return The current basic_stringbuf buffer. 500 * 501 * This hides both signatures of std::basic_ios::rdbuf(). 502 */ 503 __stringbuf_type* 504 rdbuf() const 505 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 506 507 /** 508 * @brief Copying out the string buffer. 509 * @return @c rdbuf()->str() 510 */ 511 __string_type 512 str() const 513 { return _M_stringbuf.str(); } 514 515 /** 516 * @brief Setting a new buffer. 517 * @param s The string to use as a new sequence. 518 * 519 * Calls @c rdbuf()->str(s). 520 */ 521 void 522 str(const __string_type& __s) 523 { _M_stringbuf.str(__s); } 524 }; 525 526 527 // [27.7.4] Template class basic_stringstream 528 /** 529 * @brief Controlling input and output for std::string. 530 * 531 * This class supports reading from and writing to objects of type 532 * std::basic_string, using the inherited functions from 533 * std::basic_iostream. To control the associated sequence, an instance 534 * of std::basic_stringbuf is used, which this page refers to as @c sb. 535 */ 536 template <typename _CharT, typename _Traits, typename _Alloc> 537 class basic_stringstream : public basic_iostream<_CharT, _Traits> 538 { 539 public: 540 // Types: 541 typedef _CharT char_type; 542 typedef _Traits traits_type; 543 // _GLIBCXX_RESOLVE_LIB_DEFECTS 544 // 251. basic_stringbuf missing allocator_type 545 typedef _Alloc allocator_type; 546 typedef typename traits_type::int_type int_type; 547 typedef typename traits_type::pos_type pos_type; 548 typedef typename traits_type::off_type off_type; 549 550 // Non-standard Types: 551 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 552 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 553 typedef basic_iostream<char_type, traits_type> __iostream_type; 554 555 private: 556 /** 557 * @if maint 558 * @doctodo 559 * @endif 560 */ 561 __stringbuf_type _M_stringbuf; 562 563 public: 564 // Constructors/destructors 565 /** 566 * @brief Default constructor starts with an empty string buffer. 567 * @param mode Whether the buffer can read, or write, or both. 568 * 569 * Initializes @c sb using @c mode, and passes @c &sb to the base 570 * class initializer. Does not allocate any buffer. 571 * 572 * @if maint 573 * That's a lie. We initialize the base class with NULL, because the 574 * string class does its own memory management. 575 * @endif 576 */ 577 explicit 578 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 579 : __iostream_type(), _M_stringbuf(__m) 580 { this->init(&_M_stringbuf); } 581 582 /** 583 * @brief Starts with an existing string buffer. 584 * @param str A string to copy as a starting buffer. 585 * @param mode Whether the buffer can read, or write, or both. 586 * 587 * Initializes @c sb using @a str and @c mode, and passes @c &sb 588 * to the base class initializer. 589 * 590 * @if maint 591 * That's a lie. We initialize the base class with NULL, because the 592 * string class does its own memory management. 593 * @endif 594 */ 595 explicit 596 basic_stringstream(const __string_type& __str, 597 ios_base::openmode __m = ios_base::out | ios_base::in) 598 : __iostream_type(), _M_stringbuf(__str, __m) 599 { this->init(&_M_stringbuf); } 600 601 /** 602 * @brief The destructor does nothing. 603 * 604 * The buffer is deallocated by the stringbuf object, not the 605 * formatting stream. 606 */ 607 ~basic_stringstream() 608 { } 609 610 // Members: 611 /** 612 * @brief Accessing the underlying buffer. 613 * @return The current basic_stringbuf buffer. 614 * 615 * This hides both signatures of std::basic_ios::rdbuf(). 616 */ 617 __stringbuf_type* 618 rdbuf() const 619 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 620 621 /** 622 * @brief Copying out the string buffer. 623 * @return @c rdbuf()->str() 624 */ 625 __string_type 626 str() const 627 { return _M_stringbuf.str(); } 628 629 /** 630 * @brief Setting a new buffer. 631 * @param s The string to use as a new sequence. 632 * 633 * Calls @c rdbuf()->str(s). 634 */ 635 void 636 str(const __string_type& __s) 637 { _M_stringbuf.str(__s); } 638 }; 639 } // namespace std 640 641 #ifndef _GLIBCXX_EXPORT_TEMPLATE 642 # include <bits/sstream.tcc> 643 #endif 644 645 #endif /* _GLIBCXX_SSTREAM */ 646