/* Defs for the new io stuff. */ /* If we had something resembling real object oriented programming tools, we could do something reasonable here, ie flavorize it, and use real methods, with type inheritance, before and after methods, etc. As is, all that's available is C or C++. Sigh. */ /* flags that appear in a streamoid's 'flags' short */ #define STR_OPEN_P 0x0001 /* open-p */ #define STR_AT_EOF_P 0x0002 /* if it's been read up to eof */ #define STR_BUFFERED_P 0x0004 /* if this streamoid has a buffer */ #define STR_FORCE_P 0x0008 /* force after output op */ #define STR_TEXT_P 0x0010 /* do text translation */ #define STR_INPUT_P 0x0020 /* can be read from */ #define STR_OUTPUT_P 0x0040 /* can be written to */ #define STR_UNTYIED_P 0x0080 /* there's an untyied char */ #define STR_BUF_DIRTY_P 0x0100 /* buffer is dirty, only used in bidirectional direct access */ #define STR_BUF_READ_P 0x0200 /* handle needs to be re-seeked before writing, if buf-dirty-p. only used in bidir direct access */ #define STR_INTERACTIVE_P 0x0400 /* this is an interactive streamoid */ #define STR_NOCLOSE_P 0x0800 /* don't close this streamoid on exit, just force output of it */ /* basic methods, callable from application level stuff */ #define METHOD_CLOSE 0 /* close this streamoid */ #define METHOD_TYI 1 /* get a byte/char */ #define METHOD_UNTYI 2 /* push one back */ #define METHOD_TYO 3 /* put one */ #define METHOD_READL 4 /* read a line */ #define METHOD_WRITEL 5 /* write a line */ #define METHOD_READBUF 6 /* read a buffer of n bytes */ #define METHOD_WRITEBUF 7 /* ... */ #define METHOD_SEEK 8 /* seek this streamoid */ #define METHOD_INFO 9 /* get info, stream_specific */ /* internal methods, called from other methods. So far, these are only used for buffered streamoids */ #define METHOD_GETBUF 10 /* fill next buffer */ #define METHOD_PUTBUF 11 /* put this buffer */ #define METHOD_SEEK_I 12 /* do internal work of seeking */ #define METHOD_CLOSE_I 13 /* do internal work of close */ #define METHODS_UNBUFFERED 10 /* n bethods for unbuffered streamoid */ #define METHODS_BUFFERED 14 /* n methods for buffered streamoid */ typedef int (* method_fun)(); /* info structure types */ #define INF_UNDEF 0 /* undefined */ #define INF_CONSOLE 1 /* ST console */ /* #define INF_FILE 2 /* file stream */ struct console_info_block { short * linea; /* the system's linea block */ short maxx; /* max xpos */ short maxy; /* max ypos */ short curx; /* current xpos */ short cury; /* current ypos */ }; /* the basic streamoid structure. NB! this structure doesn't work very well for bidirectional streams like network streams. It is ok for file streams, though; guess we'll do another implementation for other kinds of streams later... */ struct streamoid { unsigned short flags; /* various state flags */ unsigned long file_position; /* nbytes read/writ in file */ int last_error; /* last err code encountered */ short untyied_char; /* char untyied, if any */ short gemdos_handle; /* handle for gemdos */ short n_methods; /* n elts in method vector */ method_fun * method; /* method vector */ /* the following fields are only used if we have a buffered streamoid */ unsigned long buffer_pos; /* position in file this buf belongs */ unsigned long buffer_index; /* index into buf, if buffered */ unsigned long buffer_size; /* total buf size */ unsigned long buffer_nbytes; /* nbytes in buffer now */ unsigned char * buffer; /* buffer if any */ /* maybe add ptr to extra args here, for windows? */ }; /* the way we call methods */ static inline int method_call_0(self, meth) struct streamoid * self; int meth; { if ((self->n_methods > meth) /* && (self->method[meth]) */ ) return(*self->method[meth])(self); } /* where are &rest args when you need them??? */ static inline int method_call_1(self, meth, arg) struct streamoid * self; int meth; long arg; { if ((self->n_methods > meth) /* && (self->method[meth]) */ ) return(*self->method[meth])(self, arg); } static inline int method_call_2(self, meth, arg1, arg2) struct streamoid * self; int meth; long arg1, arg2; { if ((self->n_methods > meth) /* && (self->method[meth]) */ ) return(*self->method[meth])(self, arg1, arg2); } /* forward defs for functions */ extern method_fun * __clone_method_vector(); extern struct streamoid * __make_stream(); extern void __close_all_streamoids(); /* another step in the struggle to make C less incomprehensible */ #define local static #define DEFMETHOD int /* random things */ #define EOF_VALUE -1 extern int errno; /* compatibility for antique eunuchs s/w */ /* kludge to allow us to compile internal things while still providing prototypes for the outside world to use. */ #ifndef FILE #define FILE struct streamoid #endif