1 : // streambuf standard header
2 : #pragma once
3 : #ifndef _STREAMBUF_
4 : #define _STREAMBUF_
5 : #ifndef RC_INVOKED
6 : #include <xiosbase>
7 :
8 : #ifdef _MSC_VER
9 : #pragma pack(push,_CRT_PACKING)
10 : #pragma warning(push,3)
11 : #endif /* _MSC_VER */
12 : _STD_BEGIN
13 :
14 : // TEMPLATE CLASS basic_streambuf
15 : template<class _Elem,
16 : class _Traits>
17 : class basic_streambuf
18 : { // control read/write buffers
19 :
20 : basic_streambuf(const basic_streambuf<_Elem, _Traits>&); // not defined
21 : basic_streambuf<_Elem, _Traits>&
22 : operator=(const basic_streambuf<_Elem, _Traits>&); // not defined
23 :
24 :
25 : protected:
26 : basic_streambuf()
27 : : _Plocale(_NEW_CRT(locale))
28 10 : { // construct with no buffers
29 10 : _Init();
30 10 : }
31 :
32 : basic_streambuf(_Uninitialized)
33 : { // construct uninitialized
34 : }
35 :
36 : public:
37 : typedef basic_streambuf<_Elem, _Traits> _Myt;
38 : typedef _Elem char_type;
39 : typedef _Traits traits_type;
40 :
41 : virtual __CLR_OR_THIS_CALL ~basic_streambuf()
42 10 : { // destroy the object
43 10 : _DELETE_CRT(_Plocale);
44 10 : }
45 :
46 : typedef typename _Traits::int_type int_type;
47 : typedef typename _Traits::pos_type pos_type;
48 : typedef typename _Traits::off_type off_type;
49 :
50 : pos_type pubseekoff(off_type _Off, ios_base::seekdir _Way,
51 : ios_base::openmode _Mode = ios_base::in | ios_base::out)
52 : { // change position by _Off, according to _Way, _Mode
53 : return (seekoff(_Off, _Way, _Mode));
54 : }
55 :
56 : pos_type pubseekoff(off_type _Off, ios_base::seek_dir _Way,
57 : ios_base::open_mode _Mode)
58 : { // change position by _Off, according to _Way, _Mode (old style)
59 : return (pubseekoff(_Off, (ios_base::seekdir)_Way,
60 : (ios_base::openmode)_Mode));
61 : }
62 :
63 : pos_type pubseekpos(pos_type _Pos,
64 : ios_base::openmode _Mode = ios_base::in | ios_base::out)
65 : { // change position to _Pos, according to _Mode
66 : return (seekpos(_Pos, _Mode));
67 : }
68 :
69 : pos_type pubseekpos(pos_type _Pos, ios_base::open_mode _Mode)
70 : { // change position to _Pos, according to _Mode (old style)
71 : return (seekpos(_Pos, (ios_base::openmode)_Mode));
72 : }
73 :
74 : _Myt *pubsetbuf(_Elem *_Buffer, streamsize _Count)
75 : { // offer _Buffer to external agent
76 : return (setbuf(_Buffer, _Count));
77 : }
78 :
79 : locale pubimbue(const locale &_Newlocale)
80 : { // set locale to argument
81 : locale _Oldlocale = *_Plocale;
82 : imbue(_Newlocale);
83 : *_Plocale = _Newlocale;
84 : return (_Oldlocale);
85 : }
86 :
87 : locale getloc() const
88 : { // get locale
89 : return (*_Plocale);
90 : }
91 :
92 : streamsize in_avail()
93 : { // return count of buffered input characters
94 : streamsize _Res = _Gnavail();
95 : return (0 < _Res ? _Res : showmanyc());
96 : }
97 :
98 : int pubsync()
99 0 : { // synchronize with external agent
100 0 : return (sync());
101 0 : }
102 :
103 : int_type sbumpc()
104 : { // get a character and point past it
105 : return (0 < _Gnavail()
106 : ? _Traits::to_int_type(*_Gninc()) : uflow());
107 : }
108 :
109 : int_type sgetc()
110 : { // get a character and don't point past it
111 : return (0 < _Gnavail()
112 : ? _Traits::to_int_type(*gptr()) : underflow());
113 : }
114 :
115 : streamsize _Sgetn_s(_Elem *_Ptr, size_t _Ptr_size, streamsize _Count)
116 : { // get up to _Count characters into array beginning at _Ptr
117 : return _Xsgetn_s(_Ptr, _Ptr_size, _Count);
118 : }
119 :
120 : _SCL_INSECURE_DEPRECATE
121 : streamsize sgetn(_Elem *_Ptr, streamsize _Count)
122 : { // get up to _Count characters into array beginning at _Ptr
123 : #pragma warning(push)
124 : #pragma warning(disable:4996)
125 : return xsgetn(_Ptr, _Count);
126 : #pragma warning(pop)
127 : }
128 :
129 : int_type snextc()
130 : { // point to next character and return it
131 : return (1 < _Gnavail()
132 : ? _Traits::to_int_type(*_Gnpreinc())
133 : : _Traits::eq_int_type(_Traits::eof(), sbumpc())
134 : ? _Traits::eof() : sgetc());
135 : }
136 :
137 : int_type sputbackc(_Elem _Ch)
138 : { // put back _Ch
139 : return (gptr() != 0 && eback() < gptr()
140 : && _Traits::eq(_Ch, gptr()[-1])
141 : ? _Traits::to_int_type(*_Gndec())
142 : : pbackfail(_Traits::to_int_type(_Ch)));
143 : }
144 :
145 : void stossc()
146 : { // point past a character
147 : if (0 < _Gnavail())
148 : _Gninc();
149 : else
150 : uflow();
151 : }
152 :
153 : int_type sungetc()
154 : { // back up one position
155 : return (gptr() != 0 && eback() < gptr()
156 : ? _Traits::to_int_type(*_Gndec()) : pbackfail());
157 : }
158 :
159 : int_type sputc(_Elem _Ch)
160 10 : { // put a character
161 : return (0 < _Pnavail()
162 : ? _Traits::to_int_type(*_Pninc() = _Ch)
163 10 : : overflow(_Traits::to_int_type(_Ch)));
164 10 : }
165 :
166 : streamsize sputn(const _Elem *_Ptr, streamsize _Count)
167 9 : { // put _Count characters from array beginning at _Ptr
168 9 : return (xsputn(_Ptr, _Count));
169 9 : }
170 :
171 : void _Lock()
172 10 : { // set the thread lock
173 10 : _Mylock._Lock();
174 10 : }
175 :
176 : void _Unlock()
177 10 : { // clear the thread lock
178 10 : _Mylock._Unlock();
179 10 : }
180 :
181 :
182 : protected:
183 : _Elem *eback() const
184 10 : { // return beginning of read buffer
185 10 : return (*_IGfirst);
186 10 : }
187 :
188 : _Elem *gptr() const
189 9 : { // return current position in read buffer
190 9 : return (*_IGnext);
191 9 : }
192 :
193 : _Elem *pbase() const
194 10 : { // return beginning of write buffer
195 10 : return (*_IPfirst);
196 10 : }
197 :
198 : _Elem *pptr() const
199 10 : { // return current position in write buffer
200 10 : return (*_IPnext);
201 10 : }
202 :
203 : _Elem *egptr() const
204 0 : { // return end of read buffer
205 0 : return (*_IGnext + *_IGcount);
206 0 : }
207 :
208 : void gbump(int _Off)
209 0 : { // alter current position in read buffer by _Off
210 0 : *_IGcount -= _Off;
211 0 : *_IGnext += _Off;
212 0 : }
213 :
214 : void setg(_Elem *_First, _Elem *_Next, _Elem *_Last)
215 10 : { // set pointers for read buffer
216 10 : *_IGfirst = _First;
217 10 : *_IGnext = _Next;
218 10 : *_IGcount = (int)(_Last - _Next);
219 10 : }
220 :
221 : _Elem *epptr() const
222 10 : { // return end of write buffer
223 10 : return (*_IPnext + *_IPcount);
224 10 : }
225 :
226 : _Elem *_Gndec()
227 : { // decrement current position in read buffer
228 : ++*_IGcount;
229 : return (--*_IGnext);
230 : }
231 :
232 : _Elem *_Gninc()
233 0 : { // increment current position in read buffer
234 0 : --*_IGcount;
235 0 : return ((*_IGnext)++);
236 0 : }
237 :
238 : _Elem *_Gnpreinc()
239 : { // preincrement current position in read buffer
240 : --*_IGcount;
241 : return (++(*_IGnext));
242 : }
243 :
244 : streamsize _Gnavail() const
245 0 : { // count number of available elements in read buffer
246 0 : return (*_IGnext != 0 ? *_IGcount : 0);
247 0 : }
248 :
249 : void pbump(int _Off)
250 9 : { // alter current position in write buffer by _Off
251 9 : *_IPcount -= _Off;
252 9 : *_IPnext += _Off;
253 9 : }
254 :
255 : void setp(_Elem *_First, _Elem *_Last)
256 10 : { // set pointers for write buffer
257 10 : *_IPfirst = _First;
258 10 : *_IPnext = _First;
259 10 : *_IPcount = (int)(_Last - _First);
260 10 : }
261 :
262 : void setp(_Elem *_First, _Elem *_Next, _Elem *_Last)
263 9 : { // set pointers for write buffer, extended version
264 9 : *_IPfirst = _First;
265 9 : *_IPnext = _Next;
266 9 : *_IPcount = (int)(_Last - _Next);
267 9 : }
268 :
269 : _Elem *_Pninc()
270 10 : { // increment current position in write buffer
271 10 : --*_IPcount;
272 10 : return ((*_IPnext)++);
273 10 : }
274 :
275 : streamsize _Pnavail() const
276 10 : { // count number of available positions in write buffer
277 10 : return (*_IPnext != 0 ? *_IPcount : 0);
278 10 : }
279 :
280 : void _Init()
281 10 : { // initialize buffer parameters for no buffers
282 10 : _IGfirst = &_Gfirst, _IPfirst = &_Pfirst;
283 10 : _IGnext = &_Gnext, _IPnext = &_Pnext;
284 10 : _IGcount = &_Gcount, _IPcount = &_Pcount;
285 10 : setp(0, 0), setg(0, 0, 0);
286 10 : }
287 :
288 : void _Init(_Elem **_Gf, _Elem **_Gn, int *_Gc,
289 : _Elem **_Pf, _Elem **_Pn, int *_Pc)
290 : { // initialize buffer parameters as specified
291 : _IGfirst = _Gf, _IPfirst = _Pf;
292 : _IGnext = _Gn, _IPnext = _Pn;
293 : _IGcount = _Gc, _IPcount = _Pc;
294 : }
295 :
296 : virtual int_type __CLR_OR_THIS_CALL overflow(int_type = _Traits::eof())
297 0 : { // put a character to stream (always fail)
298 0 : return (_Traits::eof());
299 0 : }
300 :
301 : virtual int_type __CLR_OR_THIS_CALL pbackfail(int_type = _Traits::eof())
302 0 : { // put a character back to stream (always fail)
303 0 : return (_Traits::eof());
304 0 : }
305 :
306 : virtual streamsize __CLR_OR_THIS_CALL showmanyc()
307 0 : { // return count of input characters
308 0 : return (0);
309 0 : }
310 :
311 : virtual int_type __CLR_OR_THIS_CALL underflow()
312 0 : { // get a character from stream, but don't point past it
313 0 : return (_Traits::eof());
314 0 : }
315 :
316 : virtual int_type __CLR_OR_THIS_CALL uflow()
317 0 : { // get a character from stream, point past it
318 : return (_Traits::eq_int_type(_Traits::eof(), underflow())
319 0 : ? _Traits::eof() : _Traits::to_int_type(*_Gninc()));
320 0 : }
321 :
322 : _SCL_INSECURE_DEPRECATE
323 : virtual streamsize __CLR_OR_THIS_CALL xsgetn(_Elem * _Ptr,
324 : streamsize _Count)
325 0 : { // get _Count characters from stream
326 : // assume the destination buffer is large enough
327 0 : return _Xsgetn_s(_Ptr, (size_t)-1, _Count);
328 0 : }
329 :
330 : virtual streamsize __CLR_OR_THIS_CALL _Xsgetn_s(_Elem * _Ptr,
331 : size_t _Ptr_size, streamsize _Count)
332 0 : { // get _Count characters from stream
333 : int_type _Meta;
334 : streamsize _Stream_size, _Size, _Copied;
335 :
336 0 : for (_Copied = 0; 0 < _Count; )
337 0 : if (0 < (_Stream_size = _Gnavail()))
338 : { // copy from read buffer
339 0 : _Size = _Stream_size;
340 0 : if (_Count < _Size)
341 0 : _Size = _Count;
342 0 : _Traits_helper::copy_s<_Traits>(_Ptr, _Ptr_size, gptr(), _Size);
343 0 : _Ptr += _Size;
344 0 : _Copied += _Size;
345 0 : _Count -= _Size;
346 0 : gbump((int)_Size);
347 : }
348 0 : else if (_Traits::eq_int_type(_Traits::eof(), _Meta = uflow()))
349 0 : break; // end of file, quit
350 : else
351 : { // get a single character
352 0 : *_Ptr++ = _Traits::to_char_type(_Meta);
353 0 : ++_Copied;
354 0 : --_Count;
355 0 : }
356 :
357 0 : return (_Copied);
358 0 : }
359 :
360 : virtual streamsize __CLR_OR_THIS_CALL xsputn(const _Elem *_Ptr,
361 : streamsize _Count)
362 9 : { // put _Count characters to stream
363 : streamsize _Stream_size, _Size, _Copied;
364 :
365 9 : for (_Copied = 0; 0 < _Count; )
366 9 : if (0 < (_Stream_size = _Pnavail()))
367 : { // copy to write buffer
368 9 : _Size = _Stream_size;
369 9 : if (_Count < _Size)
370 9 : _Size = _Count;
371 9 : _Traits_helper::copy_s<_Traits>(pptr(), _Stream_size, _Ptr, _Size);
372 9 : _Ptr += _Size;
373 9 : _Copied += _Size;
374 9 : _Count -= _Size;
375 9 : pbump((int)_Size);
376 : }
377 9 : else if (_Traits::eq_int_type(_Traits::eof(),
378 9 : overflow(_Traits::to_int_type(*_Ptr))))
379 0 : break; // single character put failed, quit
380 : else
381 : { // count character successfully put
382 9 : ++_Ptr;
383 9 : ++_Copied;
384 9 : --_Count;
385 9 : }
386 :
387 9 : return (_Copied);
388 9 : }
389 :
390 : virtual pos_type __CLR_OR_THIS_CALL seekoff(off_type, ios_base::seekdir,
391 : ios_base::openmode = ios_base::in | ios_base::out)
392 0 : { // change position by offset, according to way and mode
393 0 : return (streampos(_BADOFF));
394 0 : }
395 :
396 : virtual pos_type __CLR_OR_THIS_CALL seekpos(pos_type,
397 : ios_base::openmode = ios_base::in | ios_base::out)
398 0 : { // change to specified position, according to mode
399 0 : return (streampos(_BADOFF));
400 0 : }
401 :
402 : virtual _Myt *__CLR_OR_THIS_CALL setbuf(_Elem *, streamsize)
403 0 : { // offer buffer to external agent (do nothing)
404 0 : return (this);
405 0 : }
406 :
407 : virtual int __CLR_OR_THIS_CALL sync()
408 0 : { // synchronize with external agent (do nothing)
409 0 : return (0);
410 0 : }
411 :
412 : virtual void __CLR_OR_THIS_CALL imbue(const locale&)
413 0 : { // set locale to argument (do nothing)
414 0 : }
415 :
416 : private:
417 : _Mutex _Mylock; // thread lock
418 : _Elem *_Gfirst; // beginning of read buffer
419 : _Elem *_Pfirst; // beginning of write buffer
420 : _Elem **_IGfirst; // pointer to beginning of read buffer
421 : _Elem **_IPfirst; // pointer to beginning of write buffer
422 : _Elem *_Gnext; // current position in read buffer
423 : _Elem *_Pnext; // current position in write buffer
424 : _Elem **_IGnext; // pointer to current position in read buffer
425 : _Elem **_IPnext; // pointer to current position in write buffer
426 : int _Gcount; // length of read buffer
427 : int _Pcount; // length of write buffer
428 : int *_IGcount; // pointer to length of read buffer
429 : int *_IPcount; // pointer to length of write buffer
430 : locale *_Plocale; // pointer to imbued locale object
431 : };
432 :
433 : #if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)
434 :
435 : template class _CRTIMP2 basic_streambuf<char, char_traits<char> >;
436 : template class _CRTIMP2 basic_streambuf<wchar_t, char_traits<wchar_t> >;
437 :
438 :
439 :
440 : #endif /* _DLL_CPPLIB */
441 :
442 : // TEMPLATE CLASS istreambuf_iterator
443 : template<class _Elem,
444 : class _Traits>
445 : class istreambuf_iterator
446 : : public iterator<input_iterator_tag,
447 : _Elem, typename _Traits::off_type, _Elem *, _Elem&>
448 : { // wrap stream buffer as input iterator
449 : typedef istreambuf_iterator<_Elem, _Traits> _Myt;
450 : public:
451 : typedef _Elem char_type;
452 : typedef _Traits traits_type;
453 : typedef basic_streambuf<_Elem, _Traits> streambuf_type;
454 : typedef basic_istream<_Elem, _Traits> istream_type;
455 :
456 : typedef typename traits_type::int_type int_type;
457 :
458 : #if _SECURE_SCL
459 : typedef _Range_checked_iterator_tag _Checked_iterator_category;
460 : #endif
461 :
462 : istreambuf_iterator(streambuf_type *_Sb = 0) _THROW0()
463 : : _Strbuf(_Sb), _Got(_Sb == 0)
464 : { // construct from stream buffer _Sb
465 : }
466 :
467 : istreambuf_iterator(istream_type& _Istr) _THROW0()
468 : : _Strbuf(_Istr.rdbuf()), _Got(_Istr.rdbuf() == 0)
469 : { // construct from stream buffer in istream _Istr
470 : }
471 :
472 : _Elem operator*() const
473 : { // return designated value
474 : if (!_Got)
475 : ((_Myt *)this)->_Peek();
476 :
477 : #if _HAS_ITERATOR_DEBUGGING
478 : if (_Strbuf == 0)
479 : _DEBUG_ERROR("istreambuf_iterator is not dereferencable");
480 : #endif /* _HAS_ITERATOR_DEBUGGING */
481 :
482 : return (_Val);
483 : }
484 :
485 : _Myt& operator++()
486 : { // preincrement
487 :
488 : #if _HAS_ITERATOR_DEBUGGING
489 : if (_Strbuf == 0)
490 : _DEBUG_ERROR("istreambuf_iterator is not incrementable");
491 : #endif /* _HAS_ITERATOR_DEBUGGING */
492 :
493 : _Inc();
494 : return (*this);
495 : }
496 :
497 : _Myt operator++(int)
498 : { // postincrement
499 : if (!_Got)
500 : _Peek();
501 : _Myt _Tmp = *this;
502 : ++*this;
503 : return (_Tmp);
504 : }
505 :
506 : bool equal(const _Myt& _Right) const
507 : { // test for equality
508 : if (!_Got)
509 : ((_Myt *)this)->_Peek();
510 : if (!_Right._Got)
511 : ((_Myt *)&_Right)->_Peek();
512 : return (_Strbuf == 0 && _Right._Strbuf == 0
513 : || _Strbuf != 0 && _Right._Strbuf != 0);
514 : }
515 :
516 : private:
517 : void _Inc()
518 : { // skip to next input element
519 : if (_Strbuf == 0
520 : || traits_type::eq_int_type(traits_type::eof(),
521 : _Strbuf->sbumpc()))
522 : _Strbuf = 0, _Got = true;
523 : else
524 : _Got = false;
525 : }
526 :
527 : _Elem _Peek()
528 : { // peek at next input element
529 : int_type _Meta;
530 : if (_Strbuf == 0
531 : || traits_type::eq_int_type(traits_type::eof(),
532 : _Meta = _Strbuf->sgetc()))
533 : _Strbuf = 0;
534 : else
535 : _Val = traits_type::to_char_type(_Meta);
536 : _Got = true;
537 : return (_Val);
538 : }
539 :
540 : streambuf_type *_Strbuf; // the wrapped stream buffer
541 : bool _Got; // true if _Val is valid
542 : _Elem _Val; // next element to deliver
543 : };
544 :
545 : // istreambuf_iterator TEMPLATE OPERATORS
546 : template<class _Elem,
547 : class _Traits> inline
548 : bool __CLR_OR_THIS_CALL operator==(
549 : const istreambuf_iterator<_Elem, _Traits>& _Left,
550 : const istreambuf_iterator<_Elem, _Traits>& _Right)
551 : { // test for istreambuf_iterator equality
552 : return (_Left.equal(_Right));
553 : }
554 :
555 : template<class _Elem,
556 : class _Traits> inline
557 : bool __CLR_OR_THIS_CALL operator!=(
558 : const istreambuf_iterator<_Elem, _Traits>& _Left,
559 : const istreambuf_iterator<_Elem, _Traits>& _Right)
560 : { // test for istreambuf_iterator inequality
561 : return (!(_Left == _Right));
562 : }
563 :
564 : // TEMPLATE CLASS ostreambuf_iterator
565 : template<class _Elem,
566 : class _Traits>
567 : class ostreambuf_iterator
568 : : public _Outit
569 : { // wrap stream buffer as output iterator
570 : typedef ostreambuf_iterator<_Elem, _Traits> _Myt;
571 : public:
572 : typedef _Elem char_type;
573 : typedef _Traits traits_type;
574 : typedef basic_streambuf<_Elem, _Traits> streambuf_type;
575 : typedef basic_ostream<_Elem, _Traits> ostream_type;
576 :
577 : #if _SECURE_SCL
578 : typedef _Range_checked_iterator_tag _Checked_iterator_category;
579 : #endif
580 :
581 : ostreambuf_iterator(streambuf_type *_Sb) _THROW0()
582 : : _Failed(false), _Strbuf(_Sb)
583 9 : { // construct from stream buffer _Sb
584 9 : }
585 :
586 : ostreambuf_iterator(ostream_type& _Ostr) _THROW0()
587 : : _Failed(false), _Strbuf(_Ostr.rdbuf())
588 : { // construct from stream buffer in _Ostr
589 : }
590 :
591 : _Myt& operator=(_Elem _Right)
592 9 : { // store element and increment
593 : if (_Strbuf == 0
594 : || traits_type::eq_int_type(_Traits::eof(),
595 9 : _Strbuf->sputc(_Right)))
596 0 : _Failed = true;
597 9 : return (*this);
598 9 : }
599 :
600 : _Myt& operator*()
601 9 : { // pretend to get designated element
602 9 : return (*this);
603 9 : }
604 :
605 : _Myt& operator++()
606 9 : { // pretend to preincrement
607 9 : return (*this);
608 9 : }
609 :
610 : _Myt& operator++(int)
611 : { // pretend to postincrement
612 : return (*this);
613 : }
614 :
615 : bool failed() const _THROW0()
616 9 : { // return true if any stores failed
617 9 : return (_Failed);
618 9 : }
619 :
620 : private:
621 : bool _Failed; // true if any stores have failed
622 : streambuf_type *_Strbuf; // the wrapped stream buffer
623 : };
624 : _STD_END
625 : #ifdef _MSC_VER
626 : #pragma warning(pop)
627 : #pragma pack(pop)
628 : #endif /* _MSC_VER */
629 :
630 : #endif /* RC_INVOKED */
631 : #endif /* _STREAMBUF_ */
632 :
633 : /*
634 : * Copyright (c) 1992-2007 by P.J. Plauger. ALL RIGHTS RESERVED.
635 : * Consult your license regarding permissions and restrictions.
636 : V5.03:0009 */
|