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