home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / SASC6571.LZX / cxxinclude / fstream.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-24  |  11.3 KB  |  390 lines

  1. /* Copyright (c) 1993             by SAS Institute Inc., Cary NC     */
  2.  
  3. #ifndef __FSTREAM_H
  4. #define __FSTREAM_H
  5.  
  6. #ifndef _STDDEFH
  7. #include <stddef.h>
  8. #endif
  9.  
  10. #ifndef __IOSTREAM_H
  11. #include <iostream.h>
  12. #endif
  13.  
  14. /*********
  15. This header file file provides four classes:
  16. filebuf and ifstream, ofstream, and fstream which associate 
  17. a filebuf with an istream, an ostream, and a iostream respectivly.
  18.  
  19. class filebuf - the current version of filebuf communicates
  20. with the world through FILE*s.  This is not the same as AT&T
  21. derived systems, which use UNIX-I/O.  It is quite posible
  22. that in the future filebufs use a lower lever I/O mechinism
  23. for speed.
  24.  
  25. *********/
  26.  
  27. extern "C++" {
  28.  
  29. class  filebuf : public streambuf {
  30.     public:
  31.  
  32.              //  Create an unopened file.
  33.       filebuf() : x_file(0) { }
  34.       
  35.             // Close the file, if open
  36.       virtual ~filebuf() _INLINE_FUNC({ if ( is_open() ) close(); })
  37.  
  38.  
  39.            // Return non-zero if open, zero otherwise.
  40.       int is_open() _INLINE_FUNC({ return x_file != NULL; })
  41.  
  42.  
  43.            // Open file 'file_name', return 0 if error.
  44.       filebuf* open(const char *file_name, int mode,
  45.                     const char* amparms = "", const char* am = "");
  46.  
  47.  
  48.            // Close currently open file.
  49.       filebuf* close();
  50.  
  51.  
  52.            // Set the get AND put pointers to a new position.
  53.       virtual streampos seekoff(streamoff, ios::seek_dir, 
  54.                                            int =ios::in|ios::out);
  55.       virtual streampos seekpos(streampos, int =ios::in|ios::out);
  56.  
  57.       virtual streambuf* setbuf(char* p, size_t len );
  58.  
  59.       virtual int sync();
  60.           // Any characters in the put area are written to the file.
  61.           // Any characters in the get area are written back to the file.
  62.           // The get and put area are both set to empty.
  63.           // Returns 0 unless error, in which case it returns EOF.
  64.  
  65.  
  66.     protected:
  67.  
  68.     /*
  69.     Buffer management for filebuf:
  70.       The reserve buffer is used by filebuf, which means that
  71.       base() and ebuf() are set to point to the beginning and
  72.       and of the reserve area, and that the get and put areas
  73.       reside within the reserve area.
  74.  
  75.       At any particular time only one of the two areas (get
  76.       or put) exists.  Since most files are either used for
  77.       input or output only, this seems most efficient.  For
  78.       those filebufs that must handle both input and output,
  79.       the current area (get or put) is flushed each time
  80.       the other area is needed.  This switching happens
  81.       any time the current operation (read or write) is opposite
  82.       from the last operation.
  83.     */
  84.  
  85.       virtual int doallocate();
  86.  
  87.       virtual int overflow( int c=EOF );
  88.           /*
  89.           is called by streambuf::sputc() to send a
  90.           character in to the file.
  91.  
  92.           If an error occurs in this function, it will return EOF,
  93.           and the filebuf will have an undefined state.
  94.  
  95.           Possible errors are: the file is not open, the file
  96.           is only open for reading, the reserve area could not
  97.           be allocated by allocate(), or a system error occured
  98.           during a write to the file.
  99.  
  100.           If no errors occur this function will do the following:
  101.               Call streambuf::allocate().
  102.               Flush the get area, if it exists, back to the file.
  103.               Write any characters in the put area to the file.
  104.               Write the 'c' character to the file.
  105.               Set the size of the put area to be one less than the
  106.                 size of the reserve area, and make the put area empty.
  107.               Returns 'c' unless 'c' == EOF in which case it returns 0.
  108.         */
  109.  
  110.       virtual int underflow();
  111.           /*
  112.           is called by streambuf::sgetn() to read a character from
  113.           the file.
  114.  
  115.           If an error occurs in this function, it will return EOF,
  116.           and the filebuf will have an undefined state.
  117.  
  118.           Possible errors are: the file
  119.           is not open for reading, the reserve area could not
  120.           be allocated by allocate(), or a system error occured
  121.           during a read from the file.
  122.  
  123.           If no errors occur this function will do the following:
  124.               Call streambuf::allocate().
  125.               Flush the put area, if it exists, back to the file.
  126.               Return the character at the get pointer
  127.         */
  128.  
  129.       virtual int xsputn( const char* s, int n );
  130.           /*
  131.           is called by streambuf::sputn() to send the 'n' characters
  132.           in 's' to the file.
  133.  
  134.           If an error occurs in this function, it will return
  135.           a number less than 'n' indicating the number of
  136.           characters in 's' that were written to the file before
  137.           the error, and the filebuf will have an undefined state.
  138.  
  139.           Possible errors are: the file
  140.           is not open for writing, the reserve area could not
  141.           be allocated by allocate(), or a system error occured
  142.           during a write to the file.
  143.  
  144.           If no errors occur this function will do the following:
  145.               Call streambuf::allocate().
  146.               Flush the get area, if it exists, back to the file.
  147.               Write any characters in the put area to the file.
  148.               Write the 'n' characters pointed at by 's' to the file.
  149.               Set the size of the put area to be one less than the
  150.                 size of the reserve area, and make the put area empty.
  151.               Return 'n'
  152.         */
  153.  
  154.       virtual int xsgetn( char* s, int n );
  155.           /*
  156.           is called by streambuf::sgetn() to read 'n' characters from
  157.           the file into 's'.
  158.  
  159.           If an error occurs in this function, it will return
  160.           a number less than 'n' indicating the number of
  161.           characters in 's' that were read from the file before
  162.           the error, and the filebuf will have an undefined state.
  163.  
  164.           Possible errors are: the file
  165.           is not open for reading, the reserve area could not
  166.           be allocated by allocate(), or a system error occured
  167.           during a read from the file.
  168.  
  169.           If no errors occur this function will do the following:
  170.               Call streambuf::allocate().
  171.               Flush the put area, if it exists, back to the file.
  172.               's' will contain the next 'n' characters from the file.
  173.               The get area will contain any characters read from the
  174.                   file but not returned in 's'.
  175.               Return 'n'.
  176.         */
  177.  
  178.       virtual int pbackfail( int );
  179.           /*
  180.           is called by streambuf::sputbackc().
  181.  
  182.           Moves the get pointer back one character.
  183.           If this succeeds this function returns the new character
  184.           at the get pointer, otherwise this function returns EOF
  185.           */
  186.  
  187.  
  188.     private:
  189.       FILE* x_file;
  190.           // The attached file.
  191.  
  192.       fpos_t x_pos;
  193.           // If the get area is not empty, this contains the file
  194.           // position of the first character in the get area.
  195.           // This is used to re-sync the file by overflow() and
  196.           // xsputn() (and indirectly by sync()).
  197.  
  198.       int mode;
  199.           // The open mode.
  200.  
  201.       char lahead[1];
  202.     };
  203.  
  204.  
  205.  
  206. class fstream : public iostream {
  207.     public:
  208.  
  209.           // create an unopened fstream
  210.       fstream() : ios( &buffer ) {}
  211.  
  212.           // create and open an fstream
  213.       fstream( const char* _name, 
  214.                int _mode,
  215.                const char* _amparms = "", const char* _am = "")
  216.         _INLINE_FUNC(
  217.           : ios( &buffer )
  218.           {
  219.           open( _name, _mode, _amparms, _am );
  220.           }
  221.         )
  222.  
  223.           // Close the file, if open (it works try it)
  224.       virtual ~fstream() {}
  225.  
  226.  
  227.           // Open a file using an unopened fstream, clear state if no error
  228.       void open( const char* _name, 
  229.                  int _mode,
  230.                  const char* _amparms = "", const char* _am = "")
  231.         _INLINE_FUNC(
  232.           {
  233.           clear( 
  234.               buffer.open( _name, _mode, _amparms, _am )
  235.                   ? 0
  236.                   : ( ios::failbit | rdstate() ));
  237.           }
  238.         )
  239.  
  240.           // Close an opened file and clear the state if no error.
  241.       void close()
  242.         _INLINE_FUNC(
  243.           {
  244.           clear( buffer.close() ? 0 : (ios::failbit | rdstate()) );
  245.           }
  246.         )
  247.  
  248.  
  249.       void setbuf(char* _p, size_t _len )  
  250.        _INLINE_FUNC(
  251.           {
  252.           if ( buffer.setbuf( _p, _len ) )
  253.               clear( ios::failbit | rdstate() );
  254.           }
  255.        )
  256.  
  257.  
  258.       filebuf*  rdbuf() _INLINE_FUNC({ return &buffer; })
  259.  
  260.  
  261.     private:
  262.       filebuf buffer;
  263.  
  264.     };
  265.  
  266. class ifstream : public istream {
  267.     public:
  268.  
  269.           // create an unopened ifstream
  270.       ifstream() : ios( &buffer ) {}
  271.  
  272.           // create and open an ifstream
  273.       ifstream( const char* _name, 
  274.                int _mode = ios::in,
  275.                const char* _amparms = "", const char* _am = "")
  276.         _INLINE_FUNC(
  277.           : ios( &buffer )
  278.           {
  279.           open( _name, _mode, _amparms, _am );
  280.           }
  281.         )
  282.  
  283.           // Close the file, if open
  284.       virtual ~ifstream() {}
  285.  
  286.  
  287.           // Open a file using an unopened ifstream, clear state if no error
  288.       void open( const char* _name, 
  289.                  int _mode = ios::in,
  290.                  const char* _amparms = "", const char* _am = "")
  291.        _INLINE_FUNC(
  292.           {
  293.           clear( 
  294.               buffer.open( _name, _mode | ios::in, _amparms, _am )
  295.                   ? 0
  296.                   : ( ios::failbit | rdstate() ));
  297.           }
  298.        )
  299.  
  300.  
  301.           // Close an opened file and clear the state if no error.
  302.       void close()
  303.         _INLINE_FUNC(
  304.           {
  305.           clear( buffer.close() ? 0 : (ios::failbit | rdstate()) );
  306.           }
  307.         )
  308.  
  309.  
  310.       void setbuf(char* _p, size_t _len )  
  311.         _INLINE_FUNC(
  312.           {
  313.           if ( buffer.setbuf( _p, _len ) )
  314.               clear( ios::failbit | rdstate() );
  315.           }
  316.         )
  317.  
  318.  
  319.       filebuf*  rdbuf() _INLINE_FUNC({ return &buffer; })
  320.  
  321.  
  322.     private:
  323.       filebuf buffer;
  324.  
  325.     };
  326.  
  327. class ofstream : public ostream {
  328.     public:
  329.  
  330.           // create an unopened ofstream
  331.       ofstream() : ios( &buffer ) {}
  332.  
  333.           // create and open an ofstream
  334.       ofstream( const char* _name, 
  335.                int _mode = ios::out,
  336.                const char* _amparms = "", const char* _am = "")
  337.        _INLINE_FUNC(
  338.           : ios( &buffer )
  339.           {
  340.           open( _name, _mode, _amparms, _am );
  341.           }
  342.        )
  343.  
  344.           // Close the file, if open (it works try it)
  345.       virtual ~ofstream() {}
  346.  
  347.  
  348.           // Open a file using an unopened ofstream, clear state if no error
  349.       void open( const char* _name, 
  350.                  int _mode = ios::out,
  351.                  const char* _amparms = "", const char* _am = "")
  352.        _INLINE_FUNC(
  353.           {
  354.           clear( 
  355.               buffer.open( _name, _mode | ios::out, _amparms, _am )
  356.                   ? 0
  357.                   : ( ios::failbit | rdstate() ));
  358.           }
  359.         )
  360.  
  361.  
  362.           // Close an opened file and clear the state if no error.
  363.       void close()
  364.        _INLINE_FUNC(
  365.           {
  366.           clear( buffer.close() ? 0 : (ios::failbit | rdstate()) );
  367.           }
  368.        )
  369.  
  370.  
  371.       void setbuf(char* _p, size_t _len )  
  372.        _INLINE_FUNC(
  373.           {
  374.           if ( buffer.setbuf( _p, _len ) )
  375.               clear( ios::failbit | rdstate() );
  376.           }
  377.         )
  378.  
  379.  
  380.       filebuf*  rdbuf() _INLINE_FUNC({ return &buffer; })
  381.  
  382.  
  383.     private:
  384.       filebuf buffer;
  385.  
  386.     };
  387. }
  388.  
  389. #endif /* __FSTREAM_H */
  390.