std_sstream.h revision 146897
156657Smckusick// String based streams -*- C++ -*- 21541Srgrimes 31541Srgrimes// Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 444344Smckusick// Free Software Foundation, Inc. 51541Srgrimes// 644344Smckusick// This file is part of the GNU ISO C++ Library. This library is free 744344Smckusick// software; you can redistribute it and/or modify it under the 81541Srgrimes// terms of the GNU General Public License as published by the 944344Smckusick// Free Software Foundation; either version 2, or (at your option) 1044344Smckusick// any later version. 1144344Smckusick 1244344Smckusick// This library is distributed in the hope that it will be useful, 1344344Smckusick// but WITHOUT ANY WARRANTY; without even the implied warranty of 1456657Smckusick// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1544344Smckusick// GNU General Public License for more details. 1644344Smckusick 1744344Smckusick// You should have received a copy of the GNU General Public License along 1844344Smckusick// with this library; see the file COPYING. If not, write to the Free 1944344Smckusick// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 2044344Smckusick// USA. 2144344Smckusick 2244344Smckusick// As a special exception, you may use this file as part of a free software 2344344Smckusick// library without restriction. Specifically, if other files instantiate 2444344Smckusick// templates or use macros or inline functions from this file, or you compile 2544344Smckusick// this file and link it with other files to produce an executable, this 2644344Smckusick// file does not by itself cause the resulting executable to be covered by 2744344Smckusick// the GNU General Public License. This exception does not however 2844344Smckusick// invalidate any other reasons why the executable file might be covered by 2944344Smckusick// the GNU General Public License. 3044344Smckusick 3144344Smckusick// 3244344Smckusick// ISO C++ 14882: 27.7 String-based streams 3344344Smckusick// 3444344Smckusick 3544344Smckusick/** @file sstream 3644344Smckusick * This is a Standard C++ Library header. You should @c #include this header 3744344Smckusick * in your programs, rather than any of the "st[dl]_*.h" implementation files. 3844344Smckusick */ 3944344Smckusick 4044344Smckusick#ifndef _GLIBCXX_SSTREAM 4144344Smckusick#define _GLIBCXX_SSTREAM 1 4244344Smckusick 4344344Smckusick#pragma GCC system_header 4444344Smckusick 4544344Smckusick#include <istream> 4644344Smckusick#include <ostream> 4744344Smckusick 4844344Smckusicknamespace std 4944344Smckusick{ 5044344Smckusick // [27.7.1] template class basic_stringbuf 5144344Smckusick /** 5244344Smckusick * @brief The actual work of input and output (for std::string). 5344344Smckusick * 5444344Smckusick * This class associates either or both of its input and output sequences 5544344Smckusick * with a sequence of characters, which can be initialized from, or made 5644344Smckusick * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 5744344Smckusick * 5844344Smckusick * For this class, open modes (of type @c ios_base::openmode) have 5944344Smckusick * @c in set if the input sequence can be read, and @c out set if the 6044344Smckusick * output sequence can be written. 6144344Smckusick */ 6244344Smckusick template<typename _CharT, typename _Traits, typename _Alloc> 6344344Smckusick class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 6444344Smckusick { 6544344Smckusick public: 6644344Smckusick // Types: 6744344Smckusick typedef _CharT char_type; 6844344Smckusick typedef _Traits traits_type; 6944344Smckusick // _GLIBCXX_RESOLVE_LIB_DEFECTS 7044344Smckusick // 251. basic_stringbuf missing allocator_type 7144344Smckusick typedef _Alloc allocator_type; 7244344Smckusick typedef typename traits_type::int_type int_type; 7344344Smckusick typedef typename traits_type::pos_type pos_type; 7444344Smckusick typedef typename traits_type::off_type off_type; 7544344Smckusick 7644344Smckusick //@{ 7744344Smckusick /** 7844344Smckusick * @if maint 7944344Smckusick * @doctodo 8056657Smckusick * @endif 8156657Smckusick */ 8244344Smckusick typedef basic_streambuf<char_type, traits_type> __streambuf_type; 8344344Smckusick typedef basic_string<char_type, _Traits, _Alloc> __string_type; 8444344Smckusick typedef typename __string_type::size_type __size_type; 8544344Smckusick //@} 8644344Smckusick 8744344Smckusick protected: 8844344Smckusick /** 8944344Smckusick * @if maint 9044344Smckusick * Place to stash in || out || in | out settings for current stringbuf. 9144344Smckusick * @endif 9244344Smckusick */ 9344344Smckusick ios_base::openmode _M_mode; 9444344Smckusick 9544344Smckusick // Data Members: 9644344Smckusick /** 9744344Smckusick * @if maint 9844344Smckusick * @doctodo 9944344Smckusick * @endif 10044344Smckusick */ 10144344Smckusick __string_type _M_string; 10244344Smckusick 10344344Smckusick public: 10444344Smckusick // Constructors: 10544344Smckusick /** 10644344Smckusick * @brief Starts with an empty string buffer. 10744344Smckusick * @param mode Whether the buffer can read, or write, or both. 10844344Smckusick * 10944344Smckusick * The default constructor initializes the parent class using its 11044344Smckusick * own default ctor. 11144344Smckusick */ 11244344Smckusick explicit 113 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 114 : __streambuf_type(), _M_mode(__mode), _M_string() 115 { } 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 if (this->pptr()) 144 { 145 // The current egptr() may not be the actual string end. 146 if (this->pptr() > this->egptr()) 147 return __string_type(this->pbase(), this->pptr()); 148 else 149 return __string_type(this->pbase(), this->egptr()); 150 } 151 else 152 return _M_string; 153 } 154 155 /** 156 * @brief Setting a new buffer. 157 * @param s The string to use as a new sequence. 158 * 159 * Deallocates any previous stored sequence, then copies @a s to 160 * use as a new one. 161 */ 162 void 163 str(const __string_type& __s) 164 { 165 // Cannot use _M_string = __s, since v3 strings are COW. 166 _M_string.assign(__s.data(), __s.size()); 167 _M_stringbuf_init(this->_M_mode); 168 } 169 170 protected: 171 // Common initialization code goes here. 172 /** 173 * @if maint 174 * @doctodo 175 * @endif 176 */ 177 void 178 _M_stringbuf_init(ios_base::openmode __mode) 179 { 180 this->_M_mode = __mode; 181 182 __size_type __len = 0; 183 if (this->_M_mode & (ios_base::ate | ios_base::app)) 184 __len = _M_string.size(); 185 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 186 } 187 188 // [documentation is inherited] 189 virtual int_type 190 underflow(); 191 192 // [documentation is inherited] 193 virtual int_type 194 pbackfail(int_type __c = traits_type::eof()); 195 196 // [documentation is inherited] 197 virtual int_type 198 overflow(int_type __c = traits_type::eof()); 199 200 /** 201 * @brief Manipulates the buffer. 202 * @param s Pointer to a buffer area. 203 * @param n Size of @a s. 204 * @return @c this 205 * 206 * If no buffer has already been created, and both @a s and @a n are 207 * non-zero, then @c s is used as a buffer; see 208 * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 209 * for more. 210 */ 211 virtual __streambuf_type* 212 setbuf(char_type* __s, streamsize __n) 213 { 214 if (__s && __n >= 0) 215 { 216 // This is implementation-defined behavior, and assumes 217 // that an external char_type array of length __n exists 218 // and has been pre-allocated. If this is not the case, 219 // things will quickly blow up. 220 221 // Step 1: Destroy the current internal array. 222 _M_string = __string_type(__s, __n); 223 224 // Step 2: Use the external array. 225 _M_sync(__s, 0, 0); 226 } 227 return this; 228 } 229 230 // [documentation is inherited] 231 virtual pos_type 232 seekoff(off_type __off, ios_base::seekdir __way, 233 ios_base::openmode __mode = ios_base::in | ios_base::out); 234 235 // [documentation is inherited] 236 virtual pos_type 237 seekpos(pos_type __sp, 238 ios_base::openmode __mode = ios_base::in | ios_base::out); 239 240 // Internal function for correctly updating the internal buffer 241 // for a particular _M_string, due to initialization or 242 // re-sizing of an existing _M_string. 243 // Assumes: contents of _M_string and internal buffer match exactly. 244 // __i == _M_in_cur - _M_in_beg 245 // __o == _M_out_cur - _M_out_beg 246 /** 247 * @if maint 248 * @doctodo 249 * @endif 250 */ 251 void 252 _M_sync(char_type* __base, __size_type __i, __size_type __o) 253 { 254 const bool __testin = this->_M_mode & ios_base::in; 255 const bool __testout = this->_M_mode & ios_base::out; 256 const __size_type __len = _M_string.size(); 257 258 if (__testin) 259 this->setg(__base, __base + __i, __base + __len); 260 if (__testout) 261 { 262 this->setp(__base, __base + _M_string.capacity()); 263 this->pbump(__o); 264 // We need a pointer to the string end anyway, even when 265 // !__testin: in that case, however, for the correct 266 // functioning of the streambuf inlines all the get area 267 // pointers must be identical. 268 if (!__testin) 269 this->setg(__base + __len, __base + __len, __base + __len); 270 } 271 } 272 273 // Internal function for correctly updating egptr() to the actual 274 // string end. 275 void 276 _M_update_egptr() 277 { 278 const bool __testin = this->_M_mode & ios_base::in; 279 280 if (this->pptr() && this->pptr() > this->egptr()) 281 if (__testin) 282 this->setg(this->eback(), this->gptr(), this->pptr()); 283 else 284 this->setg(this->pptr(), this->pptr(), this->pptr()); 285 } 286 }; 287 288 289 // [27.7.2] Template class basic_istringstream 290 /** 291 * @brief Controlling input for std::string. 292 * 293 * This class supports reading from objects of type std::basic_string, 294 * using the inherited functions from std::basic_istream. To control 295 * the associated sequence, an instance of std::basic_stringbuf is used, 296 * which this page refers to as @c sb. 297 */ 298 template<typename _CharT, typename _Traits, typename _Alloc> 299 class basic_istringstream : public basic_istream<_CharT, _Traits> 300 { 301 public: 302 // Types: 303 typedef _CharT char_type; 304 typedef _Traits traits_type; 305 // _GLIBCXX_RESOLVE_LIB_DEFECTS 306 // 251. basic_stringbuf missing allocator_type 307 typedef _Alloc allocator_type; 308 typedef typename traits_type::int_type int_type; 309 typedef typename traits_type::pos_type pos_type; 310 typedef typename traits_type::off_type off_type; 311 312 // Non-standard types: 313 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 314 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 315 typedef basic_istream<char_type, traits_type> __istream_type; 316 317 private: 318 /** 319 * @if maint 320 * @doctodo 321 * @endif 322 */ 323 __stringbuf_type _M_stringbuf; 324 325 public: 326 // Constructors: 327 /** 328 * @brief Default constructor starts with an empty string buffer. 329 * @param mode Whether the buffer can read, or write, or both. 330 * 331 * @c ios_base::in is automatically included in @a mode. 332 * 333 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 334 * class initializer. Does not allocate any buffer. 335 * 336 * @if maint 337 * That's a lie. We initialize the base class with NULL, because the 338 * string class does its own memory management. 339 * @endif 340 */ 341 explicit 342 basic_istringstream(ios_base::openmode __mode = ios_base::in) 343 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 344 { this->init(&_M_stringbuf); } 345 346 /** 347 * @brief Starts with an existing string buffer. 348 * @param str A string to copy as a starting buffer. 349 * @param mode Whether the buffer can read, or write, or both. 350 * 351 * @c ios_base::in is automatically included in @a mode. 352 * 353 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 354 * to the base class initializer. 355 * 356 * @if maint 357 * That's a lie. We initialize the base class with NULL, because the 358 * string class does its own memory management. 359 * @endif 360 */ 361 explicit 362 basic_istringstream(const __string_type& __str, 363 ios_base::openmode __mode = ios_base::in) 364 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 365 { this->init(&_M_stringbuf); } 366 367 /** 368 * @brief The destructor does nothing. 369 * 370 * The buffer is deallocated by the stringbuf object, not the 371 * formatting stream. 372 */ 373 ~basic_istringstream() 374 { } 375 376 // Members: 377 /** 378 * @brief Accessing the underlying buffer. 379 * @return The current basic_stringbuf buffer. 380 * 381 * This hides both signatures of std::basic_ios::rdbuf(). 382 */ 383 __stringbuf_type* 384 rdbuf() const 385 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 386 387 /** 388 * @brief Copying out the string buffer. 389 * @return @c rdbuf()->str() 390 */ 391 __string_type 392 str() const 393 { return _M_stringbuf.str(); } 394 395 /** 396 * @brief Setting a new buffer. 397 * @param s The string to use as a new sequence. 398 * 399 * Calls @c rdbuf()->str(s). 400 */ 401 void 402 str(const __string_type& __s) 403 { _M_stringbuf.str(__s); } 404 }; 405 406 407 // [27.7.3] Template class basic_ostringstream 408 /** 409 * @brief Controlling output for std::string. 410 * 411 * This class supports writing to objects of type std::basic_string, 412 * using the inherited functions from std::basic_ostream. To control 413 * the associated sequence, an instance of std::basic_stringbuf is used, 414 * which this page refers to as @c sb. 415 */ 416 template <typename _CharT, typename _Traits, typename _Alloc> 417 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 418 { 419 public: 420 // Types: 421 typedef _CharT char_type; 422 typedef _Traits traits_type; 423 // _GLIBCXX_RESOLVE_LIB_DEFECTS 424 // 251. basic_stringbuf missing allocator_type 425 typedef _Alloc allocator_type; 426 typedef typename traits_type::int_type int_type; 427 typedef typename traits_type::pos_type pos_type; 428 typedef typename traits_type::off_type off_type; 429 430 // Non-standard types: 431 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 432 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 433 typedef basic_ostream<char_type, traits_type> __ostream_type; 434 435 private: 436 /** 437 * @if maint 438 * @doctodo 439 * @endif 440 */ 441 __stringbuf_type _M_stringbuf; 442 443 public: 444 // Constructors/destructor: 445 /** 446 * @brief Default constructor starts with an empty string buffer. 447 * @param mode Whether the buffer can read, or write, or both. 448 * 449 * @c ios_base::out is automatically included in @a mode. 450 * 451 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 452 * class initializer. Does not allocate any buffer. 453 * 454 * @if maint 455 * That's a lie. We initialize the base class with NULL, because the 456 * string class does its own memory management. 457 * @endif 458 */ 459 explicit 460 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 461 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 462 { this->init(&_M_stringbuf); } 463 464 /** 465 * @brief Starts with an existing string buffer. 466 * @param str A string to copy as a starting buffer. 467 * @param mode Whether the buffer can read, or write, or both. 468 * 469 * @c ios_base::out is automatically included in @a mode. 470 * 471 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 472 * to the base class initializer. 473 * 474 * @if maint 475 * That's a lie. We initialize the base class with NULL, because the 476 * string class does its own memory management. 477 * @endif 478 */ 479 explicit 480 basic_ostringstream(const __string_type& __str, 481 ios_base::openmode __mode = ios_base::out) 482 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 483 { this->init(&_M_stringbuf); } 484 485 /** 486 * @brief The destructor does nothing. 487 * 488 * The buffer is deallocated by the stringbuf object, not the 489 * formatting stream. 490 */ 491 ~basic_ostringstream() 492 { } 493 494 // Members: 495 /** 496 * @brief Accessing the underlying buffer. 497 * @return The current basic_stringbuf buffer. 498 * 499 * This hides both signatures of std::basic_ios::rdbuf(). 500 */ 501 __stringbuf_type* 502 rdbuf() const 503 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 504 505 /** 506 * @brief Copying out the string buffer. 507 * @return @c rdbuf()->str() 508 */ 509 __string_type 510 str() const 511 { return _M_stringbuf.str(); } 512 513 /** 514 * @brief Setting a new buffer. 515 * @param s The string to use as a new sequence. 516 * 517 * Calls @c rdbuf()->str(s). 518 */ 519 void 520 str(const __string_type& __s) 521 { _M_stringbuf.str(__s); } 522 }; 523 524 525 // [27.7.4] Template class basic_stringstream 526 /** 527 * @brief Controlling input and output for std::string. 528 * 529 * This class supports reading from and writing to objects of type 530 * std::basic_string, using the inherited functions from 531 * std::basic_iostream. To control the associated sequence, an instance 532 * of std::basic_stringbuf is used, which this page refers to as @c sb. 533 */ 534 template <typename _CharT, typename _Traits, typename _Alloc> 535 class basic_stringstream : public basic_iostream<_CharT, _Traits> 536 { 537 public: 538 // Types: 539 typedef _CharT char_type; 540 typedef _Traits traits_type; 541 // _GLIBCXX_RESOLVE_LIB_DEFECTS 542 // 251. basic_stringbuf missing allocator_type 543 typedef _Alloc allocator_type; 544 typedef typename traits_type::int_type int_type; 545 typedef typename traits_type::pos_type pos_type; 546 typedef typename traits_type::off_type off_type; 547 548 // Non-standard Types: 549 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 550 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 551 typedef basic_iostream<char_type, traits_type> __iostream_type; 552 553 private: 554 /** 555 * @if maint 556 * @doctodo 557 * @endif 558 */ 559 __stringbuf_type _M_stringbuf; 560 561 public: 562 // Constructors/destructors 563 /** 564 * @brief Default constructor starts with an empty string buffer. 565 * @param mode Whether the buffer can read, or write, or both. 566 * 567 * Initializes @c sb using @c mode, and passes @c &sb to the base 568 * class initializer. Does not allocate any buffer. 569 * 570 * @if maint 571 * That's a lie. We initialize the base class with NULL, because the 572 * string class does its own memory management. 573 * @endif 574 */ 575 explicit 576 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 577 : __iostream_type(), _M_stringbuf(__m) 578 { this->init(&_M_stringbuf); } 579 580 /** 581 * @brief Starts with an existing string buffer. 582 * @param str A string to copy as a starting buffer. 583 * @param mode Whether the buffer can read, or write, or both. 584 * 585 * Initializes @c sb using @a str and @c mode, and passes @c &sb 586 * to the base class initializer. 587 * 588 * @if maint 589 * That's a lie. We initialize the base class with NULL, because the 590 * string class does its own memory management. 591 * @endif 592 */ 593 explicit 594 basic_stringstream(const __string_type& __str, 595 ios_base::openmode __m = ios_base::out | ios_base::in) 596 : __iostream_type(), _M_stringbuf(__str, __m) 597 { this->init(&_M_stringbuf); } 598 599 /** 600 * @brief The destructor does nothing. 601 * 602 * The buffer is deallocated by the stringbuf object, not the 603 * formatting stream. 604 */ 605 ~basic_stringstream() 606 { } 607 608 // Members: 609 /** 610 * @brief Accessing the underlying buffer. 611 * @return The current basic_stringbuf buffer. 612 * 613 * This hides both signatures of std::basic_ios::rdbuf(). 614 */ 615 __stringbuf_type* 616 rdbuf() const 617 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 618 619 /** 620 * @brief Copying out the string buffer. 621 * @return @c rdbuf()->str() 622 */ 623 __string_type 624 str() const 625 { return _M_stringbuf.str(); } 626 627 /** 628 * @brief Setting a new buffer. 629 * @param s The string to use as a new sequence. 630 * 631 * Calls @c rdbuf()->str(s). 632 */ 633 void 634 str(const __string_type& __s) 635 { _M_stringbuf.str(__s); } 636 }; 637} // namespace std 638 639#ifndef _GLIBCXX_EXPORT_TEMPLATE 640# include <bits/sstream.tcc> 641#endif 642 643#endif /* _GLIBCXX_SSTREAM */ 644