home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / msdos / djgpp / cplusinc / streambu.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-31  |  11.9 KB  |  354 lines

  1. //    This is part of the iostream library, providing -*- C++ -*- input/output.
  2. //    Copyright (C) 1991 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. //
  18. //    NOTE:
  19. //      This file was modified for DOS compatibility: Flag "ios::binary"
  20. //      was defined so that file streams can be opened in binary mode.
  21. //
  22. //                                                  J-F Gallant,
  23. //                                                  October 1st, 1992.
  24.  
  25. #ifndef _STREAMBUF_H
  26. #define _STREAMBUF_H
  27. #ifdef __GNUG__
  28. #pragma interface
  29. #endif
  30.  
  31. #include <_G_config.h>
  32. #ifndef fpos_t
  33. #define fpos_t _G_fpos_t
  34. #endif
  35.  
  36. #ifndef EOF
  37. #define EOF (-1)
  38. #endif
  39. #ifndef NULL
  40. #define NULL ((void*)0)
  41. #endif
  42. #ifndef BUFSIZ
  43. #define BUFSIZ 4096
  44. #endif
  45.  
  46. class ostream; class streambuf;
  47.  
  48. typedef long streamoff, streampos;
  49.  
  50. struct _ios_fields { // The data members of an ios.
  51.     streambuf *_strbuf;
  52.     ostream* _tie;
  53.     int _width;
  54.     unsigned long _flags;
  55.     char _fill;
  56.     unsigned char _state;
  57.     unsigned short _precision;
  58. };
  59.  
  60. #define _IOS_GOOD    0
  61. #define _IOS_EOF    1
  62. #define _IOS_FAIL    2
  63. #define _IOS_BAD    4
  64.  
  65. #define _IOS_INPUT    1
  66. #define _IOS_OUTPUT    2
  67. #define _IOS_ATEND    4
  68. #define _IOS_APPEND    8
  69. #define _IOS_TRUNC    16
  70. #define _IOS_NOCREATE    32
  71. #define _IOS_NOREPLACE    64
  72. #define _IOS_BINARY 128
  73.  
  74. #ifdef _STREAM_COMPAT
  75. enum state_value {
  76.     _good = _IOS_GOOD,
  77.     _eof = _IOS_EOF,
  78.     _fail = _IOS_FAIL,
  79.     _bad = _IOS_BAD };
  80. enum open_mode {
  81.     input = _IOS_INPUT,
  82.     output = _IOS_OUTPUT,
  83.     atend = _IOS_ATEND,
  84.     append = _IOS_APPEND,
  85.     binary = _IOS_BINARY };
  86. #endif
  87.  
  88. class ios : public _ios_fields {
  89.   public:
  90.     enum io_state {
  91.     goodbit = _IOS_GOOD,
  92.     eofbit = _IOS_EOF,
  93.     failbit = _IOS_FAIL,
  94.     badbit = _IOS_BAD };
  95.     enum open_mode {
  96.     in = _IOS_INPUT,
  97.     out = _IOS_OUTPUT,
  98.     ate = _IOS_ATEND,
  99.     app = _IOS_APPEND,
  100.     trunc = _IOS_TRUNC,
  101.     nocreate = _IOS_NOCREATE,
  102.     noreplace = _IOS_NOREPLACE,
  103.     binary = _IOS_BINARY };
  104.     enum seek_dir { beg, cur, end};
  105.     enum { skipws=01, left=02, right=04, internal=010,
  106.        dec=020, oct=040, hex=0100,
  107.        showbase=0200, showpoint=0400, uppercase=01000, showpos=02000,
  108.        scientific=04000, fixed=0100000, unitbuf=020000, stdio=040000,
  109.        dont_close=0x80000000 //Don't close streambuf when destroying stream
  110.        };
  111.  
  112.     ostream* tie() const { return _tie; }
  113.     ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
  114.  
  115.     // Methods to change the format state.
  116.     char fill() const { return _fill; }
  117.     char fill(char newf) { char oldf = _fill; _fill = newf; return oldf; }
  118.     unsigned long flags() const { return _flags; }
  119.     unsigned long flags(unsigned long new_val) {
  120.     unsigned long old_val = _flags; _flags = new_val; return old_val; }
  121.     unsigned short precision() const { return _precision; }
  122.     unsigned short precision(int newp) {
  123.     unsigned short oldp = _precision; _precision = (unsigned short)newp;
  124.     return oldp; }
  125.     unsigned long setf(unsigned long val) {
  126.     unsigned long oldbits = _flags;
  127.     _flags |= val; return oldbits; }
  128.     unsigned long setf(unsigned long val, unsigned long mask) {
  129.     unsigned long oldbits = _flags;
  130.     _flags = (_flags & ~mask) | (val & mask); return oldbits; }
  131.     unsigned long unsetf(unsigned long mask) {
  132.     unsigned long oldbits = _flags & mask;
  133.     _flags &= ~mask; return oldbits; }
  134.     int width() const { return _width; }
  135.     int width(int val) { int save = _width; _width = val; return save; }
  136.  
  137.     static const unsigned long basefield;
  138.     static const unsigned long adjustfield;
  139.     static const unsigned long floatfield;
  140.  
  141.     streambuf* rdbuf() const { return _strbuf; }
  142.     void clear(int state = 0) { _state = state; }
  143.     int good() const { return _state == 0; }
  144.     int eof() const { return _state & ios::eofbit; }
  145.     int fail() const { return _state & (ios::badbit|ios::failbit); }
  146.     int bad() const { return _state & ios::badbit; }
  147.     int rdstate() const { return _state; }
  148.     void set(int flag) { _state |= flag; }
  149.     operator void*() const { return fail() ? (void*)0 : (void*)this; }
  150.     int operator!() const { return fail(); }
  151.  
  152. #ifdef _STREAM_COMPAT
  153.     void unset(state_value flag) { _state &= ~flag; }
  154.     void close();
  155.     int is_open();
  156.     int readable();
  157.     int writable();
  158. #endif
  159.  
  160.   protected:
  161.     ios(streambuf*sb) { _strbuf=sb; _state=0; _width=0; _fill=' ';
  162.             _flags=ios::skipws; _precision=6; }
  163. };
  164.  
  165. #if __GNUG__==1
  166. typedef int _seek_dir;
  167. #else
  168. typedef ios::seek_dir _seek_dir;
  169. #endif
  170.  
  171. // Magic numbers and bits for the _flags field.
  172. // The magic numbers use the high-order bits of _flags;
  173. // the remaining bits are abailable for variable flags.
  174. // Note: The magic numbers must all be negative if stdio
  175. // emulation is desired.
  176.  
  177. #define _IO_MAGIC 0xFBAD0000 /* Magic number */
  178. #define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
  179. #define _IO_MAGIC_MASK 0xFFFF0000
  180. #define _S_USER_BUF 1 /* User owns buffer; don't delete it on close. */
  181. #define _S_UNBUFFERED 2
  182. #define _S_CAN_READ 4
  183. #define _S_CAN_WRITE 8
  184. #define _S_EOF_SEEN 16
  185. #define _S_ERR_SEEN 32
  186. #define _S_DELETE_DONT_CLOSE 64
  187. #define _S_LINKED 128 // Set if linked (using _chain) to streambuf::_list_all.
  188. #define _S_LINE_BUF 0x4000
  189. #define _S_IS_FILEBUF 0x8000
  190.  
  191. #if 0
  192. // A streammarker remembers a position in a buffer.
  193. // You are guaranteed to be able to seek back to it.
  194. class streammarker {
  195.     struct streammarker *_next;
  196.     streambuf *_buf;
  197.     char *_pos; ???
  198.   public:
  199.     streammarker(streambuf *sb);
  200.     ~streamarker();
  201. };
  202. #endif
  203.  
  204. struct __streambuf {
  205.     // NOTE: If this is changed, also change __FILE in stdio/stdio.h!
  206.     int _flags;        /* High-order word is _IO_MAGIC; rest is flags. */
  207.     char* _gptr;    /* Current get pointer */
  208.     char* _egptr;    /* End of get area. */
  209.     char* _eback;    /* Start of putback+get area. */
  210.     char* _pbase;    /* Start of put area. */
  211.     char* _pptr;    /* Current put pointer. */
  212.     char* _epptr;    /* End of put area. */
  213.     char* _base;    /* Start of reserve area. */
  214.     char* _ebuf;    /* End of reserve area. */
  215.     struct streambuf *_chain;
  216. #if 0 // Work in progress
  217.     int _collumn; // Current collumn in line at _pbase; -1 if unknown.
  218.     streammarker *_markers;
  219. #endif
  220. };
  221.  
  222. struct streambuf : private __streambuf {
  223.     friend class ios;
  224.     friend class istream;
  225.     friend class ostream;
  226.   protected:
  227.     static streambuf* _list_all; /* List of open streambufs. */
  228.     streambuf*& xchain() { return _chain; }
  229.     void _un_link();
  230.     void _link_in();
  231.     char* gptr() const { return _gptr; }
  232.     char* pptr() const { return _pptr; }
  233.     char* egptr() const { return _egptr; }
  234.     char* epptr() const { return _epptr; }
  235.     char* pbase() const { return _pbase; }
  236.     char* eback() const { return _eback; }
  237.     char* ebuf() const { return _ebuf; }
  238.     char* base() const { return _base; }
  239.     void xput_char(char c) { *_pptr++ = c; }
  240.     int xflags() { return _flags; }
  241.     int xflags(int f) { int fl = _flags; _flags = f; return fl; }
  242.     void xsetflags(int f) { _flags |= f; }
  243.     void gbump(int n) { _gptr += n; }
  244.     void pbump(int n) { _pptr += n; }
  245.     void setb(char* b, char* eb, int a=0);
  246.     void setp(char* p, char* ep) { _pbase=(_pptr=p); _epptr=ep; }
  247.     void setg(char* eb, char* g, char *eg) { _eback=eb; _gptr=g; _egptr=eg; }
  248.   public:
  249.     static int flush_all();
  250.     static void flush_all_linebuffered(); // Flush all line buffered files.
  251.     virtual int underflow(); // Leave public for now
  252.     virtual int overflow(int c = EOF); // Leave public for now
  253.     virtual int doallocate();
  254.     virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
  255.     virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
  256.     int sputbackc(char c);
  257.     int sungetc();
  258.     streambuf();
  259.     virtual ~streambuf();
  260.     int unbuffered() { return _flags & _S_UNBUFFERED ? 1 : 0; }
  261.     int linebuffered() { return _flags & _S_LINE_BUF ? 1 : 0; }
  262.     void unbuffered(int i)
  263.     { if (i) _flags |= _S_UNBUFFERED; else _flags &= ~_S_UNBUFFERED; }
  264.     void linebuffered(int i)
  265.     { if (i) _flags |= _S_LINE_BUF; else _flags &= ~_S_LINE_BUF; }
  266.     int allocate() {
  267.     if (base() || unbuffered()) return 0;
  268.     else return doallocate(); }
  269.     virtual int sync();
  270.     virtual int pbackfail(int c);
  271.     virtual int ungetfail();
  272.     virtual streambuf* setbuf(char* p, int len);
  273.     int in_avail() { return _egptr - _gptr; }
  274.     int out_waiting() { return _pptr - _pbase; }
  275.     virtual int sputn(const char* s, int n);
  276.     virtual int sgetn(char* s, int n);
  277.     long sgetline(char* buf, _G_size_t n, char delim, int putback_delim);
  278.     int sbumpc() {
  279.     if (_gptr >= _egptr && underflow() == EOF) return EOF;
  280.     else return *(unsigned char*)_gptr++; }
  281.     int sgetc() {
  282.     if (_gptr >= _egptr && underflow() == EOF) return EOF;
  283.     else return *(unsigned char*)_gptr; }
  284.     int snextc() {
  285.     if (++_gptr >= _egptr && underflow() == EOF) return EOF;
  286.     else return *(unsigned char*)_gptr; }
  287.     int sputc(int c) {
  288.     if (_pptr >= _epptr) return overflow(c);
  289.     return *_pptr++ = c, (unsigned char)c; }
  290.     int vscan(char const *fmt0, _G_va_list ap);
  291.     int vform(char const *fmt0, _G_va_list ap);
  292. #if 0 /* Work in progress */
  293.     int collumn();  // Current collumn number (of put pointer). -1 is unknown.
  294.     void collumn(int c);  // Set collumn number of put pointer to c.
  295.     friend extern "C" int _handle_overflow(int c);
  296.     friend class streammarker;
  297. #endif
  298. };
  299.  
  300. struct __file_fields {
  301.     char _fake;
  302.     char _shortbuf[1];
  303.     short _fileno;
  304.     int _blksize;
  305.     char* _save_gptr;
  306.     char* _save_egptr;
  307.     fpos_t _offset;
  308. };
  309.  
  310. class filebuf : public streambuf {
  311.     struct __file_fields _fb;
  312.     void init();
  313.   public:
  314.     filebuf();
  315.     filebuf(int fd);
  316.     filebuf(int fd, char* p, int len);
  317.     ~filebuf();
  318.     filebuf* attach(int fd);
  319.     filebuf* open(const char *filename, const char *mode);
  320.     filebuf* open(const char *filename, int mode, int prot = 0664);
  321.     virtual int underflow();
  322.     virtual int overflow(int c = EOF);
  323.     int is_open() { return _fb._fileno >= 0; }
  324.     int fd() { return is_open() ? _fb._fileno : EOF; }
  325.     filebuf* close();
  326.     virtual int doallocate();
  327.     virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
  328.     int sputn(const char* s, int n);
  329.     int sgetn(char* s, int n);
  330.     virtual int sync();
  331.   protected: // See documentation in filebuf.C.
  332.     virtual int pbackfail(int c);
  333.     int is_reading() { return eback() != egptr(); }
  334.     char* cur_ptr() { return is_reading() ?  gptr() : pptr(); }
  335.     /* System's idea of pointer */
  336.     char* file_ptr() { return _fb._save_gptr ? _fb._save_egptr : egptr(); }
  337.     int do_flush();
  338.     // Low-level operations (Usually invoke system calls.)
  339.     virtual int sys_read(char* buf, _G_size_t size);
  340.     virtual fpos_t sys_seek(fpos_t, _seek_dir);
  341.     virtual long sys_write(const void*, long);
  342.     virtual int sys_stat(void*); // Actually, a (struct stat*)
  343.     virtual int sys_close();
  344. };
  345.  
  346. #ifdef _STREAM_COMPAT
  347. inline int ios::readable() { return rdbuf()->_flags & _S_CAN_READ; }
  348. inline int ios::writable() { return rdbuf()->_flags & _S_CAN_WRITE; }
  349. inline int ios::is_open() {return rdbuf()->_flags & _S_CAN_READ+_S_CAN_WRITE;}
  350. #endif
  351.  
  352. #endif /* _STREAMBUF_H */
  353.  
  354.