00001 // String based streams -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 // 00032 // ISO C++ 14882: 27.7 String-based streams 00033 // 00034 00035 /** @file sstream 00036 * This is a Standard C++ Library header. You should @c #include this header 00037 * in your programs, rather than any of the "st[dl]_*.h" implementation files. 00038 */ 00039 00040 #ifndef _GLIBCXX_SSTREAM 00041 #define _GLIBCXX_SSTREAM 1 00042 00043 #pragma GCC system_header 00044 00045 #include <istream> 00046 #include <ostream> 00047 00048 namespace std 00049 { 00050 // [27.7.1] template class basic_stringbuf 00051 /** 00052 * @brief The actual work of input and output (for std::string). 00053 * 00054 * This class associates either or both of its input and output sequences 00055 * with a sequence of characters, which can be initialized from, or made 00056 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 00057 * 00058 * For this class, open modes (of type @c ios_base::openmode) have 00059 * @c in set if the input sequence can be read, and @c out set if the 00060 * output sequence can be written. 00061 */ 00062 template<typename _CharT, typename _Traits, typename _Alloc> 00063 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 00064 { 00065 public: 00066 // Types: 00067 typedef _CharT char_type; 00068 typedef _Traits traits_type; 00069 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00070 // 251. basic_stringbuf missing allocator_type 00071 typedef _Alloc allocator_type; 00072 typedef typename traits_type::int_type int_type; 00073 typedef typename traits_type::pos_type pos_type; 00074 typedef typename traits_type::off_type off_type; 00075 00076 //@{ 00077 /** 00078 * @if maint 00079 * @doctodo 00080 * @endif 00081 */ 00082 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 00083 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 00084 typedef typename __string_type::size_type __size_type; 00085 //@} 00086 00087 protected: 00088 /** 00089 * @if maint 00090 * Place to stash in || out || in | out settings for current stringbuf. 00091 * @endif 00092 */ 00093 ios_base::openmode _M_mode; 00094 00095 // Data Members: 00096 /** 00097 * @if maint 00098 * @doctodo 00099 * @endif 00100 */ 00101 __string_type _M_string; 00102 00103 public: 00104 // Constructors: 00105 /** 00106 * @brief Starts with an empty string buffer. 00107 * @param mode Whether the buffer can read, or write, or both. 00108 * 00109 * The default constructor initializes the parent class using its 00110 * own default ctor. 00111 */ 00112 explicit 00113 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 00114 : __streambuf_type(), _M_mode(__mode), _M_string() 00115 { } 00116 00117 /** 00118 * @brief Starts with an existing string buffer. 00119 * @param str A string to copy as a starting buffer. 00120 * @param mode Whether the buffer can read, or write, or both. 00121 * 00122 * This constructor initializes the parent class using its 00123 * own default ctor. 00124 */ 00125 explicit 00126 basic_stringbuf(const __string_type& __str, 00127 ios_base::openmode __mode = ios_base::in | ios_base::out) 00128 : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) 00129 { _M_stringbuf_init(__mode); } 00130 00131 // Get and set: 00132 /** 00133 * @brief Copying out the string buffer. 00134 * @return A copy of one of the underlying sequences. 00135 * 00136 * "If the buffer is only created in input mode, the underlying 00137 * character sequence is equal to the input sequence; otherwise, it 00138 * is equal to the output sequence." [27.7.1.2]/1 00139 */ 00140 __string_type 00141 str() const 00142 { 00143 if (this->pptr()) 00144 { 00145 // The current egptr() may not be the actual string end. 00146 if (this->pptr() > this->egptr()) 00147 return __string_type(this->pbase(), this->pptr()); 00148 else 00149 return __string_type(this->pbase(), this->egptr()); 00150 } 00151 else 00152 return _M_string; 00153 } 00154 00155 /** 00156 * @brief Setting a new buffer. 00157 * @param s The string to use as a new sequence. 00158 * 00159 * Deallocates any previous stored sequence, then copies @a s to 00160 * use as a new one. 00161 */ 00162 void 00163 str(const __string_type& __s) 00164 { 00165 // Cannot use _M_string = __s, since v3 strings are COW. 00166 _M_string.assign(__s.data(), __s.size()); 00167 _M_stringbuf_init(this->_M_mode); 00168 } 00169 00170 protected: 00171 // Common initialization code goes here. 00172 /** 00173 * @if maint 00174 * @doctodo 00175 * @endif 00176 */ 00177 void 00178 _M_stringbuf_init(ios_base::openmode __mode) 00179 { 00180 this->_M_mode = __mode; 00181 00182 __size_type __len = 0; 00183 if (this->_M_mode & (ios_base::ate | ios_base::app)) 00184 __len = _M_string.size(); 00185 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 00186 } 00187 00188 // [documentation is inherited] 00189 virtual int_type 00190 underflow(); 00191 00192 // [documentation is inherited] 00193 virtual int_type 00194 pbackfail(int_type __c = traits_type::eof()); 00195 00196 // [documentation is inherited] 00197 virtual int_type 00198 overflow(int_type __c = traits_type::eof()); 00199 00200 /** 00201 * @brief Manipulates the buffer. 00202 * @param s Pointer to a buffer area. 00203 * @param n Size of @a s. 00204 * @return @c this 00205 * 00206 * If no buffer has already been created, and both @a s and @a n are 00207 * non-zero, then @c s is used as a buffer; see 00208 * http://gcc.gnu.org/onlinedocs/libstdc++/27_io/howto.html#2 00209 * for more. 00210 */ 00211 virtual __streambuf_type* 00212 setbuf(char_type* __s, streamsize __n) 00213 { 00214 if (__s && __n >= 0) 00215 { 00216 // This is implementation-defined behavior, and assumes 00217 // that an external char_type array of length __n exists 00218 // and has been pre-allocated. If this is not the case, 00219 // things will quickly blow up. 00220 00221 // Step 1: Destroy the current internal array. 00222 _M_string = __string_type(__s, __n); 00223 00224 // Step 2: Use the external array. 00225 _M_sync(__s, 0, 0); 00226 } 00227 return this; 00228 } 00229 00230 // [documentation is inherited] 00231 virtual pos_type 00232 seekoff(off_type __off, ios_base::seekdir __way, 00233 ios_base::openmode __mode = ios_base::in | ios_base::out); 00234 00235 // [documentation is inherited] 00236 virtual pos_type 00237 seekpos(pos_type __sp, 00238 ios_base::openmode __mode = ios_base::in | ios_base::out); 00239 00240 // Internal function for correctly updating the internal buffer 00241 // for a particular _M_string, due to initialization or 00242 // re-sizing of an existing _M_string. 00243 // Assumes: contents of _M_string and internal buffer match exactly. 00244 // __i == _M_in_cur - _M_in_beg 00245 // __o == _M_out_cur - _M_out_beg 00246 /** 00247 * @if maint 00248 * @doctodo 00249 * @endif 00250 */ 00251 void 00252 _M_sync(char_type* __base, __size_type __i, __size_type __o) 00253 { 00254 const bool __testin = this->_M_mode & ios_base::in; 00255 const bool __testout = this->_M_mode & ios_base::out; 00256 const __size_type __len = _M_string.size(); 00257 00258 if (__testin) 00259 this->setg(__base, __base + __i, __base + __len); 00260 if (__testout) 00261 { 00262 this->setp(__base, __base + _M_string.capacity()); 00263 this->pbump(__o); 00264 // We need a pointer to the string end anyway, even when 00265 // !__testin: in that case, however, for the correct 00266 // functioning of the streambuf inlines all the get area 00267 // pointers must be identical. 00268 if (!__testin) 00269 this->setg(__base + __len, __base + __len, __base + __len); 00270 } 00271 } 00272 00273 // Internal function for correctly updating egptr() to the actual 00274 // string end. 00275 void 00276 _M_update_egptr() 00277 { 00278 const bool __testin = this->_M_mode & ios_base::in; 00279 00280 if (this->pptr() && this->pptr() > this->egptr()) 00281 if (__testin) 00282 this->setg(this->eback(), this->gptr(), this->pptr()); 00283 else 00284 this->setg(this->pptr(), this->pptr(), this->pptr()); 00285 } 00286 }; 00287 00288 00289 // [27.7.2] Template class basic_istringstream 00290 /** 00291 * @brief Controlling input for std::string. 00292 * 00293 * This class supports reading from objects of type std::basic_string, 00294 * using the inherited functions from std::basic_istream. To control 00295 * the associated sequence, an instance of std::basic_stringbuf is used, 00296 * which this page refers to as @c sb. 00297 */ 00298 template<typename _CharT, typename _Traits, typename _Alloc> 00299 class basic_istringstream : public basic_istream<_CharT, _Traits> 00300 { 00301 public: 00302 // Types: 00303 typedef _CharT char_type; 00304 typedef _Traits traits_type; 00305 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00306 // 251. basic_stringbuf missing allocator_type 00307 typedef _Alloc allocator_type; 00308 typedef typename traits_type::int_type int_type; 00309 typedef typename traits_type::pos_type pos_type; 00310 typedef typename traits_type::off_type off_type; 00311 00312 // Non-standard types: 00313 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00314 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00315 typedef basic_istream<char_type, traits_type> __istream_type; 00316 00317 private: 00318 /** 00319 * @if maint 00320 * @doctodo 00321 * @endif 00322 */ 00323 __stringbuf_type _M_stringbuf; 00324 00325 public: 00326 // Constructors: 00327 /** 00328 * @brief Default constructor starts with an empty string buffer. 00329 * @param mode Whether the buffer can read, or write, or both. 00330 * 00331 * @c ios_base::in is automatically included in @a mode. 00332 * 00333 * Initializes @c sb using @c mode|in, and passes @c &sb to the base 00334 * class initializer. Does not allocate any buffer. 00335 * 00336 * @if maint 00337 * That's a lie. We initialize the base class with NULL, because the 00338 * string class does its own memory management. 00339 * @endif 00340 */ 00341 explicit 00342 basic_istringstream(ios_base::openmode __mode = ios_base::in) 00343 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 00344 { this->init(&_M_stringbuf); } 00345 00346 /** 00347 * @brief Starts with an existing string buffer. 00348 * @param str A string to copy as a starting buffer. 00349 * @param mode Whether the buffer can read, or write, or both. 00350 * 00351 * @c ios_base::in is automatically included in @a mode. 00352 * 00353 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 00354 * to the base class initializer. 00355 * 00356 * @if maint 00357 * That's a lie. We initialize the base class with NULL, because the 00358 * string class does its own memory management. 00359 * @endif 00360 */ 00361 explicit 00362 basic_istringstream(const __string_type& __str, 00363 ios_base::openmode __mode = ios_base::in) 00364 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 00365 { this->init(&_M_stringbuf); } 00366 00367 /** 00368 * @brief The destructor does nothing. 00369 * 00370 * The buffer is deallocated by the stringbuf object, not the 00371 * formatting stream. 00372 */ 00373 ~basic_istringstream() 00374 { } 00375 00376 // Members: 00377 /** 00378 * @brief Accessing the underlying buffer. 00379 * @return The current basic_stringbuf buffer. 00380 * 00381 * This hides both signatures of std::basic_ios::rdbuf(). 00382 */ 00383 __stringbuf_type* 00384 rdbuf() const 00385 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00386 00387 /** 00388 * @brief Copying out the string buffer. 00389 * @return @c rdbuf()->str() 00390 */ 00391 __string_type 00392 str() const 00393 { return _M_stringbuf.str(); } 00394 00395 /** 00396 * @brief Setting a new buffer. 00397 * @param s The string to use as a new sequence. 00398 * 00399 * Calls @c rdbuf()->str(s). 00400 */ 00401 void 00402 str(const __string_type& __s) 00403 { _M_stringbuf.str(__s); } 00404 }; 00405 00406 00407 // [27.7.3] Template class basic_ostringstream 00408 /** 00409 * @brief Controlling output for std::string. 00410 * 00411 * This class supports writing to objects of type std::basic_string, 00412 * using the inherited functions from std::basic_ostream. To control 00413 * the associated sequence, an instance of std::basic_stringbuf is used, 00414 * which this page refers to as @c sb. 00415 */ 00416 template <typename _CharT, typename _Traits, typename _Alloc> 00417 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 00418 { 00419 public: 00420 // Types: 00421 typedef _CharT char_type; 00422 typedef _Traits traits_type; 00423 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00424 // 251. basic_stringbuf missing allocator_type 00425 typedef _Alloc allocator_type; 00426 typedef typename traits_type::int_type int_type; 00427 typedef typename traits_type::pos_type pos_type; 00428 typedef typename traits_type::off_type off_type; 00429 00430 // Non-standard types: 00431 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00432 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00433 typedef basic_ostream<char_type, traits_type> __ostream_type; 00434 00435 private: 00436 /** 00437 * @if maint 00438 * @doctodo 00439 * @endif 00440 */ 00441 __stringbuf_type _M_stringbuf; 00442 00443 public: 00444 // Constructors/destructor: 00445 /** 00446 * @brief Default constructor starts with an empty string buffer. 00447 * @param mode Whether the buffer can read, or write, or both. 00448 * 00449 * @c ios_base::out is automatically included in @a mode. 00450 * 00451 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 00452 * class initializer. Does not allocate any buffer. 00453 * 00454 * @if maint 00455 * That's a lie. We initialize the base class with NULL, because the 00456 * string class does its own memory management. 00457 * @endif 00458 */ 00459 explicit 00460 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 00461 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 00462 { this->init(&_M_stringbuf); } 00463 00464 /** 00465 * @brief Starts with an existing string buffer. 00466 * @param str A string to copy as a starting buffer. 00467 * @param mode Whether the buffer can read, or write, or both. 00468 * 00469 * @c ios_base::out is automatically included in @a mode. 00470 * 00471 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 00472 * to the base class initializer. 00473 * 00474 * @if maint 00475 * That's a lie. We initialize the base class with NULL, because the 00476 * string class does its own memory management. 00477 * @endif 00478 */ 00479 explicit 00480 basic_ostringstream(const __string_type& __str, 00481 ios_base::openmode __mode = ios_base::out) 00482 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 00483 { this->init(&_M_stringbuf); } 00484 00485 /** 00486 * @brief The destructor does nothing. 00487 * 00488 * The buffer is deallocated by the stringbuf object, not the 00489 * formatting stream. 00490 */ 00491 ~basic_ostringstream() 00492 { } 00493 00494 // Members: 00495 /** 00496 * @brief Accessing the underlying buffer. 00497 * @return The current basic_stringbuf buffer. 00498 * 00499 * This hides both signatures of std::basic_ios::rdbuf(). 00500 */ 00501 __stringbuf_type* 00502 rdbuf() const 00503 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00504 00505 /** 00506 * @brief Copying out the string buffer. 00507 * @return @c rdbuf()->str() 00508 */ 00509 __string_type 00510 str() const 00511 { return _M_stringbuf.str(); } 00512 00513 /** 00514 * @brief Setting a new buffer. 00515 * @param s The string to use as a new sequence. 00516 * 00517 * Calls @c rdbuf()->str(s). 00518 */ 00519 void 00520 str(const __string_type& __s) 00521 { _M_stringbuf.str(__s); } 00522 }; 00523 00524 00525 // [27.7.4] Template class basic_stringstream 00526 /** 00527 * @brief Controlling input and output for std::string. 00528 * 00529 * This class supports reading from and writing to objects of type 00530 * std::basic_string, using the inherited functions from 00531 * std::basic_iostream. To control the associated sequence, an instance 00532 * of std::basic_stringbuf is used, which this page refers to as @c sb. 00533 */ 00534 template <typename _CharT, typename _Traits, typename _Alloc> 00535 class basic_stringstream : public basic_iostream<_CharT, _Traits> 00536 { 00537 public: 00538 // Types: 00539 typedef _CharT char_type; 00540 typedef _Traits traits_type; 00541 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00542 // 251. basic_stringbuf missing allocator_type 00543 typedef _Alloc allocator_type; 00544 typedef typename traits_type::int_type int_type; 00545 typedef typename traits_type::pos_type pos_type; 00546 typedef typename traits_type::off_type off_type; 00547 00548 // Non-standard Types: 00549 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00550 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00551 typedef basic_iostream<char_type, traits_type> __iostream_type; 00552 00553 private: 00554 /** 00555 * @if maint 00556 * @doctodo 00557 * @endif 00558 */ 00559 __stringbuf_type _M_stringbuf; 00560 00561 public: 00562 // Constructors/destructors 00563 /** 00564 * @brief Default constructor starts with an empty string buffer. 00565 * @param mode Whether the buffer can read, or write, or both. 00566 * 00567 * Initializes @c sb using @c mode, and passes @c &sb to the base 00568 * class initializer. Does not allocate any buffer. 00569 * 00570 * @if maint 00571 * That's a lie. We initialize the base class with NULL, because the 00572 * string class does its own memory management. 00573 * @endif 00574 */ 00575 explicit 00576 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 00577 : __iostream_type(), _M_stringbuf(__m) 00578 { this->init(&_M_stringbuf); } 00579 00580 /** 00581 * @brief Starts with an existing string buffer. 00582 * @param str A string to copy as a starting buffer. 00583 * @param mode Whether the buffer can read, or write, or both. 00584 * 00585 * Initializes @c sb using @a str and @c mode, and passes @c &sb 00586 * to the base class initializer. 00587 * 00588 * @if maint 00589 * That's a lie. We initialize the base class with NULL, because the 00590 * string class does its own memory management. 00591 * @endif 00592 */ 00593 explicit 00594 basic_stringstream(const __string_type& __str, 00595 ios_base::openmode __m = ios_base::out | ios_base::in) 00596 : __iostream_type(), _M_stringbuf(__str, __m) 00597 { this->init(&_M_stringbuf); } 00598 00599 /** 00600 * @brief The destructor does nothing. 00601 * 00602 * The buffer is deallocated by the stringbuf object, not the 00603 * formatting stream. 00604 */ 00605 ~basic_stringstream() 00606 { } 00607 00608 // Members: 00609 /** 00610 * @brief Accessing the underlying buffer. 00611 * @return The current basic_stringbuf buffer. 00612 * 00613 * This hides both signatures of std::basic_ios::rdbuf(). 00614 */ 00615 __stringbuf_type* 00616 rdbuf() const 00617 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00618 00619 /** 00620 * @brief Copying out the string buffer. 00621 * @return @c rdbuf()->str() 00622 */ 00623 __string_type 00624 str() const 00625 { return _M_stringbuf.str(); } 00626 00627 /** 00628 * @brief Setting a new buffer. 00629 * @param s The string to use as a new sequence. 00630 * 00631 * Calls @c rdbuf()->str(s). 00632 */ 00633 void 00634 str(const __string_type& __s) 00635 { _M_stringbuf.str(__s); } 00636 }; 00637 } // namespace std 00638 00639 #ifndef _GLIBCXX_EXPORT_TEMPLATE 00640 # include <bits/sstream.tcc> 00641 #endif 00642 00643 #endif /* _GLIBCXX_SSTREAM */