/* Copyright 1989-93 GROUPE BULL -- See license conditions in file COPYRIGHT */
/**************\
*              *
*  KlO  Stream *
*  DEFINITIONS *
*              *
\**************/

#ifndef INCLUDE_Kl_STREAM_H
#define INCLUDE_Kl_STREAM_H

/* type */

/* stream->subtype:
 * KlStream is a dual type, consisting of string and file (default) streams
 * the subtype field distinguish between them and their subclasses
 * bit 1: file (cleared = string)
 * if bit 1 set:
 *        bit 2: pipe to subprocess
 *        bit 3: socket, tcp
 *        bit 4: socket, udp
 */

#define KlStreamStringType 0		/* values of subtype field */
#define KlStreamFileType 1		/* OR flag */
#define KlStreamProcessType 3		/* process is also a file stream */
#define KlStreamTcpSocketType 5		/* socket is also a file stream */
#define KlStreamUdpSocketType 9		/* socket is also a file stream */

#define KlUNPUT_BUFFER_SIZE 4

typedef struct _KlStreamString {
    KlKLONE_HEADER;
    KlString klstring;			/* dynamic buffer */
    char subtype;
    char direction;
    char blocking;			/* unused */
    char blocking_write;		/* unused */
    struct yy_buffer_state *parse_state; /* flex internal state, may be NULL */
    KlO read_expr;			/* read-ahead expression */
    char parse_dirty;			/* need to flush caches? (after seek) */
    char parse_disabled;		/* some other parser invoked? */
	/* common part stops here */
    int cursor;
    int limit;
}              *KlStreamString;

typedef struct _KlStream {
    KlKLONE_HEADER;
    FILE *fd;
    char subtype;
    char direction;
    char blocking;			/* fd mode */
    char blocking_write;		/* write_fd mode */
    struct yy_buffer_state *parse_state; /* flex internal state, may be NULL */
    KlO read_expr;			/* read-ahead expression */
    char parse_dirty;			/* need to flush caches? (after seek) */
    char parse_disabled;		/* some other parser invoked? */
	/* common part stops here */
    char parse_bufferized;		/* if not, interactive */
    char *name;
    FILE *write_fd;			/* for 2-ways R/W half-duplex streams */
}        *KlStream;


/* exported variables */

EXT KlStream KlStdin;
EXT KlStream KlStdout;
EXT KlStream KlStderr;
EXT KlStream KlStdyy;
EXT KlStreamString KlStdpool;

#ifdef INCLUDE_Kl_ATOM_H
EXT KlActive KlA_stdin;
EXT KlActive KlA_stdout;
EXT KlActive KlA_stderr;
EXT KlConstant KlA_StdinOrig;
EXT KlConstant KlA_StdoutOrig;
EXT KlConstant KlA_StderrOrig;
#endif /* INCLUDE_Kl_ATOM_H */

EXT char KlSPutc_char;

extern char *KlStreamDirectionsText[];

#define KlStreamOREAD 1
#define KlStreamOWRITE 2

#define KlStreamCanREAD(o) if (!((o)->direction & KlStreamOREAD)) { \
    KlError2(KlE_STREAM_ERROR, KlA_read, o);}
#define KlStreamCanWRITE(o) if (!((o)->direction & KlStreamOWRITE)) { \
    KlError2(KlE_STREAM_ERROR, KlA_write, o);}
#define KlStreamNotClosed(o) ((o)->direction)

#define KlStreamWriteFd(obj) ((obj)->write_fd ? (obj)->write_fd : (obj)->fd)

/* exported functions */

EXT KlStream KlStreamMake();
EXT KlStreamString KlStreamStringMake();
EXT KlO KlStreamPrint();
EXT KlO KlStream_equal();
EXT KlStream KlStream_match();
extern KlStream KlStdyyRedirect();
EXT KlO KlFlush();
EXT char *KlFGets();
EXT char *KlGets();
EXT KlStream KlOpenError();

/* exported objects */

/* methods */

EXT KlType KlStreamType;

/* macros */

#define KlIsAStream(obj) ((obj)->type == KlStreamType)
#define KlMustBeStream(o, n) KlArgumentMustBe(o, n, KlStreamType)

#define KlIsAStringStream(obj) ((obj)->subtype == KlStreamStringType)
#define KlIsAFileStream(obj) ((obj)->subtype & KlStreamFileType)

/* prints a char */
#define KlSPutc(ascii_code, stream) \
    (KlSPutc_char = ascii_code, KlSPutBytes(1, &KlSPutc_char, stream))

/* Macro to probe the stdio buffer to see if any data is pending in the
 * buffer.  Different versions are provided for System V and BSD stdio.
 */

#ifdef __SLBF
#   define READ_DATA_PENDING(fp) (fp->_r > 0)
#elif defined(LINUX)
#   define READ_DATA_PENDING(fp) ((fp)->_IO_read_end - (fp)->_IO_read_ptr)
#elif defined(sco)
#   define READ_DATA_PENDING(fp) (fp->__cnt != 0)
#else /* BSD */
#   define READ_DATA_PENDING(fp) (fp->_cnt != 0)
#endif

#ifdef USE_FILENO
#define KlFp2Fd(fp) fileno(fp)
#else /* !USE_FILENO */

#ifndef fileno
#define KlFp2Fd(fp) (fp)->_file		/* should be portable */
#else
#define KlFp2Fd(fp) fileno(fp)
#endif

#endif /* !USE_FILENO */
#endif					/* INCLUDE_Kl_STREAM_H */


syntax highlighted by Code2HTML, v. 0.9.1