sstream 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. // String based streams -*- C++ -*-
  2. // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
  3. // 2006, 2008, 2009 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library. This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. // Under Section 7 of GPL version 3, you are granted additional
  15. // permissions described in the GCC Runtime Library Exception, version
  16. // 3.1, as published by the Free Software Foundation.
  17. // You should have received a copy of the GNU General Public License and
  18. // a copy of the GCC Runtime Library Exception along with this program;
  19. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  20. // <http://www.gnu.org/licenses/>.
  21. /** @file sstream
  22. * This is a Standard C++ Library header.
  23. */
  24. //
  25. // ISO C++ 14882: 27.7 String-based streams
  26. //
  27. #ifndef _GLIBCXX_SSTREAM
  28. #define _GLIBCXX_SSTREAM 1
  29. #pragma GCC system_header
  30. #include <istream>
  31. #include <ostream>
  32. _GLIBCXX_BEGIN_NAMESPACE(std)
  33. // [27.7.1] template class basic_stringbuf
  34. /**
  35. * @brief The actual work of input and output (for std::string).
  36. * @ingroup io
  37. *
  38. * This class associates either or both of its input and output sequences
  39. * with a sequence of characters, which can be initialized from, or made
  40. * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.)
  41. *
  42. * For this class, open modes (of type @c ios_base::openmode) have
  43. * @c in set if the input sequence can be read, and @c out set if the
  44. * output sequence can be written.
  45. */
  46. template<typename _CharT, typename _Traits, typename _Alloc>
  47. class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
  48. {
  49. public:
  50. // Types:
  51. typedef _CharT char_type;
  52. typedef _Traits traits_type;
  53. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  54. // 251. basic_stringbuf missing allocator_type
  55. typedef _Alloc allocator_type;
  56. typedef typename traits_type::int_type int_type;
  57. typedef typename traits_type::pos_type pos_type;
  58. typedef typename traits_type::off_type off_type;
  59. typedef basic_streambuf<char_type, traits_type> __streambuf_type;
  60. typedef basic_string<char_type, _Traits, _Alloc> __string_type;
  61. typedef typename __string_type::size_type __size_type;
  62. protected:
  63. /// Place to stash in || out || in | out settings for current stringbuf.
  64. ios_base::openmode _M_mode;
  65. // Data Members:
  66. __string_type _M_string;
  67. public:
  68. // Constructors:
  69. /**
  70. * @brief Starts with an empty string buffer.
  71. * @param mode Whether the buffer can read, or write, or both.
  72. *
  73. * The default constructor initializes the parent class using its
  74. * own default ctor.
  75. */
  76. explicit
  77. basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
  78. : __streambuf_type(), _M_mode(__mode), _M_string()
  79. { }
  80. /**
  81. * @brief Starts with an existing string buffer.
  82. * @param str A string to copy as a starting buffer.
  83. * @param mode Whether the buffer can read, or write, or both.
  84. *
  85. * This constructor initializes the parent class using its
  86. * own default ctor.
  87. */
  88. explicit
  89. basic_stringbuf(const __string_type& __str,
  90. ios_base::openmode __mode = ios_base::in | ios_base::out)
  91. : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
  92. { _M_stringbuf_init(__mode); }
  93. // Get and set:
  94. /**
  95. * @brief Copying out the string buffer.
  96. * @return A copy of one of the underlying sequences.
  97. *
  98. * "If the buffer is only created in input mode, the underlying
  99. * character sequence is equal to the input sequence; otherwise, it
  100. * is equal to the output sequence." [27.7.1.2]/1
  101. */
  102. __string_type
  103. str() const
  104. {
  105. __string_type __ret;
  106. if (this->pptr())
  107. {
  108. // The current egptr() may not be the actual string end.
  109. if (this->pptr() > this->egptr())
  110. __ret = __string_type(this->pbase(), this->pptr());
  111. else
  112. __ret = __string_type(this->pbase(), this->egptr());
  113. }
  114. else
  115. __ret = _M_string;
  116. return __ret;
  117. }
  118. /**
  119. * @brief Setting a new buffer.
  120. * @param s The string to use as a new sequence.
  121. *
  122. * Deallocates any previous stored sequence, then copies @a s to
  123. * use as a new one.
  124. */
  125. void
  126. str(const __string_type& __s)
  127. {
  128. // Cannot use _M_string = __s, since v3 strings are COW.
  129. _M_string.assign(__s.data(), __s.size());
  130. _M_stringbuf_init(_M_mode);
  131. }
  132. protected:
  133. // Common initialization code goes here.
  134. void
  135. _M_stringbuf_init(ios_base::openmode __mode)
  136. {
  137. _M_mode = __mode;
  138. __size_type __len = 0;
  139. if (_M_mode & (ios_base::ate | ios_base::app))
  140. __len = _M_string.size();
  141. _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
  142. }
  143. virtual streamsize
  144. showmanyc()
  145. {
  146. streamsize __ret = -1;
  147. if (_M_mode & ios_base::in)
  148. {
  149. _M_update_egptr();
  150. __ret = this->egptr() - this->gptr();
  151. }
  152. return __ret;
  153. }
  154. virtual int_type
  155. underflow();
  156. virtual int_type
  157. pbackfail(int_type __c = traits_type::eof());
  158. virtual int_type
  159. overflow(int_type __c = traits_type::eof());
  160. /**
  161. * @brief Manipulates the buffer.
  162. * @param s Pointer to a buffer area.
  163. * @param n Size of @a s.
  164. * @return @c this
  165. *
  166. * If no buffer has already been created, and both @a s and @a n are
  167. * non-zero, then @c s is used as a buffer; see
  168. * http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt11ch25s02.html
  169. * for more.
  170. */
  171. virtual __streambuf_type*
  172. setbuf(char_type* __s, streamsize __n)
  173. {
  174. if (__s && __n >= 0)
  175. {
  176. // This is implementation-defined behavior, and assumes
  177. // that an external char_type array of length __n exists
  178. // and has been pre-allocated. If this is not the case,
  179. // things will quickly blow up.
  180. // Step 1: Destroy the current internal array.
  181. _M_string.clear();
  182. // Step 2: Use the external array.
  183. _M_sync(__s, __n, 0);
  184. }
  185. return this;
  186. }
  187. virtual pos_type
  188. seekoff(off_type __off, ios_base::seekdir __way,
  189. ios_base::openmode __mode = ios_base::in | ios_base::out);
  190. virtual pos_type
  191. seekpos(pos_type __sp,
  192. ios_base::openmode __mode = ios_base::in | ios_base::out);
  193. // Internal function for correctly updating the internal buffer
  194. // for a particular _M_string, due to initialization or re-sizing
  195. // of an existing _M_string.
  196. void
  197. _M_sync(char_type* __base, __size_type __i, __size_type __o);
  198. // Internal function for correctly updating egptr() to the actual
  199. // string end.
  200. void
  201. _M_update_egptr()
  202. {
  203. const bool __testin = _M_mode & ios_base::in;
  204. if (this->pptr() && this->pptr() > this->egptr())
  205. {
  206. if (__testin)
  207. this->setg(this->eback(), this->gptr(), this->pptr());
  208. else
  209. this->setg(this->pptr(), this->pptr(), this->pptr());
  210. }
  211. }
  212. };
  213. // [27.7.2] Template class basic_istringstream
  214. /**
  215. * @brief Controlling input for std::string.
  216. * @ingroup io
  217. *
  218. * This class supports reading from objects of type std::basic_string,
  219. * using the inherited functions from std::basic_istream. To control
  220. * the associated sequence, an instance of std::basic_stringbuf is used,
  221. * which this page refers to as @c sb.
  222. */
  223. template<typename _CharT, typename _Traits, typename _Alloc>
  224. class basic_istringstream : public basic_istream<_CharT, _Traits>
  225. {
  226. public:
  227. // Types:
  228. typedef _CharT char_type;
  229. typedef _Traits traits_type;
  230. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  231. // 251. basic_stringbuf missing allocator_type
  232. typedef _Alloc allocator_type;
  233. typedef typename traits_type::int_type int_type;
  234. typedef typename traits_type::pos_type pos_type;
  235. typedef typename traits_type::off_type off_type;
  236. // Non-standard types:
  237. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  238. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  239. typedef basic_istream<char_type, traits_type> __istream_type;
  240. private:
  241. __stringbuf_type _M_stringbuf;
  242. public:
  243. // Constructors:
  244. /**
  245. * @brief Default constructor starts with an empty string buffer.
  246. * @param mode Whether the buffer can read, or write, or both.
  247. *
  248. * @c ios_base::in is automatically included in @a mode.
  249. *
  250. * Initializes @c sb using @c mode|in, and passes @c &sb to the base
  251. * class initializer. Does not allocate any buffer.
  252. *
  253. * That's a lie. We initialize the base class with NULL, because the
  254. * string class does its own memory management.
  255. */
  256. explicit
  257. basic_istringstream(ios_base::openmode __mode = ios_base::in)
  258. : __istream_type(), _M_stringbuf(__mode | ios_base::in)
  259. { this->init(&_M_stringbuf); }
  260. /**
  261. * @brief Starts with an existing string buffer.
  262. * @param str A string to copy as a starting buffer.
  263. * @param mode Whether the buffer can read, or write, or both.
  264. *
  265. * @c ios_base::in is automatically included in @a mode.
  266. *
  267. * Initializes @c sb using @a str and @c mode|in, and passes @c &sb
  268. * to the base class initializer.
  269. *
  270. * That's a lie. We initialize the base class with NULL, because the
  271. * string class does its own memory management.
  272. */
  273. explicit
  274. basic_istringstream(const __string_type& __str,
  275. ios_base::openmode __mode = ios_base::in)
  276. : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
  277. { this->init(&_M_stringbuf); }
  278. /**
  279. * @brief The destructor does nothing.
  280. *
  281. * The buffer is deallocated by the stringbuf object, not the
  282. * formatting stream.
  283. */
  284. ~basic_istringstream()
  285. { }
  286. // Members:
  287. /**
  288. * @brief Accessing the underlying buffer.
  289. * @return The current basic_stringbuf buffer.
  290. *
  291. * This hides both signatures of std::basic_ios::rdbuf().
  292. */
  293. __stringbuf_type*
  294. rdbuf() const
  295. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  296. /**
  297. * @brief Copying out the string buffer.
  298. * @return @c rdbuf()->str()
  299. */
  300. __string_type
  301. str() const
  302. { return _M_stringbuf.str(); }
  303. /**
  304. * @brief Setting a new buffer.
  305. * @param s The string to use as a new sequence.
  306. *
  307. * Calls @c rdbuf()->str(s).
  308. */
  309. void
  310. str(const __string_type& __s)
  311. { _M_stringbuf.str(__s); }
  312. };
  313. // [27.7.3] Template class basic_ostringstream
  314. /**
  315. * @brief Controlling output for std::string.
  316. * @ingroup io
  317. *
  318. * This class supports writing to objects of type std::basic_string,
  319. * using the inherited functions from std::basic_ostream. To control
  320. * the associated sequence, an instance of std::basic_stringbuf is used,
  321. * which this page refers to as @c sb.
  322. */
  323. template <typename _CharT, typename _Traits, typename _Alloc>
  324. class basic_ostringstream : public basic_ostream<_CharT, _Traits>
  325. {
  326. public:
  327. // Types:
  328. typedef _CharT char_type;
  329. typedef _Traits traits_type;
  330. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  331. // 251. basic_stringbuf missing allocator_type
  332. typedef _Alloc allocator_type;
  333. typedef typename traits_type::int_type int_type;
  334. typedef typename traits_type::pos_type pos_type;
  335. typedef typename traits_type::off_type off_type;
  336. // Non-standard types:
  337. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  338. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  339. typedef basic_ostream<char_type, traits_type> __ostream_type;
  340. private:
  341. __stringbuf_type _M_stringbuf;
  342. public:
  343. // Constructors/destructor:
  344. /**
  345. * @brief Default constructor starts with an empty string buffer.
  346. * @param mode Whether the buffer can read, or write, or both.
  347. *
  348. * @c ios_base::out is automatically included in @a mode.
  349. *
  350. * Initializes @c sb using @c mode|out, and passes @c &sb to the base
  351. * class initializer. Does not allocate any buffer.
  352. *
  353. * That's a lie. We initialize the base class with NULL, because the
  354. * string class does its own memory management.
  355. */
  356. explicit
  357. basic_ostringstream(ios_base::openmode __mode = ios_base::out)
  358. : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
  359. { this->init(&_M_stringbuf); }
  360. /**
  361. * @brief Starts with an existing string buffer.
  362. * @param str A string to copy as a starting buffer.
  363. * @param mode Whether the buffer can read, or write, or both.
  364. *
  365. * @c ios_base::out is automatically included in @a mode.
  366. *
  367. * Initializes @c sb using @a str and @c mode|out, and passes @c &sb
  368. * to the base class initializer.
  369. *
  370. * That's a lie. We initialize the base class with NULL, because the
  371. * string class does its own memory management.
  372. */
  373. explicit
  374. basic_ostringstream(const __string_type& __str,
  375. ios_base::openmode __mode = ios_base::out)
  376. : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
  377. { this->init(&_M_stringbuf); }
  378. /**
  379. * @brief The destructor does nothing.
  380. *
  381. * The buffer is deallocated by the stringbuf object, not the
  382. * formatting stream.
  383. */
  384. ~basic_ostringstream()
  385. { }
  386. // Members:
  387. /**
  388. * @brief Accessing the underlying buffer.
  389. * @return The current basic_stringbuf buffer.
  390. *
  391. * This hides both signatures of std::basic_ios::rdbuf().
  392. */
  393. __stringbuf_type*
  394. rdbuf() const
  395. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  396. /**
  397. * @brief Copying out the string buffer.
  398. * @return @c rdbuf()->str()
  399. */
  400. __string_type
  401. str() const
  402. { return _M_stringbuf.str(); }
  403. /**
  404. * @brief Setting a new buffer.
  405. * @param s The string to use as a new sequence.
  406. *
  407. * Calls @c rdbuf()->str(s).
  408. */
  409. void
  410. str(const __string_type& __s)
  411. { _M_stringbuf.str(__s); }
  412. };
  413. // [27.7.4] Template class basic_stringstream
  414. /**
  415. * @brief Controlling input and output for std::string.
  416. * @ingroup io
  417. *
  418. * This class supports reading from and writing to objects of type
  419. * std::basic_string, using the inherited functions from
  420. * std::basic_iostream. To control the associated sequence, an instance
  421. * of std::basic_stringbuf is used, which this page refers to as @c sb.
  422. */
  423. template <typename _CharT, typename _Traits, typename _Alloc>
  424. class basic_stringstream : public basic_iostream<_CharT, _Traits>
  425. {
  426. public:
  427. // Types:
  428. typedef _CharT char_type;
  429. typedef _Traits traits_type;
  430. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  431. // 251. basic_stringbuf missing allocator_type
  432. typedef _Alloc allocator_type;
  433. typedef typename traits_type::int_type int_type;
  434. typedef typename traits_type::pos_type pos_type;
  435. typedef typename traits_type::off_type off_type;
  436. // Non-standard Types:
  437. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  438. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  439. typedef basic_iostream<char_type, traits_type> __iostream_type;
  440. private:
  441. __stringbuf_type _M_stringbuf;
  442. public:
  443. // Constructors/destructors
  444. /**
  445. * @brief Default constructor starts with an empty string buffer.
  446. * @param mode Whether the buffer can read, or write, or both.
  447. *
  448. * Initializes @c sb using @c mode, and passes @c &sb to the base
  449. * class initializer. Does not allocate any buffer.
  450. *
  451. * That's a lie. We initialize the base class with NULL, because the
  452. * string class does its own memory management.
  453. */
  454. explicit
  455. basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
  456. : __iostream_type(), _M_stringbuf(__m)
  457. { this->init(&_M_stringbuf); }
  458. /**
  459. * @brief Starts with an existing string buffer.
  460. * @param str A string to copy as a starting buffer.
  461. * @param mode Whether the buffer can read, or write, or both.
  462. *
  463. * Initializes @c sb using @a str and @c mode, and passes @c &sb
  464. * to the base class initializer.
  465. *
  466. * That's a lie. We initialize the base class with NULL, because the
  467. * string class does its own memory management.
  468. */
  469. explicit
  470. basic_stringstream(const __string_type& __str,
  471. ios_base::openmode __m = ios_base::out | ios_base::in)
  472. : __iostream_type(), _M_stringbuf(__str, __m)
  473. { this->init(&_M_stringbuf); }
  474. /**
  475. * @brief The destructor does nothing.
  476. *
  477. * The buffer is deallocated by the stringbuf object, not the
  478. * formatting stream.
  479. */
  480. ~basic_stringstream()
  481. { }
  482. // Members:
  483. /**
  484. * @brief Accessing the underlying buffer.
  485. * @return The current basic_stringbuf buffer.
  486. *
  487. * This hides both signatures of std::basic_ios::rdbuf().
  488. */
  489. __stringbuf_type*
  490. rdbuf() const
  491. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  492. /**
  493. * @brief Copying out the string buffer.
  494. * @return @c rdbuf()->str()
  495. */
  496. __string_type
  497. str() const
  498. { return _M_stringbuf.str(); }
  499. /**
  500. * @brief Setting a new buffer.
  501. * @param s The string to use as a new sequence.
  502. *
  503. * Calls @c rdbuf()->str(s).
  504. */
  505. void
  506. str(const __string_type& __s)
  507. { _M_stringbuf.str(__s); }
  508. };
  509. _GLIBCXX_END_NAMESPACE
  510. #ifndef _GLIBCXX_EXPORT_TEMPLATE
  511. # include <bits/sstream.tcc>
  512. #endif
  513. #endif /* _GLIBCXX_SSTREAM */