home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / modhead1.zip / IOSTREAM.H < prev    next >
C/C++ Source or Header  |  1995-09-17  |  27KB  |  1,008 lines

  1. /*
  2.  *   iostream.h
  3.  *
  4.  *   C++ IOStreams and base classes.
  5.  *
  6.  *       Copyright (c) 1991-1992, MetaWare Incorporated
  7.  */
  8.  
  9. #ifndef __IOSTREAM_H
  10. #define __IOSTREAM_H
  11. #pragma push_align_members(64);
  12.  
  13. #c_include <memory.h>
  14.     // ANSI version of memory.h is shipped in C++ include directory
  15.     // to avoid problem with UNIX's non-prototyped memory.h.
  16. //   EOF and NULL may have been defined elsewhere.
  17. #ifndef EOF
  18. # define EOF (-1)
  19. #endif
  20.  
  21. #ifndef NULL
  22.     #define NULL 0
  23. #endif
  24.  
  25. #if _NONEXCEPT_LIB
  26.     #pragma off(exception_aware_class);
  27. #elif _MSDOS || _MSNT || _OS2
  28.     #pragma on(exception_aware_class);
  29. #endif
  30.  
  31. #if _MSNT && _DLL && !_DLLBUILD
  32.     #pragma on(dllimport);
  33. #endif
  34.  
  35.  
  36. #pragma off(Behaved)
  37. #pragma off(try_static_cast)
  38. //   Extract a character from c, eliminating possibility of EOF.
  39. #define zapeof(c) ((unsigned char)(c))
  40.  
  41. typedef long streampos;
  42. typedef long streamoff;
  43.  
  44. class streambuf;
  45. class ostream;
  46.  
  47. // #define _OLD_IOSTREAM    // if defined, enables old version of xalloc
  48.  
  49. // Definitions for multi-thread libraries
  50. #if _MT
  51.     #define _MT_ONLY(X) X
  52.     #define _UNSAFE(X) X ## _unsafe
  53.     #define _LOCK_THIS _stream_lock l1(this);
  54.     #define _LOCK_BUF  _stream_lock l2(rdbuf());
  55.     #define _MT_OR_ST(X,Y) X
  56.  
  57.     typedef void * _mt_lock;
  58.  
  59.     extern "C" {
  60.     _mt_lock  _mwinit_lock  (void);
  61.     void      _mwlock       (_mt_lock);
  62.     void      _mwunlock     (_mt_lock);
  63.     void      _mwdelete_lock(_mt_lock);
  64.     }
  65. #else
  66.     #undef  _MT
  67.     #define _MT_ONLY(X)
  68.     #define _UNSAFE(X) X
  69.     #define _LOCK_THIS
  70.     #define _LOCK_BUF
  71.     #define _MT_OR_ST(X,Y) Y
  72. #endif
  73.  
  74. #pragma on(nodebug)
  75. /*---------------------------------------------------------------------------
  76.  * class _mt_stream
  77.  *
  78.  *    Base class for all multi-thread-safe classes.
  79.  */
  80.  
  81. #if _MT
  82.  
  83. class _mt_stream {
  84.  
  85. private:
  86.     _mt_lock    mutex;        // mutual exclusion lock
  87.     int        lock_flag;    // non-zero if locking is required
  88.  
  89. protected:
  90.     _mt_lock get_mutex() { return mutex; }
  91.     int get_lock_flag() { return lock_flag; }
  92. public:
  93.     _mt_stream(int safe = 1) {
  94.         lock_flag = safe;    // set safety flag
  95.         mutex = _mwinit_lock();
  96.         }
  97.  
  98.     ~_mt_stream() { _mwdelete_lock(mutex); }
  99.  
  100.     void lock()    {        // lock the stream
  101.         if (lock_flag) _mwlock(mutex); }
  102.  
  103.     void unlock() {        // unlock the stream
  104.             if (lock_flag) _mwunlock(mutex); }
  105.  
  106.     void clr_safe() {        // mark the stream as unsafe
  107.         _mwlock(mutex);
  108.         if (lock_flag)
  109.             lock_flag--;
  110.         _mwunlock(mutex);
  111.         }
  112.  
  113.     void set_safe() {        // mark the stream as safe
  114.         _mwlock(mutex);
  115.         lock_flag++;
  116.         _mwunlock(mutex);
  117.         }
  118.  
  119.     friend class _stream_lock;
  120.     };
  121.  
  122. /*---------------------------------------------------------------------------
  123.  * class _stream_lock:
  124.  *
  125.  *    Class for locking and unlocking streams.
  126.  *
  127.  *    Use this class instead of explicitly locking or
  128.  *    unlocking a stream, because its destructor will
  129.  *    automatically clean up the lock.  This makes
  130.  *    it safe even if an exception should occur while
  131.  *    a stream is locked.
  132.  */
  133.  
  134. class _stream_lock {
  135.  
  136. private:
  137.     _mt_lock    mutex;        // mutual exclusion semaphore
  138.     int        count;        // no. of times mutex has been locked
  139.  
  140.     void do_lock() {
  141.         _mwlock(mutex);
  142.         count++;
  143.         }
  144.  
  145.     void do_unlock() {
  146.         if (count) {
  147.             --count;
  148.             _mwunlock(mutex);
  149.             }
  150.         }
  151.  
  152.     void init_lock(_mt_lock p, int lock_now) {
  153.         mutex = p;
  154.         count = 0;
  155.         if (lock_now)
  156.             do_lock();
  157.         }
  158.  
  159. public:
  160.     /* Constructors allow references or pointers to
  161.      * streams or mutexes. The optional second parameter
  162.      * is non-zero if the mutex should be locked now.
  163.      */
  164.     _stream_lock(_mt_stream &strm, int lock_now = 1) {
  165.         init_lock(strm.get_mutex(), lock_now && strm.get_lock_flag());
  166.         }
  167.  
  168.     _stream_lock(_mt_stream *strmp, int lock_now = 1) {
  169.         init_lock(strmp->get_mutex(),
  170.             lock_now && strmp->get_lock_flag());
  171.         }
  172.  
  173.     _stream_lock(_mt_lock &mutex, int lock_now = 1) {
  174.         init_lock(mutex, lock_now);
  175.         }
  176.  
  177.     _stream_lock(_mt_lock *mutexp, int lock_now = 1) {
  178.         init_lock(*mutexp, lock_now);
  179.         }
  180.  
  181.     ~_stream_lock() {
  182.         do_unlock();
  183.         }
  184.  
  185.     void lock() {
  186.         do_lock();
  187.         }
  188.  
  189.     void unlock() {
  190.         do_unlock();
  191.         }
  192.     };
  193.  
  194. #endif    // _MT
  195.  
  196.  
  197. /*---------------------------------------------------------------------------
  198.  *   Class ios:
  199.  *
  200.  *      I/O Status values and access members.
  201.  *
  202.  */
  203.  
  204. class ios _MT_ONLY(: public _mt_stream) {
  205.  
  206. //   Public constants and enumerations.
  207. public:
  208.     // Stream status
  209.     enum io_state   { 
  210.         goodbit    = 0x00,    // No error
  211.         eofbit    = 0x01,    // End-of-file reached
  212.         failbit     = 0x02,    // Insertion/extraction failed
  213.         range_errbit= 0x04,    // Value out of range
  214.         badbit    = 0x08,    // Access failed
  215.         hardfail    = 0x80     // Unrecoverable error
  216.         };
  217.  
  218.     // Stream I/O mode
  219.     enum open_mode  { 
  220.         in         = 0x01,    // Input
  221.         out         = 0x02,    // Output
  222.         ate         = 0x04,    // Seek to EOF at open
  223.         app         = 0x08,    // All operations append
  224.         trunc    = 0x10,    // Truncate file
  225.         nocreate = 0x20,    // Do not create file
  226.         noreplace= 0x40,    // Do not overwrite file
  227.         binary   = 0x80    // Binary file (no CR/LF translation).
  228.         };
  229.  
  230.     // Stream seek direction
  231.     enum seek_dir   { 
  232.         beg         = 0x00,    // Seek from beginning
  233.         cur         = 0x01,    // Seek from current position
  234.         end         = 0x02    // Seek from end
  235.         };
  236.  
  237.     // Formatting flags
  238.     enum        { 
  239.         skipws     = 0x01,    // Skip whitespace on input
  240.                        
  241.         left       = 0x02,    // Padding location
  242.         right      = 0x04,
  243.         internal   = 0x08,    // Between sign and digits
  244.                     
  245.         dec         = 0x10,    // Conversion base
  246.         oct         = 0x20,
  247.         hex         = 0x40,
  248.  
  249.         showbase   = 0x80,    // Show base on output (eg. 0x)
  250.         showpoint  = 0x100,    // Print trailing zeros,decimals
  251.         uppercase  = 0x200,    // Use uppercase E,X
  252.         showpos    = 0x400,    // Print leading + for positive
  253.                 // Floating point notation
  254.         scientific = 0x800,    // 5.6789e3
  255.         fixed      = 0x1000,// 5678.9 
  256.                             
  257.         unitbuf    = 0x2000,// Buffering--if set, flush after 
  258.                 // operation complete, not every character.
  259.         keepwidth  = 0x4000,// If set, width is NOT reset
  260.                 //  after each operation.
  261.         input_seps = 0x8000,// Allow digit separators on input.
  262.         char_width_1= 0x10000,// Char inserter ignores width setting.
  263.         fp_bases   = 0x20000,// Floating point inserters
  264.                 //  respect base setting.
  265.         stdio      = 0x40000// Flush stdout, stderr
  266.         };
  267.  
  268.     // Constants for use in second argument to setf().
  269.     static const long basefield;        //  dec | oct | hex;
  270.     static const long adjustfield;    //  left | right | internal;
  271.     static const long floatfield;        //  scientific | fixed;
  272.  
  273. private:
  274.     void        ios_check();
  275.     // Privates for implementing allocated bits and words.
  276.     static unsigned long     priv_nextbit;
  277.     static unsigned long     priv_nextword;
  278.     unsigned long     old_priv_nextword;  // unused. supposed to be static
  279.  
  280.     long        priv_numuwords;
  281.     union ios_user_union {
  282.         long    long_value;
  283.         void *    pointer_value;
  284.         };
  285.     ios_user_union*   priv_userwords;
  286.     int        priv_user_resize(long __newsize);
  287.  
  288.  
  289. protected:
  290.  
  291.             ios(ios&);        // Declared but not defined.
  292.     void        operator=(ios&);    // Causes error on copy.
  293.  
  294.             // Special flags
  295.     enum        { skipping=0x200,    // Skipping whitespace
  296.               tied=0x400        // Tied to another stream
  297.             };
  298.             
  299.     streambuf*    bp;            // streambuf for this ios
  300.  
  301.             // Set status to __new_state
  302.     void        _UNSAFE(setstate)(int __new_state) {
  303.                 state |= (__new_state & 0xff);
  304.                 }
  305.  
  306.     long        state;        // Userbits and error state
  307.     long        ispecial;    // Input special flags
  308.     long        ospecial;    // Output special flags
  309.     long        isfx_special;    // Input suffix special flags
  310.     long        osfx_special;    // Output suffix special flags
  311.     long        delbuf;
  312.  
  313.     long        x_flags;    // Formatting flags
  314.     short        x_width;    // Field width
  315.     short        x_precision;    // Precision
  316.     char        x_fill;        // Fill character
  317.     char        x_decimal;    // Decimal character
  318.     char        x_digsep;    // Digit separator character
  319.     short        x_sepfreq;    // Digit separator frequency
  320.     ostream*    x_tie;        // Link to tied output stream
  321.  
  322.     static void     (*_UNSAFE(stdioflush))();   // Function to flush stdio
  323.  
  324.             // Does the real work of a constructor.
  325.     void        init(streambuf* __buffer);
  326.  
  327.             ios();  // No initialization. Needed by
  328.                 //  multiple-inheritance versions.
  329.     int        assign_private; // Needed by with_assign classes.
  330.  
  331. public:
  332.  
  333.             ios(streambuf* __buffer);
  334.  
  335.     virtual        ~ios();
  336.  
  337.             // Read flags.
  338.     long        flags() const { return x_flags; }
  339.  
  340.             // Set flags, return previous.
  341.     long        _UNSAFE(flags)(long __newflags);
  342.  
  343.             // Set flags, return previous.
  344.     long        _UNSAFE(setf)(long __setbits, long __field);
  345.  
  346.             // Turn on bits set in __setbits, return previous value.
  347.     long        _UNSAFE(setf)(long __setbits);
  348.  
  349.             // Turn off bits set in __unsetbits, return prev.
  350.     long        _UNSAFE(unsetf)(long __unsetbits);
  351.  
  352.                 // Return current width.
  353.     int        width() const { return x_width; }
  354.  
  355.             // Set width, return previous value.
  356.     int        _UNSAFE(width)(int __new_width)  {
  357.                 int temp = x_width;
  358.                 x_width = __new_width;
  359.                 return temp;
  360.                 }
  361.  
  362.             // Read tie value.
  363.     ostream*    tie() const { return x_tie; }
  364.  
  365.               // Tie to __tie_stream.
  366.     ostream*    _UNSAFE(tie)(ostream* __tie_stream);
  367.  
  368.             // Read fill value.
  369.     char        fill() const { return x_fill; }
  370.  
  371.             // Set fill char to __fillc, return previous.
  372.     char        _UNSAFE(fill)(char __fillc);
  373.  
  374.             // Read decimal character
  375.     char        decimal_point() const { return x_decimal; }
  376.  
  377.             // Set decimal char to __decimalc, return previous.
  378.     char        _UNSAFE(decimal_point)(char __decimalc) {
  379.                 char tmp = x_decimal;
  380.                 if (__decimalc !=0) x_decimal = __decimalc;
  381.                 return tmp;
  382.                 }
  383.  
  384.             // Read digit separator character
  385.     char        digit_sep() const { return x_digsep; }
  386.  
  387.             // Set digit separator char to __sepchar
  388.     char        _UNSAFE(digit_sep)(char __sepchar) {
  389.                 char temp = x_digsep;
  390.                 x_digsep = __sepchar;
  391.                 return temp;
  392.                 }
  393.  
  394.             // Read digit separator character
  395.     int        digit_sep_freq() const { return x_sepfreq; }
  396.  
  397.             // Set digit separator frequenct to __sepfreq
  398.     int        _UNSAFE(digit_sep_freq)(char __sepfreq) {
  399.                 int temp = x_sepfreq;
  400.                 x_sepfreq = __sepfreq;
  401.                 return temp;
  402.                 }
  403.  
  404.             // Read current precision
  405.     int        precision() { return x_precision; }
  406.  
  407.             // Set precision to __prec, return previous.
  408.     int        _UNSAFE(precision)(int __prec);
  409.  
  410.             // Read state.
  411.     int        rdstate() const { return state; }
  412.  
  413.             // Typecast operator.
  414.             // Return valid pointer only if state is not bad.
  415.             operator void*() {
  416.                 if(state&(failbit|badbit|hardfail)) return NULL;
  417.                 else return this;
  418.                 }
  419.  
  420.             // Check state -- 0 if state is bad, 1 otherwise
  421.     int        operator!()
  422.                 { return (state&(failbit|badbit|hardfail)); }
  423.  
  424.             // Check for EOF
  425.     int        eof()   const { return (state&eofbit); }
  426.  
  427.             // Check for failed operation
  428.     int        fail()  const { return (state&(failbit|badbit|hardfail)); }
  429.  
  430.             // Check for unusable stream
  431.     int        hard_fail()  const { return (state&(hardfail)); }
  432.  
  433.             // Check for bad stream status
  434.     int        bad()   const { return (state&badbit); }
  435.  
  436.             // Check for range error status
  437.     int        range_err()   const { return (state&range_errbit); }
  438.  
  439.             // Check for good stream status
  440.     int        good()  const { return (state==0); }
  441.  
  442.             // Clear status, set to __init
  443.             // Note: Only modifies standard state flags
  444.     void        _UNSAFE(clear)(int __init = 0) {
  445.                 state =  (__init&0xff) | (state&hardfail);
  446.                 }
  447.  
  448.             // Clear status, set to __init
  449.             // Use this function to modify user-defined
  450.             //  state flags.
  451.             // This function is the same as clear(), except
  452.             //  that it modifies all state flags.
  453.     virtual void    _UNSAFE(set_err)(int __init = 0) {
  454.                 state =  __init | (state&hardfail);
  455.                 }
  456.  
  457.             // Get pointer to associated streambuf
  458.     streambuf*    rdbuf() { return bp;}
  459.  
  460.     // Members related to user-allocated bits and words.
  461.  
  462.             // Returns __index_num'th user-defined flag word.
  463.     long &        iword(int __index_num);
  464.  
  465.             // Returns __index_num'th user-defined flag word.
  466.     void* &        pword(int __index_num);
  467.  
  468.             // Returns a long with one previously-unused bit set.
  469.             // This can be used as a user error flag.
  470.     static long    bitalloc();
  471.  
  472.             // Returns a previously-unused index into an array of
  473.             //  words available for use as format state variables.
  474.             // For use by derived classes.
  475. #ifndef _OLD_IOSTREAM
  476.     static
  477. #endif
  478.     int    xalloc();
  479.  
  480.             // Allows mixed use of stdio FILE*'s and streams.
  481.             // Has an effect only the first time called.
  482.     static void    sync_with_stdio();
  483. #if _MT
  484. private:
  485.     static _mt_lock    static_mutex;        // mutex for static members
  486. protected:
  487.     void        setstate(int __new_state);
  488.     static void     (*stdioflush)();    // Function to flush stdio
  489. public:
  490.     long        flags(long __newflags);
  491.     long        setf(long __setbits, long __field);
  492.     long        setf(long __setbits);
  493.     long        unsetf(long __unsetbits);
  494.     int        width(int __new_width);
  495.     ostream*    tie(ostream* __tie_stream);
  496.     char        fill(char __fillc);
  497.     char        decimal_point(char __decimalc);
  498.     char        digit_sep(char __sepchar);
  499.     int        digit_sep_freq(char __sepfreq);
  500.     int        precision(int __prec);
  501.     void        clear(int __init = 0);
  502.     virtual void    set_err(int __init = 0);
  503. #endif
  504.     };
  505.  
  506. /*---------------------------------------------------------------------------
  507.  *   Class streambuf
  508.  *
  509.  *      Base stream-buffer class.
  510.  *
  511.  */
  512.  
  513. class streambuf _MT_ONLY(: public _mt_stream) {
  514.  
  515. private:
  516.     void        check_stat();
  517.     short        priv_alloc;    // TRUE == Delete buffer on setbuf
  518.     short        priv_unbuf;    // TRUE == unbuffered stream
  519.     char*        priv_base;    // Base of reserve area.
  520.     char*        priv_ebuf;    // Byte after end of reserve area.
  521.     char*        priv_pbase;    // Base of put area.
  522.     char*        priv_pptr;    // Current position in put area.
  523.     char*        priv_epptr;    // Byte after end of put area.
  524.     char*        priv_gptr;    // Current position in get area.
  525.     char*        priv_egptr;    // Byte after end of get area.
  526.     char*        priv_eback;    // Lower bound of gptr -- space
  527.                     //  available for putback.
  528.  
  529.     int        priv_snextc();
  530.     
  531. protected:
  532.             // Copy operators declared but not defined.
  533.             // Declaring as protected causes compiler to produce
  534.             //  an error if an assignment of a streambuf is 
  535.             //  attempted.  This is desirable, as assignment
  536.             //  of streambufs is not well-defined.
  537.             streambuf(streambuf&);
  538.     void        operator=(streambuf&);
  539.     
  540.             streambuf();
  541.             streambuf(char* __buf, int __len);
  542.  
  543.     char*        base()  const { return priv_base; }
  544.     char*        pbase() const { return priv_pbase; }
  545.     char*        pptr()  const { return priv_pptr; }
  546.     char*        epptr() const { return priv_epptr; }
  547.     char*        gptr()  const { return priv_gptr; }
  548.     char*        egptr() const { return priv_egptr; }
  549.     char*        eback() const { return priv_eback; }
  550.     char*        ebuf()  const { return priv_ebuf; }
  551.     int        _UNSAFE(blen)()  {
  552.                 return ((priv_ebuf>priv_base)
  553.                     ? (priv_ebuf-priv_base)
  554.                     : 0);
  555.                 }
  556.  
  557.     void        _UNSAFE(setp)(char*  __p, char*  __ep) {
  558.                 priv_pbase=priv_pptr=__p; priv_epptr=__ep;
  559.                 }
  560.  
  561.     void        _UNSAFE(setg)(char*  __eb, char*  __g, char*  __eg) {
  562.                 priv_eback=__eb; priv_gptr=__g; priv_egptr=__eg;
  563.                 }
  564.  
  565.     void        _UNSAFE(pbump)(int __num) {
  566.                 priv_pptr+=__num;
  567.                 }
  568.  
  569.     void        _UNSAFE(gbump)(int __num) {
  570.                 priv_gptr+=__num;
  571.                 }
  572.  
  573.     void        _UNSAFE(setb)(char* __b, char* __eb, int __a = 0 ) {
  574.                 if ( priv_alloc && priv_base ) delete priv_base;
  575.                 priv_base = __b;
  576.                 priv_ebuf = __eb;
  577.                 priv_alloc = __a;
  578.                 priv_unbuf = (__eb<=__b?1:0);
  579.                 }
  580.  
  581.     int        unbuffered() const { return priv_unbuf; }
  582.  
  583.     void        unbuffered(int __unb) { priv_unbuf = (__unb!=0); }
  584.  
  585.     int        _UNSAFE(allocate)() {
  586.                 if ( priv_base == 0 && !unbuffered() )
  587.                     return _UNSAFE(doallocate)();
  588.                 else
  589.                     return 0;
  590.                 }
  591.  
  592.     virtual int    _UNSAFE(doallocate)();
  593.     
  594.     virtual int    _UNSAFE(xsputn)(const char* __str, int __num);
  595.     virtual int    _UNSAFE(xsgetn)(char* __str,int __num);
  596.  
  597. public :
  598.     void        _UNSAFE(dbp)(int __level=0);
  599.     virtual int    _UNSAFE(overflow)(int __c=EOF);
  600.     virtual int    _UNSAFE(underflow)();
  601.     virtual int    _UNSAFE(pbackfail)(int __c);
  602.     virtual int    _UNSAFE(sync)();
  603.     
  604.     virtual streampos
  605.         _UNSAFE(seekoff)(streamoff __offset, ios::seek_dir __dir,
  606.                 long __mode=ios::in|ios::out);
  607.     virtual streampos
  608.         _UNSAFE(seekpos)(streampos __pos, long __mode=ios::in|ios::out);
  609.  
  610.     int        _UNSAFE(in_avail)() const {
  611.                 return (priv_gptr<priv_egptr
  612.                     ? priv_egptr-priv_gptr
  613.                     : 0);
  614.                 }
  615.  
  616.     int        _UNSAFE(out_waiting)() const {
  617.                 if ( priv_pptr ) return priv_pptr-priv_pbase;
  618.                 else return 0;
  619.                 }
  620.  
  621.             // *** WARNING: sgetc does not bump the get pointer
  622.     int        _UNSAFE(sgetc)() {
  623.                 return (priv_gptr>=priv_egptr)
  624.                     ? _UNSAFE(underflow)()
  625.                     : zapeof(*priv_gptr);
  626.                 }
  627.  
  628.     int        _UNSAFE(snextc)() {
  629.                 return (++priv_gptr>=priv_egptr)
  630.                     ? priv_snextc()
  631.                     : zapeof(*priv_gptr);
  632.                 }
  633.  
  634.     int        _UNSAFE(sbumpc)() {
  635.                 return ((priv_gptr>=priv_egptr
  636.                       && _UNSAFE(underflow)()==EOF)
  637.                     ? EOF
  638.                     : zapeof(*priv_gptr++));
  639.                 }
  640.  
  641.     void        _UNSAFE(stossc)() {
  642.                 if (priv_gptr>=priv_egptr) _UNSAFE(underflow)();
  643.                 else ++priv_gptr;
  644.                 }
  645.  
  646.     int        _UNSAFE(sputbackc)(char __c) {
  647.                 if (priv_gptr > priv_egptr) return EOF;
  648.                 if (priv_gptr > priv_eback ) {
  649.                     if ( *--priv_gptr == __c )
  650.                         return zapeof(__c);
  651.                     else return zapeof(*priv_gptr=__c);
  652.                     }
  653.                 else {
  654.                     return _UNSAFE(pbackfail)(__c);
  655.                     }
  656.                 }
  657.  
  658.     int        _UNSAFE(sputc)(int __c) {
  659.                 return (priv_pptr>=priv_epptr)
  660.                     ? _UNSAFE(overflow)((int)zapeof(__c))
  661.                     : zapeof(*priv_pptr++=__c);
  662.                 }
  663.  
  664.     int        _UNSAFE(sputn)(const char* __str,int __num) {
  665.                 if ( __num <= (priv_epptr-priv_pptr) ) {
  666.                     memcpy(priv_pptr, __str, __num);
  667.                     _UNSAFE(pbump)(__num);
  668.                     return __num;
  669.                     }
  670.                 else {
  671.                     return _UNSAFE(xsputn)(__str, __num);
  672.                     }
  673.                 }
  674.  
  675.     int        _UNSAFE(sgetn)(char* __str,int __num) {
  676.                 if ( __num <= (priv_egptr-priv_gptr) ) {
  677.                     memcpy(__str,(const char*)priv_gptr,
  678.                            __num);
  679.                     _UNSAFE(gbump)(__num);
  680.                     return __num;
  681.                     }
  682.                 else {
  683.                     return _UNSAFE(xsgetn)(__str, __num);
  684.                     }
  685.                 }
  686.  
  687.     virtual streambuf*
  688.             setbuf(char* __buf, int __len);
  689.  
  690.     streambuf*    setbuf(unsigned char* __buf, int __len) {
  691.                 return (setbuf((char*)__buf, __len));
  692.                 }
  693.  
  694.     virtual        ~streambuf();
  695. #if _MT
  696. protected:
  697.     int        blen();
  698.     void        setp(char*  __p, char*  __ep);
  699.     void        setg(char*  __eb, char*  __g, char*  __eg);
  700.     void        pbump(int __num);
  701.     void        gbump(int __num);
  702.     void        setb(char* __b, char* __eb, int __a = 0 );
  703.     int        allocate();
  704.     virtual int    doallocate();
  705.     virtual int    xsputn(const char* __str, int __num);
  706.     virtual int    xsgetn(char* __str,int __num);
  707. public :
  708.     void        dbp(int __level=0);
  709.     virtual int    overflow(int __c=EOF);
  710.     virtual int    underflow();
  711.     virtual int    pbackfail(int __c);
  712.     virtual int    sync();
  713.     virtual streampos
  714.         seekoff(streamoff __offset, ios::seek_dir __dir,
  715.                 long __mode=ios::in|ios::out);
  716.     virtual streampos
  717.         seekpos(streampos __pos, long __mode=ios::in|ios::out);
  718.     int        in_avail();
  719.     int        out_waiting();
  720.     int        sgetc();
  721.     int        snextc();
  722.     int        sbumpc();
  723.     void        stossc();
  724.     int        sputbackc(char __c);
  725.     int        sputc(int __c);
  726.     int        sputn(const char* __str,int __num);
  727.     int        sgetn(char* __str,int __num);
  728. #endif
  729.     };
  730.  
  731.  
  732. /*---------------------------------------------------------------------------
  733.  *   Class istream
  734.  *
  735.  */
  736.  
  737. class istream : virtual public ios {
  738.  
  739. private:
  740.     int        priv_gcount;        // Keep track of # of chars
  741.                         //  last extracted.
  742.     void        ischeck_state();
  743.     void        _doget(char* __c);    // Actually does a get.
  744.  
  745. protected:
  746.     int        _UNSAFE(do_ipfx)(int __noskipws);
  747.     void        _UNSAFE(do_isfx)();
  748.     int        _UNSAFE(eatwhite)(void);
  749.             istream();
  750.             
  751. public:
  752.             istream(streambuf *__buffer);
  753.     virtual        ~istream();
  754.     
  755.     int        _UNSAFE(ipfx)(int __noskipws=0) {
  756.                 if ( __noskipws?(ispecial&~skipping):ispecial) {
  757.                     return _UNSAFE(do_ipfx)(__noskipws);
  758.                     }
  759.                 else return 1;
  760.                 }
  761.  
  762.     void        _UNSAFE(isfx)() {
  763.                 if (isfx_special) _UNSAFE(do_isfx)();
  764.                 }
  765.  
  766.     istream&    seekg(streampos __position);
  767.     istream&    seekg(streamoff __offset, ios::seek_dir __dir);
  768.  
  769.             // Returns the current offset into the get buffer.
  770.     streampos    tellg();
  771.  
  772.             // For manipulators.
  773.     istream&    operator>> (istream& (*__fcn)(istream&)) {
  774.                 return (*__fcn)(*this);
  775.                 }
  776.  
  777.             // For manipulators.
  778.     istream&    operator>> (ios& (*__fcn)(ios&) );
  779.  
  780.     istream&    operator>>(char *__cp);
  781.     istream&    operator>>(unsigned char *__ucp);
  782.     istream&    operator>>(unsigned char &__ucr);
  783.     istream&    operator>>(char& __cr);
  784.     istream&    operator>>(short& __sr);
  785.     istream&    operator>>(int& __ir);
  786.     istream&    operator>>(long& __lr);
  787.     istream&    operator>>(unsigned short& __usr);
  788.     istream&    operator>>(unsigned int& __uir);
  789.     istream&    operator>>(unsigned long& __ulr);
  790.     istream&    operator>>(float& __fr);
  791.     istream&    operator>>(double& __dr);
  792.     istream&    operator>>(long double& __ldr);
  793.     istream&    operator>>(streambuf* __sp);
  794.  
  795.             // Read and extract characters ending in delim,
  796.             //  up to a maximum of lim characters.
  797.             // delim IS NOT stored in buffer.
  798.     istream&    get(char* __buffer, int __lim, char __delim='\n');
  799.     istream&    get(unsigned char* __buffer, int __lim, char __delim='\n');
  800.     istream&    get(char* __buffer, int __lim, char *__delims);
  801.     istream&    get(unsigned char* __buffer, int __lim, char *__delims);
  802.  
  803.             // Read and extract characters ending in delim,
  804.             //  up to a maximum of lim characters.
  805.             // delim IS stored in buffer if space allows.
  806.     istream&    getline(char* __buffer, int __lim, char __delim='\n');
  807.     istream&    getline(unsigned char* __buffer,int __lim, char __delim='\n'); 
  808.     istream&    getline(char* __buffer, int __lim, char *__delims);
  809.     istream&    getline(unsigned char* __buffer,int __lim, char *__delims); 
  810.             // Read and extract character.
  811.     istream&    get(streambuf& __sb, char __delim ='\n');
  812.     istream&    get(unsigned char& __c);
  813.     istream&    get(char& __c);
  814.     int        _UNSAFE(get)();
  815.  
  816.             // Read next character, but don't extract.
  817.     int        _UNSAFE(peek)() {
  818.                 if ( _UNSAFE(ipfx)(-1) )
  819.                     return rdbuf()->_UNSAFE(sgetc)();
  820.                 else return EOF;
  821.                 }
  822.  
  823.             // Extract and trash n characters, stopping
  824.             //  if delim is encountered.
  825.     istream&    ignore(int __num=1,int __delim=EOF);
  826.  
  827.     istream&    read(char* __buf,int __num);
  828.     istream&    read(unsigned char* __buf,int __num) {
  829.                 return read((char*)__buf,__num);
  830.                 }
  831.     int        gcount() { return priv_gcount; }
  832.     istream&    putback(char __c);
  833.     int        _UNSAFE(sync)()  { return rdbuf()->_UNSAFE(sync)(); }
  834.  
  835. #if _MT
  836. protected:
  837.     int        do_ipfx(int __noskipws);
  838.     void        do_isfx();
  839.     int        eatwhite(void);
  840. public:
  841.     int        ipfx(int __noskipws=0);
  842.     void        isfx();
  843.     int        peek();
  844.     int        sync();
  845.     int        get();
  846.     istream&    operator_shrd_unsafe(double& __dr);
  847.     istream&    operator_shrc_unsafe(char& __cr);
  848. #endif
  849.     };
  850.  
  851.  
  852. /*---------------------------------------------------------------------------
  853.  *   Class ostream
  854.  *
  855.  */
  856.  
  857. class ostream : virtual public ios {
  858.  
  859. protected:
  860.     int        _UNSAFE(do_opfx)();
  861.     void        _UNSAFE(do_osfx)();
  862.             ostream();
  863.  
  864. public:
  865.             ostream(streambuf *__sbp);
  866.     virtual        ~ostream();
  867.  
  868.     int        _UNSAFE(opfx)() {
  869.                 if (!good()) return 0;
  870.                 else if (ospecial) return _UNSAFE(do_opfx)();
  871.                 else return 1;
  872.                 }
  873.  
  874.     void        _UNSAFE(osfx)() {
  875.                 if (osfx_special) _UNSAFE(do_osfx)();
  876.                 }
  877.  
  878.     ostream&    _UNSAFE(flush)();
  879.  
  880.     ostream&    seekp(streampos __pos);
  881.     ostream&    seekp(streamoff __off, ios::seek_dir __dir);
  882.     streampos    tellp();
  883.  
  884.     ostream&    put(char __c);
  885.  
  886.     ostream&    operator<<(char __c) {
  887.                 return put(__c);
  888.                 }
  889.  
  890.     ostream&    operator<<(unsigned char __uc) {
  891.                 return put(__uc);
  892.                 }
  893.  
  894.     ostream&    operator<<(const char* __ccp);
  895.     ostream&    operator<<(int __i);
  896.     ostream&    operator<<(long __l);
  897.     ostream&    operator<<(double __d);
  898.     ostream&    operator<<(long double __ld);
  899.     ostream&    operator<<(float __f);
  900.     ostream&    operator<<(unsigned int  __ui);
  901.     ostream&    operator<<(unsigned long __ul);
  902.     ostream&    operator<<(void* __vp);
  903.     ostream&    operator<<(streambuf* __sbp);
  904.     ostream&    operator<<(short __s);
  905.     ostream&    operator<<(unsigned short __us);
  906.  
  907.             // For manipulators.
  908.     ostream&    operator<<(ostream& (*__fcn)(ostream&)) {
  909.                 return (*__fcn)(*this);
  910.                 }
  911.  
  912.             // For manipulators.
  913.     ostream&    operator<<(ios& (*__fcn)(ios&) );
  914.  
  915.     ostream&    write(const char* __str,int __num);
  916.     ostream&    write(const unsigned char* __str, int __num) {
  917.                 return write((const char*)__str,__num);
  918.                 }
  919. #if _MT
  920. protected:
  921.     int            do_opfx();
  922.     void        do_osfx();
  923. public:
  924.     int            opfx();
  925.     void        osfx();
  926.     ostream&        flush();
  927.     ostream&        operator_shlccp_unsafe(const char *__ccp);
  928. #endif
  929.     };
  930.  
  931. /*---------------------------------------------------------------------------
  932. */
  933. class iostream : public istream, public ostream {
  934. protected:
  935.             iostream();
  936.  
  937. public:
  938.             iostream(streambuf* __sbp);
  939.     virtual        ~iostream();
  940.     };
  941.  
  942.  
  943. class istream_withassign : public istream {
  944. public:
  945.                 istream_withassign();
  946.     virtual            ~istream_withassign();
  947.     istream_withassign&    operator=(istream&);
  948.     istream_withassign&    operator=(streambuf*);
  949.     };
  950.  
  951.  
  952. class ostream_withassign : public ostream {
  953. public:
  954.                 ostream_withassign();
  955.     virtual            ~ostream_withassign();
  956.     ostream_withassign&    operator=(ostream&);
  957.     ostream_withassign&    operator=(streambuf*);
  958.     };
  959.  
  960.  
  961. class iostream_withassign : public iostream {
  962. public:
  963.                 iostream_withassign();
  964.     virtual            ~iostream_withassign();
  965.     iostream_withassign&    operator=(ios&);
  966.     iostream_withassign&    operator=(streambuf*);
  967.     };
  968. #pragma pop(nodebug)
  969.  
  970. /*---------------------------------------------------------------------------
  971. */
  972. extern istream_withassign cin;
  973. extern ostream_withassign cout;
  974. extern ostream_withassign cerr;
  975. extern ostream_withassign clog;
  976. #ifdef _MSDOS
  977. // Additional standard streams provided under DOS
  978. extern ostream_withassign caux;
  979. extern ostream_withassign cprn;
  980. #endif
  981.  
  982. extern ostream&        endl(ostream& os);
  983. extern ostream&        ends(ostream& os);
  984. extern ostream&        flush(ostream& os);
  985. extern ios&        dec(ios& iosr);
  986. extern ios&        oct(ios& iosr);
  987. extern ios&        hex(ios& iosr);
  988. extern istream&        ws(istream& is);
  989.  
  990. #if _MSNT && _DLL && !_DLLBUILD
  991.     #pragma pop(dllimport);
  992. #endif
  993.  
  994.  
  995. #if _NONEXCEPT_LIB
  996.     #pragma pop(exception_aware_class);
  997. #elif _MSDOS || _MSNT || _OS2
  998.     #pragma pop(exception_aware_class);
  999. #endif
  1000.  
  1001. #pragma pop(try_static_cast)
  1002. #pragma pop(Behaved)
  1003. #pragma pop_align_members();
  1004. #endif
  1005.  
  1006.  
  1007. /**      Copyright (c) 1991-1993, MetaWare Incorporated         **/
  1008.