arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

kokostream.h

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////
00002 /// kokostream.h
00003 ///
00004 /// Basic Koko Streams 
00005 //// a hacked version of sstream
00006 /// "hacked" by Joe Kniss 7-10-03
00007 ///
00008 /// kokobuf's are first
00009 /// ikokostreams are second
00010 /// okokostreams are third
00011 /// kokostreams (in and out) are last
00012 ///
00013 /// There are key typedefs after each of these
00014 ///   specifically for "char" type instances (BYTE)
00015 ///   after each class declaration
00016 ///
00017 //////////////////////////////////////////////////////////////////////////////
00018 
00019 
00020 #ifndef __KOKO_STREAM_BASIC_DOT_H
00021 #define __KOKO_STREAM_BASIC_DOT_H
00022 
00023 #include <istream>
00024 #include <ostream>
00025 #include <string>
00026 #include <smartptr.h>
00027 
00028 #ifdef WIN32
00029 #pragma warning(disable:4251)
00030 #endif
00031 
00032 #ifndef _BADOFF
00033 #define _BADOFF 0
00034 #endif
00035 
00036 //////////////////////////////////////////////////////////////////////////////
00037 //////////////////////////////////////////////////////////////////////////////
00038 //////////////////////////////////////////////////////////////////////////////
00039 // TEMPLATE CLASS basic_kokobuf
00040 //////////////////////////////////////////////////////////////////////////////
00041 //////////////////////////////////////////////////////////////////////////////
00042 //////////////////////////////////////////////////////////////////////////////
00043 template<
00044          class _Elem,
00045          class _Traits,
00046          class _Alloc
00047         >
00048 class basic_kokobuf
00049    : public std::basic_streambuf<_Elem, _Traits>,
00050      public gutz::Counted
00051 {       // stream buffer maintaining an allocated character array
00052 public:
00053    typedef _Alloc allocator_type;
00054    /// My Stream buffer (ie. my base class)
00055    typedef std::basic_streambuf<_Elem, _Traits> _Mysb;
00056    /// My String (ie, what kind of buffer am I)
00057    typedef std::basic_string<_Elem, _Traits, _Alloc> _Mystr;
00058    typedef std::ios_base::openmode openmode;
00059 
00060    /////////////////////////////////////////////////////////////
00061    /// Construction, given some intial size
00062    explicit basic_kokobuf(int size, openmode _Mode = 
00063                             std::ios_base::in | std::ios_base::out)
00064    /// using default base class constructors
00065    {    // construct specific sized character buffer 
00066       
00067       _Init(0, 0, _Getstate(_Mode));
00068       
00069       if(size < 0) return;
00070 
00071       _Elem *_Pnew = _Al.allocate(size);
00072       _Seekhigh = _Pnew;
00073 
00074       /// istream
00075       if (!(_Mystate & _Noread))
00076          _Mysb::setg(_Pnew, _Pnew,
00077                      _Pnew + size);     // setup read buffer
00078       /// &| ostream
00079       if (!(_Mystate & _Constant))
00080       { // setup write buffer, and maybe read buffer
00081          _Mysb::setp(_Pnew, _Pnew + size);
00082          if (_Mysb::gptr() == 0)
00083             _Mysb::setg(_Pnew, 0, _Pnew);
00084       }
00085       _Mystate |= _Allocated;
00086    }
00087 
00088    /////////////////////////////////////////////////////////////
00089    /// destruction, nuke it :)
00090    virtual ~basic_kokobuf()
00091    {    // destroy the object
00092       _Tidy();
00093    }
00094 
00095    enum
00096    {    // constants for bits in stream state
00097       _Allocated = 1,  // set if character array storage has been allocated
00098       _Constant = 2,     // set if character array nonmutable
00099       _Noread = 4,         // set if character array cannot be read
00100       _Append = 8,     // set if all writes are appends
00101       _Frozen = 16     // U can't touch this!!
00102    };
00103    typedef int _Strstate;
00104 
00105    typedef typename _Traits::int_type int_type;
00106    typedef typename _Traits::pos_type pos_type;
00107    typedef typename _Traits::off_type off_type;
00108 
00109    /////////////////////////////////////////////////////////////
00110    /// New additions, direct hacking of the stream!!! yeay.
00111    /////////////////////////////////////////////////////////////
00112 
00113    ////////////////////////////////////////
00114    /// recycle your streams, think green.
00115    /// false = success, true = failure
00116    bool resetStream()
00117    {
00118       if(_Mystate & _Frozen) return true;
00119       _Seekhigh = _Mysb::pbase();
00120       
00121       #ifdef WIN32
00122       _Mysb::setp(_Mysb::pbase(), _Mysb::pbase(), _Mysb::epptr());
00123       #else /// g++ ?
00124       _Mysb::setp(_Mysb::pbase(), _Mysb::epptr());
00125       #endif
00126 
00127       if (_Mystate & _Noread)
00128       {
00129          _Mysb::setg(_Mysb::eback(), 0, _Mysb::epptr());
00130       }
00131       else
00132       {
00133          _Mysb::setg(_Mysb::eback(), _Mysb::eback(), _Mysb::eback()+1);
00134       }
00135       return false;
00136    }
00137 
00138    ////////////////////////////////////////
00139    /// make it into a "in" stream buf,
00140    /// you still need to reset the stream,
00141    /// if that is your intention
00142    /// false= success, true = failure
00143    bool makeWritable()
00144    {
00145       if(_Mystate & _Frozen) return true;
00146       _Mystate &= ~(_Constant);
00147       return false;
00148    }
00149    
00150    ////////////////////////////////////////
00151    /// make it into a "out" stream buf
00152    /// make an instream into an outstream.
00153    /// false = success, true = failure
00154    bool makeReadable()
00155    {
00156       if(_Mystate & _Frozen) return true;
00157       ///setg(_Mysb::pbase(),_Mysb::pbase(),_Mysb::pptr()+1);
00158       _Mystate &= ~(_Noread);
00159       _Mysb::setg(_Mysb::pbase(), _Mysb::pbase(), _Mysb::pptr());
00160       return false;
00161    }
00162    
00163    
00164    ////////////////////////////////////////
00165    /// How big is this buffer
00166    int totalBufferSize() const 
00167    {
00168       return (_Mysb::pptr() == 0
00169                    ? 0 : _Mysb::epptr() - _Mysb::pbase()) ;
00170    }
00171    ////////////////////////////////////////
00172    /// how much could you write to this stream?
00173    int writableSize() const
00174    {
00175       return (_Mysb::pptr() == 0
00176                    ? 0 : _Mysb::epptr() - _Mysb::pptr() - 1) ;
00177    }
00178    ////////////////////////////////////////
00179    /// how much has been written
00180    int writtenSize() const
00181    {
00182       return (_Mysb::pptr() == 0
00183                    ? 0 : _Mysb::pptr() - _Mysb::pbase() );
00184    }
00185 
00186    ////////////////////////////////////////
00187    /// getWritePtr(), frezes stream till 
00188    /// you set the written size,
00189    _Elem *getCurWritePtr()
00190    {
00191       if(_Mystate & _Constant) return 0;
00192       _Mystate |= _Constant | _Frozen;
00193       #if WIN32
00194       return (_Mysb::_Pninc());
00195       #else
00196       _Elem *_Pret = _M_out_cur;
00197       _M_out_cur_move(1);
00198       return (_Pret);
00199       #endif
00200 
00201    }
00202    ////////////////////////////////////////
00203    /// set how much was written after you get the
00204    /// getWritePtr(), + "unFreze" the stream
00205    void setWrittenSize(int size)
00206    {
00207       if(!(_Mystate & _Frozen)) return;
00208       _Mystate &= ~(_Constant | _Frozen);
00209       pbump(size-1); /// we only inc to last char written
00210    }
00211    ////////////////////////////////////////
00212    /// get the pointer for reading only,
00213    /// starting at the beginning of stream
00214    const _Elem *getReadPtr() const
00215    {
00216       if(!(_Mystate & _Constant)) 
00217          _Mystate |= _Constant | _Frozen;
00218       return _Mysb::eback();
00219    }
00220    ////////////////////////////////////////
00221    /// get a read pointer from the current
00222    /// position
00223    const _Elem *getCurReadPtr() const
00224    {
00225       if(!(_Mystate & _Constant)) 
00226          _Mystate |= _Constant | _Frozen;
00227       return _Mysb::gptr();
00228    }
00229    ////////////////////////////////////////
00230    /// you read from it? how much
00231    /// plus, return it to a "normal state"
00232    void setReadSize(int size)
00233    {
00234       if(!(_Mystate & _Frozen))
00235          _Mystate &= ~(_Constant | _Frozen);
00236       gbump(size);
00237    }
00238    ////////////////////////////////////////
00239    /// return it to a "normal state" after 
00240    /// reading, equiv. unFreze();
00241    void returnReadPtr() 
00242    {
00243       if(!(_Mystate & _Frozen)) return;
00244       _Mystate &= ~(_Constant | _Frozen);
00245    }
00246    ////////////////////////////////////////
00247    /// how much of this array has been written to
00248    size_t getReadableSize() const 
00249    {
00250       return (_Mysb::pptr() == 0
00251                    ? 0 : _Mysb::egptr() - _Mysb::gptr()) ;
00252    }
00253    ////////////////////////////////////////
00254    /// can we/should we write to this buffer
00255    bool isFrozen() const { return _Mystate & _Frozen; }
00256    bool isConst() const  { return _Mystate & (_Constant | _Frozen); }
00257 
00258    ////////////////////////////////////////
00259    /// change the size of this stream, 
00260    /// carefull, is this really nessessary? 
00261    ///   copys old data, could be slow.
00262    bool setSize(int size)
00263    {
00264       if(size < 0) return false;
00265          
00266       _Elem *_Ptr = 0;
00267       _Ptr = _Al.allocate(_Newsize);
00268       if (_Mystate & _Allocated)
00269          _Al.deallocate(_Mysb::eback(), _Oldsize);
00270       _Mystate |= _Allocated;
00271 
00272       _Seekhigh = _Seekhigh - _Mysb::eback() + _Ptr;
00273       _Mysb::setp(_Mysb::pbase() - _Mysb::eback() + _Ptr,
00274          _Mysb::pptr() - _Mysb::eback() + _Ptr, _Ptr + _Newsize);
00275       if (_Mystate & _Noread)
00276          _Mysb::setg(_Ptr, 0, _Ptr);
00277       else
00278          _Mysb::setg(_Ptr,
00279                      _Mysb::gptr() - _Mysb::eback() + _Ptr,
00280                      _Mysb::pptr() + 1);
00281       return true;
00282    }
00283 
00284    /////////////////////////////////////////////////////////////
00285    /// get a "deep copy" of the buffer, no need to unfreze()
00286    _Mystr str() const
00287    {    // return string copy of character array
00288       /// ostream
00289       if (!(_Mystate & _Constant) && _Mysb::pptr() != 0)
00290       { // writable, make string from write buffer
00291          _Mystr _Str(_Mysb::pbase(), (_Seekhigh < _Mysb::pptr()
00292             ? int(_Mysb::pptr()) : int(_Seekhigh)) - int(_Mysb::pbase()));
00293          return (_Str);
00294       }
00295       /// istream
00296       else if (!(_Mystate & _Noread) && _Mysb::gptr() != 0)
00297       { // readable, make string from read buffer
00298          _Mystr _Str(_Mysb::eback(), _Mysb::egptr() - _Mysb::eback());
00299          return (_Str);
00300       }
00301       else
00302       { // inaccessible, return empty string
00303          _Mystr _Nul;
00304          return (_Nul);
00305       }
00306    }
00307 
00308    /////////////////////////////////////////////////////////////
00309    /// resize + "deep copy" from a string
00310    void str(const _Mystr& _Newstr)
00311    {    // replace character array from string
00312       if(int(_Newstr.size()) > int(epptr() - pbase()))
00313       {
00314          _Tidy();
00315          _Init(_Newstr.c_str(), _Newstr.size(), _Mystate);
00316          return;
00317       }
00318       resetStream();
00319       _Elem * p = getCurWritePtr();
00320       const _Elem * s = _Newstr.c_str();
00321       for(int i=0; i<int(_Newstr.size()); ++i)
00322       {
00323          p[i] = s[i];
00324       }
00325       setWrittenSize(_Newstr.size());
00326    }
00327 
00328    /////////////////////////////////////////////////////////////
00329    /// Protected from here down
00330    /////////////////////////////////////////////////////////////
00331 
00332 protected:
00333 
00334    virtual int_type overflow(int_type _Meta = _Traits::eof())
00335    {    // put an element to stream
00336       if (_Mystate & _Append
00337          && _Mysb::pptr() != 0 && _Mysb::pptr() < _Seekhigh)
00338       {
00339          #ifdef WIN32
00340          _Mysb::setp(_Mysb::pbase(), _Seekhigh, _Mysb::epptr());        
00341          #else /// g++, may need yet more hacks!
00342          _Mysb::setp(_Mysb::pbase(), _Mysb::epptr());
00343          _M_out_cur_move(_Seekhigh - _Mysb::pbase());
00344          #endif
00345       }
00346       if (_Traits::eq_int_type(_Traits::eof(), _Meta))
00347          return (_Traits::not_eof(_Meta));      // EOF, return success code
00348       else if (_Mysb::pptr() != 0
00349          && _Mysb::pptr() < _Mysb::epptr())
00350       { // room in buffer, store it
00351          #if WIN32
00352          *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
00353          #else
00354          (*_M_out_cur) = _Traits::to_char_type(_Meta);
00355          _M_out_cur_move(1);
00356          #endif
00357          return (_Meta);
00358       }
00359       else if (_Mystate & _Constant)
00360          return (_Traits::eof());       // array nonmutable, fail
00361       else
00362       { // grow buffer and store element
00363          size_t _Oldsize = _Mysb::pptr() == 0
00364             ? 0 : _Mysb::epptr() - _Mysb::eback();
00365          size_t _Newsize = _Oldsize;
00366          size_t _Inc = _Newsize / 2 < _MINSIZE
00367             ? _MINSIZE : _Newsize / 2;  // grow by 50 per cent
00368          _Elem *_Ptr = 0;
00369 
00370          while (0 < _Inc && INT_MAX - _Inc < _Newsize)
00371             _Inc /= 2;  // increment causes overflow, halve it
00372          if (0 < _Inc)
00373          {      // finite increment, allocate new character array
00374             _Newsize += _Inc;
00375             _Ptr = _Al.allocate(_Newsize);
00376          }
00377 
00378          if (0 < _Oldsize)
00379             _Traits::copy(_Ptr, _Mysb::eback(), _Oldsize);
00380          if (_Mystate & _Allocated)
00381             _Al.deallocate(_Mysb::eback(), _Oldsize);
00382          _Mystate |= _Allocated;
00383 
00384          if (_Oldsize == 0)
00385          {      // first growth, set up pointers
00386             _Seekhigh = _Ptr;
00387             _Mysb::setp(_Ptr, _Ptr + _Newsize);
00388             if (_Mystate & _Noread)
00389                _Mysb::setg(_Ptr, 0, _Ptr);
00390             else
00391                _Mysb::setg(_Ptr, _Ptr, _Ptr + 1);
00392          }
00393          else
00394          {      // not first growth, adjust pointers
00395             _Seekhigh = _Seekhigh - _Mysb::eback() + _Ptr;
00396 
00397             #ifdef WIN32
00398             _Mysb::setp(_Mysb::pbase() - _Mysb::eback() + _Ptr,
00399                         _Mysb::pptr() - _Mysb::eback() + _Ptr, 
00400                         _Ptr + _Newsize);
00401             #else /// g++, may need yet more hacks!
00402                _Mysb::setp(_Mysb::pbase() - _Mysb::eback() + _Ptr, 
00403                            _Ptr + _Newsize);
00404                _M_out_cur_move(_Mysb::pptr() - _Mysb::eback() + _Ptr - _Mysb::pbase());
00405             #endif
00406             if (_Mystate & _Noread)
00407                _Mysb::setg(_Ptr, 0, _Ptr);
00408             else
00409                _Mysb::setg(_Ptr,
00410                            _Mysb::gptr() - _Mysb::eback() + _Ptr,
00411                            _Mysb::pptr() + 1);
00412          }
00413           #if WIN32
00414            *_Mysb::_Pninc() = _Traits::to_char_type(_Meta);
00415           #else
00416            (*_M_out_cur) = _Traits::to_char_type(_Meta);
00417            _M_out_cur_move(1);
00418          #endif
00419          
00420          return (_Meta);
00421       }
00422    }
00423 
00424    virtual int_type pbackfail(int_type _Meta = _Traits::eof())
00425    {    // put an element back to stream
00426       if (_Mysb::gptr() == 0
00427          || _Mysb::gptr() <= _Mysb::eback()
00428          || !_Traits::eq_int_type(_Traits::eof(), _Meta)
00429          && !_Traits::eq(_Traits::to_char_type(_Meta), _Mysb::gptr()[-1])
00430          && _Mystate & _Constant)
00431          return (_Traits::eof());       // can't put back, fail
00432       else
00433       { // back up one position and store put-back character
00434          _Mysb::gbump(-1);
00435          if (!_Traits::eq_int_type(_Traits::eof(), _Meta))
00436             *_Mysb::gptr() = _Traits::to_char_type(_Meta);
00437          return (_Traits::not_eof(_Meta));
00438       }
00439    }
00440 
00441    virtual int_type underflow()
00442    {    // get an element from stream, but don't point past it
00443       if (_Mysb::gptr() == 0)
00444          return (_Traits::eof());       // no character buffer, fail
00445       else if (_Mysb::gptr() < _Mysb::egptr())
00446          return (_Traits::to_int_type(*_Mysb::gptr())); // return buffered
00447       else if (_Mystate & _Noread || _Mysb::pptr() == 0
00448          || _Mysb::pptr() <= _Mysb::gptr() && _Seekhigh <= _Mysb::gptr())
00449          return (_Traits::eof());       // can't read, fail
00450       else
00451       { // extend read buffer into written area, then return buffered
00452          if (_Seekhigh < _Mysb::pptr())
00453             _Seekhigh = _Mysb::pptr();
00454          _Mysb::setg(_Mysb::eback(), _Mysb::gptr(), _Seekhigh);
00455          return (_Traits::to_int_type(*_Mysb::gptr()));
00456       }
00457    }
00458 
00459    virtual pos_type seekoff(off_type _Off,
00460                             std::ios_base::seekdir _Way,
00461                             openmode _Which = std::ios_base::in | std::ios_base::out)
00462    {    // change position by _Off, according to _Way, _Mode
00463       if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
00464          _Seekhigh = _Mysb::pptr();     // update high-water pointer
00465 
00466       /// istream
00467       if (_Which & std::ios_base::in && _Mysb::gptr() != 0)
00468       { // position within read buffer
00469          if (_Way == std::ios_base::end)
00470             _Off += (off_type)(_Seekhigh - _Mysb::eback());
00471          else if (_Way == std::ios_base::cur
00472                   && (_Which & std::ios_base::out) == 0)
00473             _Off += (off_type)(_Mysb::gptr() - _Mysb::eback());
00474          else if (_Way != std::ios_base::beg)
00475             _Off = _BADOFF;
00476 
00477          if ( (0 <= _Off) && (_Off <= (_Seekhigh - _Mysb::eback())) )
00478          {      // change read position
00479             _Mysb::gbump( int( _Mysb::eback() - _Mysb::gptr() + _Off ) );
00480             if ( _Which & std::ios_base::out && _Mysb::pptr() != 0 )
00481             {
00482                #ifdef WIN32
00483                _Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
00484                            _Mysb::epptr());     // change write position to match
00485                #else /// g++, may need yet more hacks!
00486                _Mysb::setp(_Mysb::pbase(), _Mysb::epptr());
00487                _M_out_cur_move(_Mysb::gptr() - _Mysb::pbase());
00488                #endif
00489             }
00490          }
00491          else
00492             _Off = _BADOFF;
00493       }
00494       /// ostream
00495       else if (_Which & std::ios_base::out && _Mysb::pptr() != 0)
00496       { // position within write buffer
00497          if (_Way == std::ios_base::end)
00498             _Off += (off_type)(_Seekhigh - _Mysb::eback());
00499          else if (_Way == std::ios_base::cur)
00500             _Off += (off_type)(_Mysb::pptr() - _Mysb::eback());
00501          else if (_Way != std::ios_base::beg)
00502             _Off = _BADOFF;
00503 
00504          if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
00505             _Mysb::pbump((int)(_Mysb::eback()
00506             - _Mysb::pptr() + _Off));   // change write position
00507          else
00508             _Off = _BADOFF;
00509       }
00510       else
00511          _Off = _BADOFF;        // neither read nor write buffer selected, fail
00512       return (pos_type(_Off));
00513    }
00514 
00515    virtual pos_type seekpos(pos_type _Ptr,
00516       openmode _Mode = std::ios_base::in | std::ios_base::out)
00517    {    // change position to _Pos, according to _Mode
00518       std::streamoff _Off = (std::streamoff)_Ptr;
00519       if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
00520          _Seekhigh = _Mysb::pptr();     // update high-water pointer
00521 
00522       if (_Off == int(_BADOFF))
00523          ;
00524       else if (_Mode & std::ios_base::in && _Mysb::gptr() != 0)
00525       { // position within read buffer
00526          if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
00527          {      // change read position
00528             _Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
00529             if (_Mode & std::ios_base::out && _Mysb::pptr() != 0)
00530                #ifdef WIN32
00531                _Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
00532                            _Mysb::epptr());     // change write position to match
00533                #else
00534                _Mysb::setp(_Mysb::pbase(), _Mysb::epptr());
00535                _M_out_cur_move(_Mysb::gptr() - _Mysb::pbase());
00536                #endif
00537          }
00538          else
00539             _Off = _BADOFF;
00540       }
00541       else if (_Mode & std::ios_base::out && _Mysb::pptr() != 0)
00542       { // position within write buffer
00543          if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
00544             _Mysb::pbump((int)(_Mysb::eback()
00545             - _Mysb::pptr() + _Off));   // change write position
00546          else
00547             _Off = _BADOFF;
00548       }
00549       else
00550          _Off = _BADOFF;
00551       return (std::streampos(_Off));
00552    }
00553 
00554    void _Init(const _Elem *_Ptr,
00555       size_t _Count, _Strstate _State)
00556    {    // initialize buffer to [_Ptr, _Ptr + _Count), set state
00557       _Seekhigh = 0;
00558       _Mystate = _State;
00559 
00560       if (_Count != 0
00561          && (_Mystate & (_Noread | _Constant)) != (_Noread | _Constant))
00562       { // finite buffer that can be read or written, set it up
00563          _Elem *_Pnew = _Al.allocate(_Count);
00564          _Traits::copy(_Pnew, _Ptr, _Count);
00565          _Seekhigh = _Pnew + _Count;
00566 
00567          /// istream
00568          if (!(_Mystate & _Noread))
00569             _Mysb::setg(_Pnew, _Pnew,
00570                         _Pnew + _Count);        // setup read buffer
00571          /// ostream
00572          if (!(_Mystate & _Constant))
00573          {      // setup write buffer, and maybe read buffer
00574             _Mysb::setp(_Pnew, _Pnew + _Count);
00575             if (_Mysb::gptr() == 0)
00576                _Mysb::setg(_Pnew, 0, _Pnew);
00577          }
00578          _Mystate |= _Allocated;
00579       }
00580    }
00581 
00582    void _Tidy()
00583    {    // discard any allocated buffer and clear pointers
00584       if (_Mystate & _Allocated)
00585          _Al.deallocate(_Mysb::eback(),
00586          (_Mysb::pptr() != 0 ? _Mysb::epptr()
00587          : _Mysb::egptr()) - _Mysb::eback());
00588       _Mysb::setg(0, 0, 0);
00589       _Mysb::setp(0, 0);
00590       _Seekhigh = 0;
00591       _Mystate &= ~_Allocated;
00592    }
00593 
00594 protected:  // ahh protected, what a pain sstreams are!!!
00595    enum
00596    {    // constant for minimum buffer size
00597       _MINSIZE = 32
00598    };
00599 
00600    _Strstate _Getstate(openmode _Mode)
00601    {    // convert open mode to stream state bits
00602       _Strstate _State = (_Strstate)0;
00603       if (!(_Mode & std::ios_base::in))
00604          _State |= _Noread;
00605       if (!(_Mode & std::ios_base::out))
00606          _State |= _Constant;
00607       if (_Mode & std::ios_base::app)
00608          _State |= _Append;
00609       return (_State);
00610    }
00611 
00612    _Elem *_Seekhigh;    // the high-water pointer in character array
00613    _Strstate _Mystate;  // the stream state
00614    allocator_type _Al;  // the allocator object
00615 };
00616 
00617 /// char type koko buffer
00618 typedef basic_kokobuf< char, std::char_traits<char>, std::allocator<char> >
00619    kokobuf;   
00620 
00621 typedef gutz::SmartPtr<kokobuf>  kokobufSP;
00622 
00623 /*  not using dll's yet 
00624 #ifdef _DLL_CPPLIB
00625 template class _CRTIMP2 basic_kokobuf<char, char_traits<char>, 
00626                                       allocator<char> >;
00627 template class _CRTIMP2 basic_kokobuf<wchar_t, char_traits<wchar_t>, 
00628                                       allocator<wchar_t> >;
00629 #endif 
00630 */
00631 
00632 //////////////////////////////////////////////////////////////////////////////
00633 //////////////////////////////////////////////////////////////////////////////
00634 //////////////////////////////////////////////////////////////////////////////
00635 //////////////////////////////////////////////////////////////////////////////
00636 //////////////////////////////////////////////////////////////////////////////
00637 // TEMPLATE CLASS basic_ikokostream
00638 //////////////////////////////////////////////////////////////////////////////
00639 //////////////////////////////////////////////////////////////////////////////
00640 //////////////////////////////////////////////////////////////////////////////
00641 //////////////////////////////////////////////////////////////////////////////
00642 //////////////////////////////////////////////////////////////////////////////
00643 template<
00644          class _Elem,
00645          class _Traits,
00646          class _Alloc
00647         >
00648 class basic_ikokostream
00649    : public std::basic_istream<_Elem, _Traits>
00650 {       // input stream associated with a character array
00651 public:
00652    typedef _Alloc allocator_type;
00653    /// type of stream buffer we use
00654    typedef basic_kokobuf<_Elem, _Traits, _Alloc> _Mysb;
00655    /// type of string we return
00656    typedef std::basic_string<_Elem, _Traits, _Alloc>  _Mystr;
00657 
00658    /////////////////////////////////////////////////////////////
00659    /// construct, use an existing buffer
00660    explicit basic_ikokostream(_Mysb *sb)
00661       : std::basic_istream<_Elem, _Traits>(sb),
00662         _kokobuffer(sb)
00663    {
00664    }
00665 
00666    /////////////////////////////////////////////////////////////
00667    /// destruct
00668    virtual ~basic_ikokostream()
00669    {    // destroy the object
00670    }
00671 
00672    /////////////////////////////////////////////////////////////
00673    /// change buffer
00674    void setStreamBuffer(_Mysb *sb)
00675    {
00676       _kokobuffer = sb;
00677       clear();
00678       std::basic_istream<_Elem, _Traits>::basic_istream<_Elem,_Traits>((_Mysb*)_kokobuffer);
00679    }
00680    /////////////////////////////////////////////////////////////
00681    /// get buffer
00682    gutz::SmartPtr<_Mysb> getStreamBuffer() { return _kokobuffer; }
00683 
00684    /////////////////////////////////////////////////////////////
00685    /// get the buffer object
00686    _Mysb *rdbuf() const
00687    {    // return pointer to koko buffer
00688       return (_kokobuffer.getPtr());
00689    }
00690 
00691    /////////////////////////////////////////////////////////////
00692    /// Deep copy string out
00693    _Mystr str() const
00694    {    // return string copy of character array
00695       return (_kokobuffer->str());
00696    }
00697 
00698    /////////////////////////////////////////////////////////////
00699    /// Resize & deep copy in
00700    void str(const _Mystr& _Newstr)
00701    {    // replace character array from string
00702       _kokobuffer->str(_Newstr);
00703    }
00704 
00705 protected:
00706    gutz::SmartPtr<_Mysb> _kokobuffer;   // the string buffer
00707 };
00708 
00709 /// char type basic ikokostream
00710 typedef basic_ikokostream<char, std::char_traits<char>, std::allocator<char> >
00711    ikokostream;
00712 
00713 /*  not using dll's yet
00714 #ifdef _DLL_CPPLIB
00715 template class _CRTIMP2 basic_istringstream<char,
00716 char_traits<char>, allocator<char> >;
00717 template class _CRTIMP2 basic_istringstream<wchar_t,
00718 char_traits<wchar_t>, allocator<wchar_t> >;
00719 #endif 
00720 */
00721 
00722 //////////////////////////////////////////////////////////////////////////////
00723 //////////////////////////////////////////////////////////////////////////////
00724 //////////////////////////////////////////////////////////////////////////////
00725 //////////////////////////////////////////////////////////////////////////////
00726 //////////////////////////////////////////////////////////////////////////////
00727 // TEMPLATE CLASS basic_okokostream
00728 //////////////////////////////////////////////////////////////////////////////
00729 //////////////////////////////////////////////////////////////////////////////
00730 //////////////////////////////////////////////////////////////////////////////
00731 //////////////////////////////////////////////////////////////////////////////
00732 //////////////////////////////////////////////////////////////////////////////
00733 template<
00734          class _Elem,
00735          class _Traits,
00736          class _Alloc
00737         >
00738 class basic_okokostream
00739    : public std::basic_ostream<_Elem, _Traits>
00740 {       // output stream associated with a character array
00741 public:
00742    typedef _Alloc allocator_type;
00743    typedef basic_kokobuf<_Elem, _Traits, _Alloc> _Mysb;
00744    typedef std::basic_string<_Elem, _Traits, _Alloc> _Mystr;
00745 
00746    explicit basic_okokostream(_Mysb *sb)
00747       : std::basic_ostream<_Elem, _Traits>(sb),
00748       _kokobuffer(sb)
00749    {
00750 
00751    }
00752 
00753    virtual ~basic_okokostream()
00754    {    // destroy the object
00755    }
00756 
00757    void setStreamBuffer(_Mysb *sb)
00758    {
00759       _kokobuffer = sb;
00760       clear();
00761       std::basic_ostream<_Elem, _Traits>::basic_ostream<_Elem, _Traits>((_Mysb*)_kokobuffer);
00762    }
00763    /////////////////////////////////////////////////////////////
00764    /// get buffer
00765    gutz::SmartPtr<_Mysb> getStreamBuffer() { return _kokobuffer; }
00766 
00767    _Mysb *rdbuf() const
00768    {    // return pointer to buffer
00769       return (_kokobuffer.getPtr());
00770    }
00771 
00772    _Mystr str() const
00773    {    // return string copy of character array
00774       return (_kokobuffer->str());
00775    }
00776 
00777    void str(const _Mystr& _Newstr)
00778    {    // replace character array from string
00779       _kokobuffer->str(_Newstr);
00780    }
00781 
00782 protected:
00783    gutz::SmartPtr<_Mysb> _kokobuffer;   // the string buffer
00784 };
00785 
00786 typedef basic_okokostream<char, std::char_traits<char>, std::allocator<char> >
00787    okokostream;
00788 
00789 /* not using dll's yet...
00790 #ifdef _DLL_CPPLIB
00791 template class _CRTIMP2 basic_okokostream<char, char_traits<char>, allocator<char> >;
00792 template class _CRTIMP2 basic_okokostream<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >;
00793 #endif
00794 */
00795 
00796 //////////////////////////////////////////////////////////////////////////////
00797 //////////////////////////////////////////////////////////////////////////////
00798 //////////////////////////////////////////////////////////////////////////////
00799 //////////////////////////////////////////////////////////////////////////////
00800 //////////////////////////////////////////////////////////////////////////////
00801 // TEMPLATE CLASS basic_kokostream
00802 //////////////////////////////////////////////////////////////////////////////
00803 //////////////////////////////////////////////////////////////////////////////
00804 //////////////////////////////////////////////////////////////////////////////
00805 //////////////////////////////////////////////////////////////////////////////
00806 //////////////////////////////////////////////////////////////////////////////
00807 template<
00808          class _Elem,
00809          class _Traits,
00810          class _Alloc
00811         >
00812 class basic_kokostream
00813    : public std::basic_iostream<_Elem, _Traits>
00814 {       // input/output stream associated with a character array
00815 public:
00816    typedef _Elem char_type;
00817    typedef _Traits traits_type;
00818    typedef _Alloc allocator_type;
00819    typedef typename _Traits::int_type int_type;
00820    typedef typename _Traits::pos_type pos_type;
00821    typedef typename _Traits::off_type off_type;
00822    typedef basic_kokobuf<_Elem, _Traits, _Alloc> _Mysb;
00823    typedef std::basic_string<_Elem, _Traits, _Alloc> _Mystr;
00824 
00825    explicit basic_kokostream(_Mysb *sb)
00826       : std::basic_iostream<_Elem, _Traits>(sb),
00827         _kokobuffer(sb)
00828    {
00829    }
00830 
00831    virtual ~basic_kokostream()
00832    {    // destroy the object
00833    }
00834 
00835    void setStreamBuffer(_Mysb *sp)
00836    {
00837       _kokobuffer = sp;
00838       clear();
00839       std::basic_iostream<_Elem, _Traits>::basic_iostream<_Elem, _Traits>(_kokobuffer);
00840    }
00841 
00842    /////////////////////////////////////////////////////////////
00843    /// get buffer
00844    gutz::SmartPtr<_Mysb> getStreamBuffer() { return _kokobuffer; }
00845 
00846    _Mysb *rdbuf() const
00847    {    // return pointer to buffer
00848       return (_kokobuffer.getPtr());
00849    }
00850 
00851    _Mystr str() const
00852    {    // return string copy of character array
00853       return (_kokobuffer->str());
00854    }
00855 
00856    void str(const _Mystr& _Newstr)
00857    {    // replace character array from string
00858       _kokobuffer->str(_Newstr);
00859    }
00860 
00861 protected:
00862    gutz::SmartPtr<_Mysb> _kokobuffer;   // the string buffer
00863 };
00864 
00865 typedef basic_kokostream<char, std::char_traits<char>, std::allocator<char> >
00866    kokostream;
00867 
00868 /* not using dll's yet...
00869 #ifdef _DLL_CPPLIB
00870 template class _CRTIMP2 basic_kokostream<char, char_traits<char>, allocator<char> >;
00871 template class _CRTIMP2 basic_kokostream<wchar_t,char_traits<wchar_t>, allocator<wchar_t> >;
00872 #endif
00873 */
00874 
00875 #endif // catch include
00876 

Send questions, comments, and bug reports to:
jmk