1 // String based streams -*- C++ -*- 2 3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /** @file sstream 32 * This is a Standard C++ Library header. 33 */ 34 35 // 36 // ISO C++ 14882: 27.7 String-based streams 37 // 38 39 #ifndef _GLIBCXX_SSTREAM 40 #define _GLIBCXX_SSTREAM 1 41 42 #pragma GCC system_header 43 44 #include <istream> 45 #include <ostream> 46 47 _GLIBCXX_BEGIN_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 // _GLIBCXX_RESOLVE_LIB_DEFECTS 69 // 251. basic_stringbuf missing allocator_type 70 typedef _Alloc allocator_type; 71 typedef typename traits_type::int_type int_type; 72 typedef typename traits_type::pos_type pos_type; 73 typedef typename traits_type::off_type off_type; 74 75 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 76 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 77 typedef typename __string_type::size_type __size_type; 78 79 protected: 80 /** 81 * @if maint 82 * Place to stash in || out || in | out settings for current stringbuf. 83 * @endif 84 */ 85 ios_base::openmode _M_mode; 86 87 // Data Members: 88 __string_type _M_string; 89 90 public: 91 // Constructors: 92 /** 93 * @brief Starts with an empty string buffer. 94 * @param mode Whether the buffer can read, or write, or both. 95 * 96 * The default constructor initializes the parent class using its 97 * own default ctor. 98 */ 99 explicit 100 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 101 : __streambuf_type(), _M_mode(__mode), _M_string() 102 { } 103 104 /** 105 * @brief Starts with an existing string buffer. 106 * @param str A string to copy as a starting buffer. 107 * @param mode Whether the buffer can read, or write, or both. 108 * 109 * This constructor initializes the parent class using its 110 * own default ctor. 111 */ 112 explicit 113 basic_stringbuf(const __string_type& __str, 114 ios_base::openmode __mode = ios_base::in | ios_base::out) 115 : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) 116 { _M_stringbuf_init(__mode); } 117 118 // Get and set: 119 /** 120 * @brief Copying out the string buffer. 121 * @return A copy of one of the underlying sequences. 122 * 123 * "If the buffer is only created in input mode, the underlying 124 * character sequence is equal to the input sequence; otherwise, it 125 * is equal to the output sequence." [27.7.1.2]/1 126 */ 127 __string_type 128 str() const 129 { 130 __string_type __ret; 131 if (this->pptr()) 132 { 133 // The current egptr() may not be the actual string end. 134 if (this->pptr() > this->egptr()) 135 __ret = __string_type(this->pbase(), this->pptr()); 136 else 137 __ret = __string_type(this->pbase(), this->egptr()); 138 } 139 else 140 __ret = _M_string; 141 return __ret; 142 } 143 144 /** 145 * @brief Setting a new buffer. 146 * @param s The string to use as a new sequence. 147 * 148 * Deallocates any previous stored sequence, then copies @a s to 149 * use as a new one. 150 */ 151 void 152 str(const __string_type& __s) 153 { 154 // Cannot use _M_string = __s, since v3 strings are COW. 155 _M_string.assign(__s.data(), __s.size()); 156 _M_stringbuf_init(_M_mode); 157 } 158 159 protected: 160 // Common initialization code goes here. 161 void 162 _M_stringbuf_init(ios_base::openmode __mode) 163 { 164 _M_mode = __mode; 165 __size_type __len = 0; 166 if (_M_mode & (ios_base::ate | ios_base::app)) 167 __len = _M_string.size(); 168 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 169 } 170 171 virtual streamsize 172 showmanyc() 173 { 174 streamsize __ret = -1; 175 if (_M_mode & ios_base::in) 176 { 177 _M_update_egptr(); 178 __ret = this->egptr() - this->gptr(); 179 } 180 return __ret; 181 } 182 183 virtual int_type 184 underflow(); 185 186 virtual int_type 187 pbackfail(int_type __c = traits_type::eof()); 188 189 virtual int_type 190 overflow(int_type __c = traits_type::eof()); 191 192 /** 193 * @brief Manipulates the buffer. 194 * @param s Pointer to a buffer area. 195 * @param n Size of @a s. 196 * @return @c this 197 * 198 * If no buffer has already been created, and both @a s and @a n are 199 * non-zero, then @c s is used as a buffer; see 200 * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 201 * for more. 202 */ 203 virtual __streambuf_type* 204 setbuf(char_type* __s, streamsize __n) 205 { 206 if (__s && __n >= 0) 207 { 208 // This is implementation-defined behavior, and assumes 209 // that an external char_type array of length __n exists 210 // and has been pre-allocated. If this is not the case, 211 // things will quickly blow up. 212 213 // Step 1: Destroy the current internal array. 214 _M_string.clear(); 215 216 // Step 2: Use the external array. 217 _M_sync(__s, __n, 0); 218 } 219 return this; 220 } 221 222 virtual pos_type 223 seekoff(off_type __off, ios_base::seekdir __way, 224 ios_base::openmode __mode = ios_base::in | ios_base::out); 225 226 virtual pos_type 227 seekpos(pos_type __sp, 228 ios_base::openmode __mode = ios_base::in | ios_base::out); 229 230 // Internal function for correctly updating the internal buffer 231 // for a particular _M_string, due to initialization or re-sizing 232 // of an existing _M_string. 233 void 234 _M_sync(char_type* __base, __size_type __i, __size_type __o); 235 236 // Internal function for correctly updating egptr() to the actual 237 // string end. 238 void 239 _M_update_egptr() 240 { 241 const bool __testin = _M_mode & ios_base::in; 242 if (this->pptr() && this->pptr() > this->egptr()) 243 if (__testin) 244 this->setg(this->eback(), this->gptr(), this->pptr()); 245 else 246 this->setg(this->pptr(), this->pptr(), this->pptr()); 247 } 248 }; 249 250 251 // [27.7.2] Template class basic_istringstream 252 /** 253 * @brief Controlling input for std::string. 254 * 255 * This class supports reading from objects of type std::basic_string, 256 * using the inherited functions from std::basic_istream. To control 257 * the associated sequence, an instance of std::basic_stringbuf is used, 258 * which this page refers to as @c sb. 259 */ 260 template<typename _CharT, typename _Traits, typename _Alloc> 261 class basic_istringstream : public basic_istream<_CharT, _Traits> 262 { 263 public: 264 // Types: 265 typedef _CharT char_type; 266 typedef _Traits traits_type; 267 // _GLIBCXX_RESOLVE_LIB_DEFECTS 268 // 251. basic_stringbuf missing allocator_type 269 typedef _Alloc allocator_type; 270 typedef typename traits_type::int_type int_type; 271 typedef typename traits_type::pos_type pos_type; 272 typedef typename traits_type::off_type off_type; 273 274 // Non-standard types: 275 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 276 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 277 typedef basic_istream<char_type, traits_type> __istream_type; 278 279 private: 280 __stringbuf_type _M_stringbuf; 281 282 public: 283 // Constructors: 284 /** 285 * @brief Default constructor starts with an empty string buffer. 286 * @param mode Whether the buffer can read, or write, or both. 287 * 288 * @c ios_base::in is automatically included in @a mode. 289 * 290 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 291 * class initializer. Does not allocate any buffer. 292 * 293 * @if maint 294 * That's a lie. We initialize the base class with NULL, because the 295 * string class does its own memory management. 296 * @endif 297 */ 298 explicit 299 basic_istringstream(ios_base::openmode __mode = ios_base::in) 300 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 301 { this->init(&_M_stringbuf); } 302 303 /** 304 * @brief Starts with an existing string buffer. 305 * @param str A string to copy as a starting buffer. 306 * @param mode Whether the buffer can read, or write, or both. 307 * 308 * @c ios_base::in is automatically included in @a mode. 309 * 310 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 311 * to the base class initializer. 312 * 313 * @if maint 314 * That's a lie. We initialize the base class with NULL, because the 315 * string class does its own memory management. 316 * @endif 317 */ 318 explicit 319 basic_istringstream(const __string_type& __str, 320 ios_base::openmode __mode = ios_base::in) 321 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 322 { this->init(&_M_stringbuf); } 323 324 /** 325 * @brief The destructor does nothing. 326 * 327 * The buffer is deallocated by the stringbuf object, not the 328 * formatting stream. 329 */ 330 ~basic_istringstream() 331 { } 332 333 // Members: 334 /** 335 * @brief Accessing the underlying buffer. 336 * @return The current basic_stringbuf buffer. 337 * 338 * This hides both signatures of std::basic_ios::rdbuf(). 339 */ 340 __stringbuf_type* 341 rdbuf() const 342 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 343 344 /** 345 * @brief Copying out the string buffer. 346 * @return @c rdbuf()->str() 347 */ 348 __string_type 349 str() const 350 { return _M_stringbuf.str(); } 351 352 /** 353 * @brief Setting a new buffer. 354 * @param s The string to use as a new sequence. 355 * 356 * Calls @c rdbuf()->str(s). 357 */ 358 void 359 str(const __string_type& __s) 360 { _M_stringbuf.str(__s); } 361 }; 362 363 364 // [27.7.3] Template class basic_ostringstream 365 /** 366 * @brief Controlling output for std::string. 367 * 368 * This class supports writing to objects of type std::basic_string, 369 * using the inherited functions from std::basic_ostream. To control 370 * the associated sequence, an instance of std::basic_stringbuf is used, 371 * which this page refers to as @c sb. 372 */ 373 template <typename _CharT, typename _Traits, typename _Alloc> 374 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 375 { 376 public: 377 // Types: 378 typedef _CharT char_type; 379 typedef _Traits traits_type; 380 // _GLIBCXX_RESOLVE_LIB_DEFECTS 381 // 251. basic_stringbuf missing allocator_type 382 typedef _Alloc allocator_type; 383 typedef typename traits_type::int_type int_type; 384 typedef typename traits_type::pos_type pos_type; 385 typedef typename traits_type::off_type off_type; 386 387 // Non-standard types: 388 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 389 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 390 typedef basic_ostream<char_type, traits_type> __ostream_type; 391 392 private: 393 __stringbuf_type _M_stringbuf; 394 395 public: 396 // Constructors/destructor: 397 /** 398 * @brief Default constructor starts with an empty string buffer. 399 * @param mode Whether the buffer can read, or write, or both. 400 * 401 * @c ios_base::out is automatically included in @a mode. 402 * 403 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 404 * class initializer. Does not allocate any buffer. 405 * 406 * @if maint 407 * That's a lie. We initialize the base class with NULL, because the 408 * string class does its own memory management. 409 * @endif 410 */ 411 explicit 412 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 413 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 414 { this->init(&_M_stringbuf); } 415 416 /** 417 * @brief Starts with an existing string buffer. 418 * @param str A string to copy as a starting buffer. 419 * @param mode Whether the buffer can read, or write, or both. 420 * 421 * @c ios_base::out is automatically included in @a mode. 422 * 423 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 424 * to the base class initializer. 425 * 426 * @if maint 427 * That's a lie. We initialize the base class with NULL, because the 428 * string class does its own memory management. 429 * @endif 430 */ 431 explicit 432 basic_ostringstream(const __string_type& __str, 433 ios_base::openmode __mode = ios_base::out) 434 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 435 { this->init(&_M_stringbuf); } 436 437 /** 438 * @brief The destructor does nothing. 439 * 440 * The buffer is deallocated by the stringbuf object, not the 441 * formatting stream. 442 */ 443 ~basic_ostringstream() 444 { } 445 446 // Members: 447 /** 448 * @brief Accessing the underlying buffer. 449 * @return The current basic_stringbuf buffer. 450 * 451 * This hides both signatures of std::basic_ios::rdbuf(). 452 */ 453 __stringbuf_type* 454 rdbuf() const 455 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 456 457 /** 458 * @brief Copying out the string buffer. 459 * @return @c rdbuf()->str() 460 */ 461 __string_type 462 str() const 463 { return _M_stringbuf.str(); } 464 465 /** 466 * @brief Setting a new buffer. 467 * @param s The string to use as a new sequence. 468 * 469 * Calls @c rdbuf()->str(s). 470 */ 471 void 472 str(const __string_type& __s) 473 { _M_stringbuf.str(__s); } 474 }; 475 476 477 // [27.7.4] Template class basic_stringstream 478 /** 479 * @brief Controlling input and output for std::string. 480 * 481 * This class supports reading from and writing to objects of type 482 * std::basic_string, using the inherited functions from 483 * std::basic_iostream. To control the associated sequence, an instance 484 * of std::basic_stringbuf is used, which this page refers to as @c sb. 485 */ 486 template <typename _CharT, typename _Traits, typename _Alloc> 487 class basic_stringstream : public basic_iostream<_CharT, _Traits> 488 { 489 public: 490 // Types: 491 typedef _CharT char_type; 492 typedef _Traits traits_type; 493 // _GLIBCXX_RESOLVE_LIB_DEFECTS 494 // 251. basic_stringbuf missing allocator_type 495 typedef _Alloc allocator_type; 496 typedef typename traits_type::int_type int_type; 497 typedef typename traits_type::pos_type pos_type; 498 typedef typename traits_type::off_type off_type; 499 500 // Non-standard Types: 501 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 502 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 503 typedef basic_iostream<char_type, traits_type> __iostream_type; 504 505 private: 506 __stringbuf_type _M_stringbuf; 507 508 public: 509 // Constructors/destructors 510 /** 511 * @brief Default constructor starts with an empty string buffer. 512 * @param mode Whether the buffer can read, or write, or both. 513 * 514 * Initializes @c sb using @c mode, and passes @c &sb to the base 515 * class initializer. Does not allocate any buffer. 516 * 517 * @if maint 518 * That's a lie. We initialize the base class with NULL, because the 519 * string class does its own memory management. 520 * @endif 521 */ 522 explicit 523 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 524 : __iostream_type(), _M_stringbuf(__m) 525 { this->init(&_M_stringbuf); } 526 527 /** 528 * @brief Starts with an existing string buffer. 529 * @param str A string to copy as a starting buffer. 530 * @param mode Whether the buffer can read, or write, or both. 531 * 532 * Initializes @c sb using @a str and @c mode, and passes @c &sb 533 * to the base class initializer. 534 * 535 * @if maint 536 * That's a lie. We initialize the base class with NULL, because the 537 * string class does its own memory management. 538 * @endif 539 */ 540 explicit 541 basic_stringstream(const __string_type& __str, 542 ios_base::openmode __m = ios_base::out | ios_base::in) 543 : __iostream_type(), _M_stringbuf(__str, __m) 544 { this->init(&_M_stringbuf); } 545 546 /** 547 * @brief The destructor does nothing. 548 * 549 * The buffer is deallocated by the stringbuf object, not the 550 * formatting stream. 551 */ 552 ~basic_stringstream() 553 { } 554 555 // Members: 556 /** 557 * @brief Accessing the underlying buffer. 558 * @return The current basic_stringbuf buffer. 559 * 560 * This hides both signatures of std::basic_ios::rdbuf(). 561 */ 562 __stringbuf_type* 563 rdbuf() const 564 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 565 566 /** 567 * @brief Copying out the string buffer. 568 * @return @c rdbuf()->str() 569 */ 570 __string_type 571 str() const 572 { return _M_stringbuf.str(); } 573 574 /** 575 * @brief Setting a new buffer. 576 * @param s The string to use as a new sequence. 577 * 578 * Calls @c rdbuf()->str(s). 579 */ 580 void 581 str(const __string_type& __s) 582 { _M_stringbuf.str(__s); } 583 }; 584 585 _GLIBCXX_END_NAMESPACE 586 587 #ifndef _GLIBCXX_EXPORT_TEMPLATE 588 # include <bits/sstream.tcc> 589 #endif 590 591 #endif /* _GLIBCXX_SSTREAM */ 592