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 { 244 if (__testin) 245 this->setg(this->eback(), this->gptr(), this->pptr()); 246 else 247 this->setg(this->pptr(), this->pptr(), this->pptr()); 248 } 249 } 250 }; 251 252 253 // [27.7.2] Template class basic_istringstream 254 /** 255 * @brief Controlling input for std::string. 256 * 257 * This class supports reading from objects of type std::basic_string, 258 * using the inherited functions from std::basic_istream. To control 259 * the associated sequence, an instance of std::basic_stringbuf is used, 260 * which this page refers to as @c sb. 261 */ 262 template<typename _CharT, typename _Traits, typename _Alloc> 263 class basic_istringstream : public basic_istream<_CharT, _Traits> 264 { 265 public: 266 // Types: 267 typedef _CharT char_type; 268 typedef _Traits traits_type; 269 // _GLIBCXX_RESOLVE_LIB_DEFECTS 270 // 251. basic_stringbuf missing allocator_type 271 typedef _Alloc allocator_type; 272 typedef typename traits_type::int_type int_type; 273 typedef typename traits_type::pos_type pos_type; 274 typedef typename traits_type::off_type off_type; 275 276 // Non-standard types: 277 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 278 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 279 typedef basic_istream<char_type, traits_type> __istream_type; 280 281 private: 282 __stringbuf_type _M_stringbuf; 283 284 public: 285 // Constructors: 286 /** 287 * @brief Default constructor starts with an empty string buffer. 288 * @param mode Whether the buffer can read, or write, or both. 289 * 290 * @c ios_base::in is automatically included in @a mode. 291 * 292 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 293 * class initializer. Does not allocate any buffer. 294 * 295 * @if maint 296 * That's a lie. We initialize the base class with NULL, because the 297 * string class does its own memory management. 298 * @endif 299 */ 300 explicit 301 basic_istringstream(ios_base::openmode __mode = ios_base::in) 302 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 303 { this->init(&_M_stringbuf); } 304 305 /** 306 * @brief Starts with an existing string buffer. 307 * @param str A string to copy as a starting buffer. 308 * @param mode Whether the buffer can read, or write, or both. 309 * 310 * @c ios_base::in is automatically included in @a mode. 311 * 312 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 313 * to the base class initializer. 314 * 315 * @if maint 316 * That's a lie. We initialize the base class with NULL, because the 317 * string class does its own memory management. 318 * @endif 319 */ 320 explicit 321 basic_istringstream(const __string_type& __str, 322 ios_base::openmode __mode = ios_base::in) 323 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 324 { this->init(&_M_stringbuf); } 325 326 /** 327 * @brief The destructor does nothing. 328 * 329 * The buffer is deallocated by the stringbuf object, not the 330 * formatting stream. 331 */ 332 ~basic_istringstream() 333 { } 334 335 // Members: 336 /** 337 * @brief Accessing the underlying buffer. 338 * @return The current basic_stringbuf buffer. 339 * 340 * This hides both signatures of std::basic_ios::rdbuf(). 341 */ 342 __stringbuf_type* 343 rdbuf() const 344 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 345 346 /** 347 * @brief Copying out the string buffer. 348 * @return @c rdbuf()->str() 349 */ 350 __string_type 351 str() const 352 { return _M_stringbuf.str(); } 353 354 /** 355 * @brief Setting a new buffer. 356 * @param s The string to use as a new sequence. 357 * 358 * Calls @c rdbuf()->str(s). 359 */ 360 void 361 str(const __string_type& __s) 362 { _M_stringbuf.str(__s); } 363 }; 364 365 366 // [27.7.3] Template class basic_ostringstream 367 /** 368 * @brief Controlling output for std::string. 369 * 370 * This class supports writing to objects of type std::basic_string, 371 * using the inherited functions from std::basic_ostream. To control 372 * the associated sequence, an instance of std::basic_stringbuf is used, 373 * which this page refers to as @c sb. 374 */ 375 template <typename _CharT, typename _Traits, typename _Alloc> 376 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 377 { 378 public: 379 // Types: 380 typedef _CharT char_type; 381 typedef _Traits traits_type; 382 // _GLIBCXX_RESOLVE_LIB_DEFECTS 383 // 251. basic_stringbuf missing allocator_type 384 typedef _Alloc allocator_type; 385 typedef typename traits_type::int_type int_type; 386 typedef typename traits_type::pos_type pos_type; 387 typedef typename traits_type::off_type off_type; 388 389 // Non-standard types: 390 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 391 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 392 typedef basic_ostream<char_type, traits_type> __ostream_type; 393 394 private: 395 __stringbuf_type _M_stringbuf; 396 397 public: 398 // Constructors/destructor: 399 /** 400 * @brief Default constructor starts with an empty string buffer. 401 * @param mode Whether the buffer can read, or write, or both. 402 * 403 * @c ios_base::out is automatically included in @a mode. 404 * 405 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 406 * class initializer. Does not allocate any buffer. 407 * 408 * @if maint 409 * That's a lie. We initialize the base class with NULL, because the 410 * string class does its own memory management. 411 * @endif 412 */ 413 explicit 414 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 415 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 416 { this->init(&_M_stringbuf); } 417 418 /** 419 * @brief Starts with an existing string buffer. 420 * @param str A string to copy as a starting buffer. 421 * @param mode Whether the buffer can read, or write, or both. 422 * 423 * @c ios_base::out is automatically included in @a mode. 424 * 425 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 426 * to the base class initializer. 427 * 428 * @if maint 429 * That's a lie. We initialize the base class with NULL, because the 430 * string class does its own memory management. 431 * @endif 432 */ 433 explicit 434 basic_ostringstream(const __string_type& __str, 435 ios_base::openmode __mode = ios_base::out) 436 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 437 { this->init(&_M_stringbuf); } 438 439 /** 440 * @brief The destructor does nothing. 441 * 442 * The buffer is deallocated by the stringbuf object, not the 443 * formatting stream. 444 */ 445 ~basic_ostringstream() 446 { } 447 448 // Members: 449 /** 450 * @brief Accessing the underlying buffer. 451 * @return The current basic_stringbuf buffer. 452 * 453 * This hides both signatures of std::basic_ios::rdbuf(). 454 */ 455 __stringbuf_type* 456 rdbuf() const 457 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 458 459 /** 460 * @brief Copying out the string buffer. 461 * @return @c rdbuf()->str() 462 */ 463 __string_type 464 str() const 465 { return _M_stringbuf.str(); } 466 467 /** 468 * @brief Setting a new buffer. 469 * @param s The string to use as a new sequence. 470 * 471 * Calls @c rdbuf()->str(s). 472 */ 473 void 474 str(const __string_type& __s) 475 { _M_stringbuf.str(__s); } 476 }; 477 478 479 // [27.7.4] Template class basic_stringstream 480 /** 481 * @brief Controlling input and output for std::string. 482 * 483 * This class supports reading from and writing to objects of type 484 * std::basic_string, using the inherited functions from 485 * std::basic_iostream. To control the associated sequence, an instance 486 * of std::basic_stringbuf is used, which this page refers to as @c sb. 487 */ 488 template <typename _CharT, typename _Traits, typename _Alloc> 489 class basic_stringstream : public basic_iostream<_CharT, _Traits> 490 { 491 public: 492 // Types: 493 typedef _CharT char_type; 494 typedef _Traits traits_type; 495 // _GLIBCXX_RESOLVE_LIB_DEFECTS 496 // 251. basic_stringbuf missing allocator_type 497 typedef _Alloc allocator_type; 498 typedef typename traits_type::int_type int_type; 499 typedef typename traits_type::pos_type pos_type; 500 typedef typename traits_type::off_type off_type; 501 502 // Non-standard Types: 503 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 504 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 505 typedef basic_iostream<char_type, traits_type> __iostream_type; 506 507 private: 508 __stringbuf_type _M_stringbuf; 509 510 public: 511 // Constructors/destructors 512 /** 513 * @brief Default constructor starts with an empty string buffer. 514 * @param mode Whether the buffer can read, or write, or both. 515 * 516 * Initializes @c sb using @c mode, and passes @c &sb to the base 517 * class initializer. Does not allocate any buffer. 518 * 519 * @if maint 520 * That's a lie. We initialize the base class with NULL, because the 521 * string class does its own memory management. 522 * @endif 523 */ 524 explicit 525 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 526 : __iostream_type(), _M_stringbuf(__m) 527 { this->init(&_M_stringbuf); } 528 529 /** 530 * @brief Starts with an existing string buffer. 531 * @param str A string to copy as a starting buffer. 532 * @param mode Whether the buffer can read, or write, or both. 533 * 534 * Initializes @c sb using @a str and @c mode, and passes @c &sb 535 * to the base class initializer. 536 * 537 * @if maint 538 * That's a lie. We initialize the base class with NULL, because the 539 * string class does its own memory management. 540 * @endif 541 */ 542 explicit 543 basic_stringstream(const __string_type& __str, 544 ios_base::openmode __m = ios_base::out | ios_base::in) 545 : __iostream_type(), _M_stringbuf(__str, __m) 546 { this->init(&_M_stringbuf); } 547 548 /** 549 * @brief The destructor does nothing. 550 * 551 * The buffer is deallocated by the stringbuf object, not the 552 * formatting stream. 553 */ 554 ~basic_stringstream() 555 { } 556 557 // Members: 558 /** 559 * @brief Accessing the underlying buffer. 560 * @return The current basic_stringbuf buffer. 561 * 562 * This hides both signatures of std::basic_ios::rdbuf(). 563 */ 564 __stringbuf_type* 565 rdbuf() const 566 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 567 568 /** 569 * @brief Copying out the string buffer. 570 * @return @c rdbuf()->str() 571 */ 572 __string_type 573 str() const 574 { return _M_stringbuf.str(); } 575 576 /** 577 * @brief Setting a new buffer. 578 * @param s The string to use as a new sequence. 579 * 580 * Calls @c rdbuf()->str(s). 581 */ 582 void 583 str(const __string_type& __s) 584 { _M_stringbuf.str(__s); } 585 }; 586 587_GLIBCXX_END_NAMESPACE 588 589#ifndef _GLIBCXX_EXPORT_TEMPLATE 590# include <bits/sstream.tcc> 591#endif 592 593#endif /* _GLIBCXX_SSTREAM */ 594