1 : // sstream standard header
2 : #pragma once
3 : #ifndef _SSTREAM_
4 : #define _SSTREAM_
5 : #ifndef RC_INVOKED
6 : #include <string>
7 :
8 : #ifdef _MSC_VER
9 : #pragma pack(push,_CRT_PACKING)
10 : #pragma warning(push,3)
11 : #endif /* _MSC_VER */
12 :
13 : _STD_BEGIN
14 :
15 : #pragma warning(disable:4251)
16 :
17 : // TEMPLATE CLASS basic_stringbuf
18 : template<class _Elem,
19 : class _Traits,
20 : class _Alloc>
21 : class basic_stringbuf
22 : : public basic_streambuf<_Elem, _Traits>
23 : { // stream buffer maintaining an allocated character array
24 : public:
25 : typedef _Alloc allocator_type;
26 : typedef basic_streambuf<_Elem, _Traits> _Mysb;
27 : typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
28 :
29 10 : explicit __CLR_OR_THIS_CALL basic_stringbuf(ios_base::openmode _Mode =
30 : ios_base::in | ios_base::out)
31 : { // construct empty character buffer from mode
32 10 : _Init(0, 0, _Getstate(_Mode));
33 10 : }
34 :
35 : explicit __CLR_OR_THIS_CALL basic_stringbuf(const _Mystr& _Str,
36 : ios_base::openmode _Mode = ios_base::in | ios_base::out)
37 : { // construct character buffer from string, mode
38 : _Init(_Str.c_str(), _Str.size(), _Getstate(_Mode));
39 : }
40 :
41 : virtual __CLR_OR_THIS_CALL ~basic_stringbuf()
42 10 : { // destroy the object
43 10 : _Tidy();
44 10 : }
45 :
46 : enum
47 : { // constants for bits in stream state
48 : _Allocated = 1, // set if character array storage has been allocated
49 : _Constant = 2, // set if character array nonmutable
50 : _Noread = 4, // set if character array cannot be read
51 : _Append = 8, // set if all writes are appends
52 : _Atend = 16}; // set if initial writes are appends
53 : typedef int _Strstate;
54 :
55 : typedef typename _Traits::int_type int_type;
56 : typedef typename _Traits::pos_type pos_type;
57 : typedef typename _Traits::off_type off_type;
58 :
59 : _Mystr __CLR_OR_THIS_CALL str() const
60 10 : { // return string copy of character array
61 10 : if (!(_Mystate & _Constant) && _Mysb::pptr() != 0)
62 : { // writable, make string from write buffer
63 : _Mystr _Str(_Mysb::pbase(), (_Seekhigh < _Mysb::pptr()
64 10 : ? _Mysb::pptr() : _Seekhigh) - _Mysb::pbase());
65 10 : return (_Str);
66 : }
67 3 : else if (!(_Mystate & _Noread) && _Mysb::gptr() != 0)
68 : { // readable, make string from read buffer
69 0 : _Mystr _Str(_Mysb::eback(), _Mysb::egptr() - _Mysb::eback());
70 0 : return (_Str);
71 : }
72 : else
73 : { // inaccessible, return empty string
74 3 : _Mystr _Nul;
75 3 : return (_Nul);
76 : }
77 10 : }
78 :
79 : void __CLR_OR_THIS_CALL str(const _Mystr& _Newstr)
80 : { // replace character array from string
81 : _Tidy();
82 : _Init(_Newstr.c_str(), _Newstr.size(), _Mystate);
83 : }
84 :
85 : protected:
86 : virtual int_type __CLR_OR_THIS_CALL overflow(int_type _Meta = _Traits::eof())
87 10 : { // put an element to stream
88 : if (_Mystate & _Append
89 10 : && _Mysb::pptr() != 0 && _Mysb::pptr() < _Seekhigh)
90 0 : _Mysb::setp(_Mysb::pbase(), _Seekhigh, _Mysb::epptr());
91 :
92 10 : if (_Traits::eq_int_type(_Traits::eof(), _Meta))
93 0 : return (_Traits::not_eof(_Meta)); // EOF, return success code
94 : else if (_Mysb::pptr() != 0
95 10 : && _Mysb::pptr() < _Mysb::epptr())
96 : { // room in buffer, store it
97 0 : *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
98 0 : return (_Meta);
99 : }
100 10 : else if (_Mystate & _Constant)
101 0 : return (_Traits::eof()); // array nonmutable, fail
102 : else
103 : { // grow buffer and store element
104 : size_t _Oldsize = _Mysb::pptr() == 0
105 10 : ? 0 : _Mysb::epptr() - _Mysb::eback();
106 10 : size_t _Newsize = _Oldsize;
107 : size_t _Inc = _Newsize / 2 < _MINSIZE
108 10 : ? _MINSIZE : _Newsize / 2; // grow by 50 per cent
109 :
110 10 : while (0 < _Inc && INT_MAX - _Inc < _Newsize)
111 0 : _Inc /= 2; // increment causes overflow, halve it
112 10 : if (_Inc == 0)
113 0 : return (_Traits::eof()); // buffer can't grow, fail
114 :
115 10 : _Newsize += _Inc;
116 :
117 10 : _Elem *_Newptr = _Al.allocate(_Newsize);
118 10 : _Elem *_Oldptr = _Mysb::eback();
119 :
120 10 : if (0 < _Oldsize)
121 9 : _Traits_helper::copy_s<_Traits>(_Newptr, _Newsize, _Oldptr, _Oldsize);
122 :
123 10 : if (_Oldsize == 0)
124 : { // first growth, set up pointers
125 10 : _Seekhigh = _Newptr;
126 10 : _Mysb::setp(_Newptr, _Newptr + _Newsize);
127 10 : if (_Mystate & _Noread)
128 0 : _Mysb::setg(_Newptr, 0, _Newptr);
129 0 : else
130 10 : _Mysb::setg(_Newptr, _Newptr, _Newptr + 1);
131 : }
132 10 : else
133 : { // not first growth, adjust pointers
134 9 : _Seekhigh = _Newptr + (_Seekhigh - _Oldptr);
135 : _Mysb::setp(_Newptr + (_Mysb::pbase() - _Oldptr),
136 : _Newptr + (_Mysb::pptr() - _Oldptr),
137 9 : _Newptr + _Newsize);
138 9 : if (_Mystate & _Noread)
139 0 : _Mysb::setg(_Newptr, 0, _Newptr);
140 0 : else
141 : _Mysb::setg(_Newptr,
142 : _Newptr + (_Mysb::gptr() - _Oldptr),
143 9 : _Mysb::pptr() + 1);
144 : }
145 :
146 10 : if (_Mystate & _Allocated)
147 9 : _Al.deallocate(_Oldptr, _Oldsize);
148 10 : _Mystate |= _Allocated;
149 :
150 10 : *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
151 10 : return (_Meta);
152 : }
153 10 : }
154 :
155 : virtual int_type __CLR_OR_THIS_CALL pbackfail(int_type _Meta = _Traits::eof())
156 0 : { // put an element back to stream
157 : if (_Mysb::gptr() == 0
158 : || _Mysb::gptr() <= _Mysb::eback()
159 : || !_Traits::eq_int_type(_Traits::eof(), _Meta)
160 : && !_Traits::eq(_Traits::to_char_type(_Meta), _Mysb::gptr()[-1])
161 0 : && _Mystate & _Constant)
162 0 : return (_Traits::eof()); // can't put back, fail
163 : else
164 : { // back up one position and store put-back character
165 0 : _Mysb::gbump(-1);
166 0 : if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
167 0 : *_Mysb::gptr() = _Traits::to_char_type(_Meta);
168 0 : return (_Traits::not_eof(_Meta));
169 : }
170 0 : }
171 :
172 : virtual int_type __CLR_OR_THIS_CALL underflow()
173 0 : { // get an element from stream, but don't point past it
174 0 : if (_Mysb::gptr() == 0)
175 0 : return (_Traits::eof()); // no character buffer, fail
176 0 : else if (_Mysb::gptr() < _Mysb::egptr())
177 0 : return (_Traits::to_int_type(*_Mysb::gptr())); // return buffered
178 : else if (_Mystate & _Noread || _Mysb::pptr() == 0
179 0 : || _Mysb::pptr() <= _Mysb::gptr() && _Seekhigh <= _Mysb::gptr())
180 0 : return (_Traits::eof()); // can't read, fail
181 : else
182 : { // extend read buffer into written area, then return buffered
183 0 : if (_Seekhigh < _Mysb::pptr())
184 0 : _Seekhigh = _Mysb::pptr();
185 0 : _Mysb::setg(_Mysb::eback(), _Mysb::gptr(), _Seekhigh);
186 0 : return (_Traits::to_int_type(*_Mysb::gptr()));
187 : }
188 0 : }
189 :
190 : virtual pos_type __CLR_OR_THIS_CALL seekoff(off_type _Off,
191 : ios_base::seekdir _Way,
192 : ios_base::openmode _Which = ios_base::in | ios_base::out)
193 0 : { // change position by _Off, according to _Way, _Mode
194 0 : if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
195 0 : _Seekhigh = _Mysb::pptr(); // update high-water pointer
196 :
197 0 : if (_Which & ios_base::in && _Mysb::gptr() != 0)
198 : { // position within read buffer
199 0 : if (_Way == ios_base::end)
200 0 : _Off += (off_type)(_Seekhigh - _Mysb::eback());
201 0 : else if (_Way == ios_base::cur
202 0 : && (_Which & ios_base::out) == 0)
203 0 : _Off += (off_type)(_Mysb::gptr() - _Mysb::eback());
204 0 : else if (_Way != ios_base::beg)
205 0 : _Off = _BADOFF;
206 :
207 0 : if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
208 : { // change read position
209 0 : _Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
210 0 : if (_Which & ios_base::out && _Mysb::pptr() != 0)
211 : _Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
212 0 : _Mysb::epptr()); // change write position to match
213 : }
214 0 : else
215 0 : _Off = _BADOFF;
216 : }
217 0 : else if (_Which & ios_base::out && _Mysb::pptr() != 0)
218 : { // position within write buffer
219 0 : if (_Way == ios_base::end)
220 0 : _Off += (off_type)(_Seekhigh - _Mysb::eback());
221 0 : else if (_Way == ios_base::cur)
222 0 : _Off += (off_type)(_Mysb::pptr() - _Mysb::eback());
223 0 : else if (_Way != ios_base::beg)
224 0 : _Off = _BADOFF;
225 :
226 0 : if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
227 : _Mysb::pbump((int)(_Mysb::eback()
228 0 : - _Mysb::pptr() + _Off)); // change write position
229 0 : else
230 0 : _Off = _BADOFF;
231 : }
232 0 : else
233 0 : _Off = _BADOFF; // neither read nor write buffer selected, fail
234 0 : return (pos_type(_Off));
235 0 : }
236 :
237 : virtual pos_type __CLR_OR_THIS_CALL seekpos(pos_type _Ptr,
238 : ios_base::openmode _Mode = ios_base::in | ios_base::out)
239 0 : { // change position to _Pos, according to _Mode
240 0 : streamoff _Off = (streamoff)_Ptr;
241 0 : if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
242 0 : _Seekhigh = _Mysb::pptr(); // update high-water pointer
243 :
244 0 : if (_Off == _BADOFF)
245 : ;
246 0 : else if (_Mode & ios_base::in && _Mysb::gptr() != 0)
247 : { // position within read buffer
248 0 : if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
249 : { // change read position
250 0 : _Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
251 0 : if (_Mode & ios_base::out && _Mysb::pptr() != 0)
252 : _Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
253 0 : _Mysb::epptr()); // change write position to match
254 : }
255 0 : else
256 0 : _Off = _BADOFF;
257 : }
258 0 : else if (_Mode & ios_base::out && _Mysb::pptr() != 0)
259 : { // position within write buffer
260 0 : if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
261 : _Mysb::pbump((int)(_Mysb::eback()
262 0 : - _Mysb::pptr() + _Off)); // change write position
263 0 : else
264 0 : _Off = _BADOFF;
265 : }
266 0 : else
267 0 : _Off = _BADOFF;
268 0 : return (streampos(_Off));
269 0 : }
270 :
271 : void __CLR_OR_THIS_CALL _Init(const _Elem *_Ptr,
272 : size_t _Count, _Strstate _State)
273 10 : { // initialize buffer to [_Ptr, _Ptr + _Count), set state
274 10 : _Seekhigh = 0;
275 10 : _Mystate = _State;
276 :
277 : if (_Count != 0
278 10 : && (_Mystate & (_Noread | _Constant)) != (_Noread | _Constant))
279 : { // finite buffer that can be read or written, set it up
280 0 : _Elem *_Pnew = _Al.allocate(_Count);
281 0 : _Traits_helper::copy_s<_Traits>(_Pnew, _Count, _Ptr, _Count);
282 0 : _Seekhigh = _Pnew + _Count;
283 :
284 0 : if (!(_Mystate & _Noread))
285 : _Mysb::setg(_Pnew, _Pnew,
286 0 : _Pnew + _Count); // setup read buffer
287 0 : if (!(_Mystate & _Constant))
288 : { // setup write buffer, and maybe read buffer
289 : _Mysb::setp(_Pnew,
290 : (_Mystate & _Atend) ? _Pnew + _Count : _Pnew,
291 0 : _Pnew + _Count);
292 0 : if (_Mysb::gptr() == 0)
293 0 : _Mysb::setg(_Pnew, 0, _Pnew);
294 : }
295 0 : _Mystate |= _Allocated;
296 : }
297 10 : }
298 :
299 : void __CLR_OR_THIS_CALL _Tidy()
300 10 : { // discard any allocated buffer and clear pointers
301 10 : if (_Mystate & _Allocated)
302 : _Al.deallocate(_Mysb::eback(),
303 : (_Mysb::pptr() != 0 ? _Mysb::epptr()
304 10 : : _Mysb::egptr()) - _Mysb::eback());
305 10 : _Mysb::setg(0, 0, 0);
306 10 : _Mysb::setp(0, 0);
307 10 : _Seekhigh = 0;
308 10 : _Mystate &= ~_Allocated;
309 10 : }
310 :
311 : private:
312 : enum
313 : { // constant for minimum buffer size
314 : _MINSIZE = 32};
315 :
316 : _Strstate __CLR_OR_THIS_CALL _Getstate(ios_base::openmode _Mode)
317 10 : { // convert open mode to stream state bits
318 10 : _Strstate _State = (_Strstate)0;
319 10 : if (!(_Mode & ios_base::in))
320 0 : _State |= _Noread;
321 10 : if (!(_Mode & ios_base::out))
322 0 : _State |= _Constant;
323 10 : if (_Mode & ios_base::app)
324 0 : _State |= _Append;
325 10 : if (_Mode & ios_base::ate)
326 0 : _State |= _Atend;
327 10 : return (_State);
328 10 : }
329 :
330 : _Elem *_Seekhigh; // the high-water pointer in character array
331 : _Strstate _Mystate; // the stream state
332 : allocator_type _Al; // the allocator object
333 : };
334 :
335 : #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
336 :
337 : template class _CRTIMP2_PURE basic_stringbuf<char,
338 : char_traits<char>, allocator<char> >;
339 : template class _CRTIMP2_PURE basic_stringbuf<wchar_t,
340 : char_traits<wchar_t>, allocator<wchar_t> >;
341 :
342 :
343 :
344 : #endif /* _DLL_CPPLIB */
345 :
346 : // TEMPLATE CLASS basic_istringstream
347 : template<class _Elem,
348 : class _Traits,
349 : class _Alloc>
350 : class basic_istringstream
351 : : public basic_istream<_Elem, _Traits>
352 : { // input stream associated with a character array
353 : public:
354 : typedef _Alloc allocator_type;
355 : typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
356 : typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
357 :
358 : explicit __CLR_OR_THIS_CALL basic_istringstream(ios_base::openmode _Mode = ios_base::in)
359 : : basic_istream<_Elem, _Traits>(&_Stringbuffer),
360 : _Stringbuffer(_Mode | ios_base::in)
361 : { // construct empty readable character buffer
362 : }
363 :
364 : explicit __CLR_OR_THIS_CALL basic_istringstream(const _Mystr& _Str,
365 : ios_base::openmode _Mode = ios_base::in)
366 : : basic_istream<_Elem, _Traits>(&_Stringbuffer),
367 : _Stringbuffer(_Str, _Mode | ios_base::in)
368 : { // construct readable character buffer from NTCS
369 : }
370 :
371 : virtual __CLR_OR_THIS_CALL ~basic_istringstream()
372 : { // destroy the object
373 : }
374 :
375 : _Mysb *__CLR_OR_THIS_CALL rdbuf() const
376 : { // return pointer to file buffer
377 : return ((_Mysb *)&_Stringbuffer);
378 : }
379 :
380 : _Mystr __CLR_OR_THIS_CALL str() const
381 : { // return string copy of character array
382 : return (_Stringbuffer.str());
383 : }
384 :
385 : void __CLR_OR_THIS_CALL str(const _Mystr& _Newstr)
386 : { // replace character array from string
387 : _Stringbuffer.str(_Newstr);
388 : }
389 :
390 : private:
391 : _Mysb _Stringbuffer; // the string buffer
392 : };
393 :
394 : #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
395 :
396 : template class _CRTIMP2_PURE basic_istringstream<char,
397 : char_traits<char>, allocator<char> >;
398 : template class _CRTIMP2_PURE basic_istringstream<wchar_t,
399 : char_traits<wchar_t>, allocator<wchar_t> >;
400 :
401 :
402 :
403 : #endif /* _DLL_CPPLIB */
404 :
405 : // TEMPLATE CLASS basic_ostringstream
406 : template<class _Elem,
407 : class _Traits,
408 : class _Alloc>
409 : class basic_ostringstream
410 : : public basic_ostream<_Elem, _Traits>
411 : { // output stream associated with a character array
412 : public:
413 : typedef _Alloc allocator_type;
414 : typedef basic_stringbuf<_Elem, _Traits, _Alloc> _Mysb;
415 : typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
416 :
417 : explicit __CLR_OR_THIS_CALL basic_ostringstream(ios_base::openmode _Mode = ios_base::out)
418 : : basic_ostream<_Elem, _Traits>(&_Stringbuffer),
419 : _Stringbuffer(_Mode | ios_base::out)
420 : { // construct empty writable character buffer
421 : }
422 :
423 : explicit __CLR_OR_THIS_CALL basic_ostringstream(const _Mystr& _Str,
424 : ios_base::openmode _Mode = ios_base::out)
425 : : basic_ostream<_Elem, _Traits>(&_Stringbuffer),
426 : _Stringbuffer(_Str, _Mode | ios_base::out)
427 : { // construct writable character buffer from NTCS
428 : }
429 :
430 : virtual __CLR_OR_THIS_CALL ~basic_ostringstream()
431 : { // destroy the object
432 : }
433 :
434 : _Mysb *__CLR_OR_THIS_CALL rdbuf() const
435 : { // return pointer to buffer
436 : return ((_Mysb *)&_Stringbuffer);
437 : }
438 :
439 : _Mystr __CLR_OR_THIS_CALL str() const
440 : { // return string copy of character array
441 : return (_Stringbuffer.str());
442 : }
443 :
444 : void __CLR_OR_THIS_CALL str(const _Mystr& _Newstr)
445 : { // replace character array from string
446 : _Stringbuffer.str(_Newstr);
447 : }
448 :
449 : private:
450 : _Mysb _Stringbuffer; // the string buffer
451 : };
452 :
453 : #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
454 :
455 : template class _CRTIMP2_PURE basic_ostringstream<char,
456 : char_traits<char>, allocator<char> >;
457 : template class _CRTIMP2_PURE basic_ostringstream<wchar_t,
458 : char_traits<wchar_t>, allocator<wchar_t> >;
459 :
460 :
461 :
462 : #endif /* _DLL_CPPLIB */
463 :
464 : // TEMPLATE CLASS basic_stringstream
465 : template<class _Elem,
466 : class _Traits,
467 : class _Alloc>
468 : class basic_stringstream
469 : : public basic_iostream<_Elem, _Traits>
470 : { // input/output stream associated with a character array
471 : public:
472 : typedef _Elem char_type;
473 : typedef _Traits traits_type;
474 : typedef _Alloc allocator_type;
475 : typedef typename _Traits::int_type int_type;
476 : typedef typename _Traits::pos_type pos_type;
477 : typedef typename _Traits::off_type off_type;
478 : typedef basic_string<_Elem, _Traits, _Alloc> _Mystr;
479 :
480 : explicit __CLR_OR_THIS_CALL basic_stringstream(ios_base::openmode _Mode =
481 : ios_base::in | ios_base::out)
482 : : basic_iostream<_Elem, _Traits>(&_Stringbuffer),
483 : _Stringbuffer(_Mode)
484 10 : { // construct empty character buffer
485 10 : }
486 :
487 : explicit __CLR_OR_THIS_CALL basic_stringstream(const _Mystr& _Str,
488 : ios_base::openmode _Mode = ios_base::in | ios_base::out)
489 : : basic_iostream<_Elem, _Traits>(&_Stringbuffer),
490 : _Stringbuffer(_Str, _Mode)
491 : { // construct character buffer from NTCS
492 : }
493 :
494 : virtual __CLR_OR_THIS_CALL ~basic_stringstream()
495 10 : { // destroy the object
496 10 : }
497 :
498 : basic_stringbuf<_Elem, _Traits, _Alloc> *__CLR_OR_THIS_CALL rdbuf() const
499 : { // return pointer to buffer
500 : return ((basic_stringbuf<_Elem, _Traits, _Alloc> *)&_Stringbuffer);
501 : }
502 :
503 : _Mystr __CLR_OR_THIS_CALL str() const
504 10 : { // return string copy of character array
505 10 : return (_Stringbuffer.str());
506 10 : }
507 :
508 : void __CLR_OR_THIS_CALL str(const _Mystr& _Newstr)
509 : { // replace character array from string
510 : _Stringbuffer.str(_Newstr);
511 : }
512 :
513 : private:
514 : basic_stringbuf<_Elem, _Traits, _Alloc>
515 : _Stringbuffer; // the string buffer
516 : };
517 :
518 : #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
519 :
520 : template class _CRTIMP2_PURE basic_stringstream<char,
521 : char_traits<char>, allocator<char> >;
522 : template class _CRTIMP2_PURE basic_stringstream<wchar_t,
523 : char_traits<wchar_t>, allocator<wchar_t> >;
524 :
525 :
526 :
527 : #endif /* _DLL_CPPLIB */
528 : _STD_END
529 :
530 : #ifdef _MSC_VER
531 : #pragma warning(pop)
532 : #pragma pack(pop)
533 : #endif /* _MSC_VER */
534 :
535 : #endif /* RC_INVOKED */
536 : #endif /* _SSTREAM_ */
537 :
538 : /*
539 : * Copyright (c) 1992-2008 by P.J. Plauger. ALL RIGHTS RESERVED.
540 : * Consult your license regarding permissions and restrictions.
541 : V5.05:0009 */
542 :
543 :
|