home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / strstrea.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  6KB  |  251 lines

  1. // strstreambuf -- strstreambuf basic members
  2. #include <climits>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <locale>
  6. #include <strstream>
  7. _STD_BEGIN
  8.  
  9. _CRTIMP2 istrstream::~istrstream()
  10.     {    // destruct an istrstream
  11.     }
  12.  
  13. _CRTIMP2 ostrstream::ostrstream(char *s, streamsize n, openmode mode)
  14.     : ostream(&_Sb),
  15.     _Sb(s, n, s == 0 || (mode & app) == 0 ? s : s + strlen(s))
  16.     {    // write at terminating null (if there)
  17.     }
  18.  
  19. _CRTIMP2 ostrstream::~ostrstream()
  20.     {    // destruct an ostrstream
  21.     }
  22.  
  23. _CRTIMP2 strstream::strstream(char *s, streamsize n, openmode mode)
  24.     : iostream(&_Sb),
  25.     _Sb(s, n, s == 0 || (mode & app) == 0 ? s : s + strlen(s))
  26.     {    // write at terminating null (if there)
  27.     }
  28.  
  29. _CRTIMP2 strstream::~strstream()
  30.     {    // destruct a strstream
  31.     }
  32.  
  33. _CRTIMP2 strstreambuf::~strstreambuf()
  34.     {    // destruct a strstreambuf
  35.     _Tidy();
  36.     }
  37.  
  38. _CRTIMP2 void strstreambuf::freeze(bool freezeit)
  39.     {    // freeze a dynamic string
  40.     if (freezeit && !(_Strmode & _Frozen))
  41.         {    // disable writing
  42.         _Strmode |= _Frozen;
  43.         _Pendsave = epptr();
  44.         setp(pbase(), pptr(), eback());
  45.         }
  46.     else if (!freezeit && _Strmode & _Frozen)
  47.         {    // re-enable writing
  48.         _Strmode &= ~_Frozen;
  49.         setp(pbase(), pptr(), _Pendsave);
  50.         }
  51.     }
  52.  
  53. _CRTIMP2 int strstreambuf::overflow(int ch)
  54.     {    // try to extend write area
  55.     if (ch == EOF)
  56.         return (0);
  57.     else if (pptr() != 0 && pptr() < epptr())
  58.         return ((unsigned char)(*_Pninc() = (char)ch));
  59.     else if (!(_Strmode & _Dynamic)
  60.         || _Strmode & (_Constant | _Frozen))
  61.         return (EOF);
  62.     else
  63.         {    // okay to extend
  64.         int osize = gptr() == 0 ? 0 : epptr() - eback();
  65.         int nsize = osize + _Alsize;
  66.         char *p = _Palloc != 0 ? (char *)(*_Palloc)(nsize)
  67.             : new char[nsize];
  68.         if (p == 0)
  69.             return (EOF);
  70.         if (0 < osize)
  71.             memcpy(p, eback(), osize);
  72.         else if (_ALSIZE < _Alsize)
  73.             _Alsize = _ALSIZE;
  74.         if (!(_Strmode & _Allocated))
  75.             ;
  76.         else if (_Pfree != 0)
  77.             (*_Pfree)(eback());
  78.         else
  79.             delete[] eback();
  80.         _Strmode |= _Allocated;
  81.         if (osize == 0)
  82.             {    // setup new buffer
  83.             _Seekhigh = p;
  84.             setp(p, p + nsize);
  85.             setg(p, p, p);
  86.             }
  87.         else
  88.             {    // revise old pointers
  89.             _Seekhigh = _Seekhigh - eback() + p;
  90.             setp(pbase() - eback() + p, pptr() - eback() + p,
  91.                 p + nsize);
  92.             setg(p, gptr() - eback() + p, pptr() + 1);
  93.             }
  94.         return ((unsigned char)(*_Pninc() = (char)ch));
  95.         }
  96.     }
  97.  
  98. _CRTIMP2 int strstreambuf::pbackfail(int ch)
  99.     {    // try to putback a character
  100.     if (gptr() == 0 || gptr() <= eback()
  101.         || ch != EOF
  102.             && (unsigned char)ch != (unsigned char)gptr()[-1]
  103.             && _Strmode & _Constant)
  104.         return (EOF);
  105.     else
  106.         {    // safe to back up
  107.         gbump(-1);
  108.         return (ch == EOF ? 0 : (unsigned char)(*gptr() = (char)ch));
  109.         }
  110.     }
  111.  
  112. _CRTIMP2 int strstreambuf::underflow()
  113.     {    // read only if read position available
  114.     if (gptr() == 0)
  115.         return (EOF);
  116.     else if (gptr() < egptr())
  117.         return ((unsigned char)*gptr());
  118.     else if (pptr() == 0
  119.         || pptr() <= gptr() && _Seekhigh <= gptr())
  120.         return (EOF);
  121.     else
  122.         {    // update _Seekhigh and expand read region
  123.         if (_Seekhigh < pptr())
  124.             _Seekhigh = pptr();
  125.         setg(eback(), gptr(), _Seekhigh);
  126.         return ((unsigned char)*gptr());
  127.         }
  128.     }
  129.  
  130. _CRTIMP2 streampos strstreambuf::seekoff(streamoff off,
  131.     ios::seekdir way, ios::openmode which)
  132.     {    // seek by specified offset
  133.     if (pptr() != 0 && _Seekhigh < pptr())
  134.         _Seekhigh = pptr();
  135.     if (which & ios::in && gptr() != 0)
  136.         {    // set input (and maybe output) pointer
  137.         if (way == ios::end)
  138.             off += _Seekhigh - eback();
  139.         else if (way == ios::cur && !(which & ios::out))
  140.             off += gptr() - eback();
  141.         else if (way != ios::beg || off == _BADOFF)
  142.             off = _BADOFF;
  143.         if (0 <= off && off <= _Seekhigh - eback())
  144.             {    // set one or two pointers
  145.             gbump(eback() - gptr() + off);
  146.             if (which & ios::out && pptr() != 0)
  147.                 setp(pbase(), gptr(), epptr());
  148.             }
  149.         else
  150.             off = _BADOFF;
  151.         }
  152.     else if (which & ios::out && pptr() != 0)
  153.         {    // set only output pointer
  154.         if (way == ios::end)
  155.             off += _Seekhigh - eback();
  156.         else if (way == ios::cur)
  157.             off += pptr() - eback();
  158.         else if (way != ios::beg || off == _BADOFF)
  159.             off = _BADOFF;
  160.         if (0 <= off && off <= _Seekhigh - eback())
  161.             pbump(eback() - pptr() + off);
  162.         else
  163.             off = _BADOFF;
  164.         }
  165.     else    // nothing to set
  166.         off = _BADOFF;
  167.     return (streampos(off));
  168.     }
  169.  
  170. _CRTIMP2 streampos strstreambuf::seekpos(streampos sp,
  171.         ios::openmode which)
  172.     {    // seek to memorized position
  173.     streamoff off = (streamoff)sp;
  174.     if (pptr() != 0 && _Seekhigh < pptr())
  175.         _Seekhigh = pptr();
  176.     if (off == _BADOFF)
  177.         ;
  178.     else if (which & ios::in && gptr() != 0)
  179.         {    // set input (and maybe output) pointer
  180.         if (0 <= off && off <= _Seekhigh - eback())
  181.             {    // set valid offset
  182.             gbump(eback() - gptr() + off);
  183.             if (which & ios::out && pptr() != 0)
  184.                 setp(pbase(), gptr(), epptr());
  185.             }
  186.         else
  187.             off = _BADOFF;
  188.         }
  189.     else if (which & ios::out && pptr() != 0)
  190.         {    // set output pointer
  191.         if (0 <= off && off <= _Seekhigh - eback())
  192.             pbump(eback() - pptr() + off);
  193.         else
  194.             off = _BADOFF;
  195.         }
  196.     else    // nothing to set
  197.         off = _BADOFF;
  198.     return (streampos(off));
  199.     }
  200.  
  201. _CRTIMP2 void strstreambuf::_Init(int n, char *gp, char *pp,
  202.     _Strstate mode)
  203.     {    // initialize with possibly static buffer
  204.     streambuf::_Init();
  205.     _Pendsave = 0;
  206.     _Seekhigh = 0;
  207.     _Palloc = 0;
  208.     _Pfree = 0;
  209.     _Strmode = mode;
  210.     if (gp == 0)
  211.         {    // make dynamic
  212.         _Alsize = _MINSIZE <= n ? n : _ALSIZE;
  213.         _Strmode |= _Dynamic;
  214.         }
  215.     else
  216.         {    // make static
  217.         int size = n < 0 ? INT_MAX : n == 0 ? strlen(gp) : n;
  218.         _Alsize = 0;
  219.         _Seekhigh = gp + size;
  220.         if (pp == 0)
  221.             setg(gp, gp, gp + size);
  222.         else
  223.             {    // make writable too
  224.             if (pp < gp)
  225.                 pp = gp;
  226.             else if (gp + size < pp)
  227.                 pp = gp + size;
  228.             setp(pp, gp + size);
  229.             setg(gp, gp, pp);
  230.             }
  231.         }
  232.     }
  233.  
  234. _CRTIMP2 void strstreambuf::_Tidy()
  235.     {    // discard any allocated storage
  236.     if ((_Strmode & (_Allocated | _Frozen)) != _Allocated)
  237.         ;
  238.     else if (_Pfree != 0)
  239.         (*_Pfree)(eback());
  240.     else
  241.         delete[] eback();
  242.     _Seekhigh = 0;
  243.     _Strmode &= ~(_Allocated | _Frozen);
  244.     }
  245. _STD_END
  246.  
  247. /*
  248.  * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  249.  * Consult your license regarding permissions and restrictions.
  250.  */
  251.