[comp.lang.c++] A stream library clone, Part 03

pcg@aber-cs.UUCP (Piercarlo Grandi) (12/05/89)

---------------------------------cut here-----------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 3)."
# Contents:  _iobuf.H stream.H stream/Makefile stream/open-stream.C
#   stream/setHandler.C
# Wrapped by piercarl@aware on Mon Dec  4 14:14:28 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo '
    Copyright 1989 Piercarlo Grandi. All rights reserved.

    This  shar  archive is free software; you can redistribute it and/or
    modify  it  under  the  terms  of  the GNU General Public License as
    published  by the Free Software Foundation; either version 1, or (at
    your option) any later version.

    This shar archive is distributed in the hope that it will be useful,
    but  WITHOUT  ANY  WARRANTY;  without  even  the implied warranty of
    MERCHANTABILITY  or  FITNESS  FOR  A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.

    You may have received a copy of the GNU General Public License along
    with  this  program;  if not, write to the Free Software Foundation,
    Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
'
if test -f '_iobuf.H' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'_iobuf.H'\"
else
echo shar: Extracting \"'_iobuf.H'\" \(2065 characters\)
sed "s/^X//" >'_iobuf.H' <<'END_OF_FILE'
X#ifndef _iobuf_H
X#define _iobuf_H
X#if __STDC__
X#   pragma once
X#endif
X
X#ifndef _iobufUSG
X#   define _iobufUSG		    1
X#   define _iobufSETLINEBUF	    0
X#   define _iobufSETVBUF	    0
X#endif
X
X#define nil(t)			((t) 0)
X#define construct
X#define destruct
X#define convert
X
class _iobuf
X{
protected:
X
X    signed		rest;		/* _cnt				*/
X    char unsigned	*hand;		/* _ptr				*/
X    char unsigned	*buffer;	/* _base			*/
X
X#if (_iobufUSG)
X    unsigned		flags : 8;	/* _flag			*/
X    char signed		fd;		/* _file			*/
X#else
X    signed		capacity;	/* _bufsiz			*/
X    unsigned		flags : 16;	/* _flag			*/
X    char signed		fd;		/* _file			*/
X#endif
X
X    friend class	stream;
X
public:
X
X    friend signed	putc(char,_iobuf *);
X    friend signed	getc(_iobuf *);
X
X    friend signed	feof(const _iobuf *);
X    friend signed	ferror(const _iobuf *);
X
X    friend signed	fileno(const _iobuf *);
X    friend void		clearerr(_iobuf *);
X};
X
enum _iobufFlags
X{
X    _iobufBuffered	= 0000,
X    _iobufReadable	= 0001,
X    _iobufWritable	= 0002,
X    _iobufUnbuffered	= 0004,
X    _iobufUserBuffer	= 0010,
X    _iobufEof		= 0020,
X    _iobufError		= 0040,
X#if (_iobufUSG)
X    _iobufLineBuffer	= 0100,
X    _iobufUpdatable	= 0200,
X    _iobufString	= 0000,
X#else
X    _iobufString	= 0100,
X    _iobufLineBuffer	= 0200,
X    _iobufUpdatable	= 0400,
X    _iobufAppendable	= 01000,
X#endif
X};
X
extern "C"
X{
extern signed		_filbuf(_iobuf *),
X			_flsbuf(unsigned,_iobuf *);
X}
X
static const signed	EOF = -1;
X
static inline signed	ferror
X(
X    register const _iobuf   *const stdio
X)
X{
X    return stdio->flags & _iobufError;
X}
X
static inline signed	feof
X(
X    register const _iobuf   *const stdio
X)
X{
X    return stdio->flags & _iobufEof;
X}
X
static inline signed	getc
X(
X    register _iobuf	    *const stdio
X)
X{
X    return (--stdio->rest >= 0)
X	? (signed) *stdio->hand++
X	: _filbuf(stdio);
X}
X
static inline signed	putc
X(
X    auto const char	    ch,
X    register _iobuf	    *const stdio
X)
X{
X    return (--stdio->rest >= 0)
X	? (signed) (*stdio->hand++ = (char unsigned) ch)
X	: _flsbuf((unsigned) ch,stdio);
X}
X
X#endif /* _iobuf_H */
END_OF_FILE
if test 2065 -ne `wc -c <'_iobuf.H'`; then
    echo shar: \"'_iobuf.H'\" unpacked with wrong size!
fi
# end of '_iobuf.H'
fi
if test -f 'stream.H' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stream.H'\"
else
echo shar: Extracting \"'stream.H'\" \(4541 characters\)
sed "s/^X//" >'stream.H' <<'END_OF_FILE'
X#ifndef stream_H
X#define stream_H
X#if __STDC__
X#   pragma once
X#endif
X
X#ifndef _stddef_h
X#   include <stddef.h>
X#endif
X#ifndef _iobuf_H
X#   include "_iobuf.H"
X#endif
X
enum streamType
X{
X    streamRead,
X    streamWrite,
X    streamUpdate,
X    streamAppend,
X    streamExtend,
X};
X
enum streamMode
X{
X    streamCreate,
X    streamRecreate,
X    streamUse,
X    streamReuse,
X};
X
enum streamState
X{
X    streamGood,
X    streamEof,
X    streamFail,
X    streamBad
X};
X
X/*
X    Two exceedingly important flags are disabled and string. Disabled is
X    true  when  the  stream  is not yet open, or when the last operation
X    failed.  This  means  that  stdio  is guaranteed to be valid only if
X    disabled  is  false. Dispose is true if stdio maps an incore string,
X    not an external file, as in this case stdio points to an _iobuf that
X    must be disposed of, as it has been allocated explicitly.
X*/
X
class stream
X{
protected:
X
X    char unsigned	disabled;
X    char unsigned	dispose;
X
X    _iobuf		*stdio;
X    char		*fileName;
X
X    long signed		count;
X
X    void		initialize();
X    void		restart(const char *);
X
X    char		*readline(const signed,const char);
X
public:
X
X    construct		stream();
X    construct		stream(const char *,streamType,streamMode);
X    construct		stream(const char *,const char *);
X    construct		stream(signed,streamType);
X    construct		stream(const _iobuf *);
X    construct		stream(signed,char *,streamType);
X
X    destruct		~stream();
X
X    stream		&open(const char *,streamType,streamMode);
X    stream		&open(const char *,const char *);
X    stream		&open(signed,streamType);
X    stream		&open(const _iobuf *);
X
X    signed		fileno() const;
X    const char		*name() const;
X    void		setname(const char *);
X    long signed		iocount() const;
X
X    streamState		getstate() const;
X    void		clear(streamState = streamGood);
X
X    signed		eof() const;
X    signed		fail() const;
X    signed		bad() const;
X    signed		good() const;
X
X    signed		isopen() const;
X    signed		readable() const;
X    signed		writable() const;
X
X    convert		operator void *() const;
X
X    stream		&put(char);
X    stream		&get(char &);
X    stream		&unget(char);
X    stream		&putback(char);
X
X    stream		&put(const char *);
X    stream		&get(char *,signed,char = '\n');
X    stream		&gets(char **,char = '\n');
X    stream		&getline(char *,signed,char = '\n');
X
X    stream		&read(void *,signed,signed);
X    stream		&write(void *,signed,signed);
X
X    stream		&seek(long signed,signed = 0);
X    long signed		tell() const;
X
X    stream		&raw();
X    stream		&flush();
X    stream		&setbuf(_iobufFlags);
X    stream		&setbuf(signed,char *);
X
X    void		error();
X
X    stream		&remove();
X    stream		&close();
X
X    static one_arg_error_handler_t	verboseHandler;
X    static one_arg_error_handler_t	quietHandler;
X    static one_arg_error_handler_t	fatalHandler;
X
X    static one_arg_error_handler_t	handler;
X
X    static one_arg_error_handler_t	setHandler(one_arg_error_handler_t);
X};
X
X/*
X    Note  that  the  only  operations  that  may  modify  the  status of
X    'disabled'  are  get and put and similia, and we guarantee that they
X    do  update  the  disabled indicator. If all is well with the stream,
X    disabled  is  false;  only  if  disabled is true we need to (slowly)
X    examine the status of the underlying _iobuf structure.
X*/
X
static inline stream	&stream::get
X(
X    char		    &ch
X)
X{
X    if (!this->disabled)
X    {
X	if (--stdio->rest >= 0)
X	    ch = *stdio->hand++;
X	else
X	    this->disabled = (ch = _filbuf(stdio)) == EOF;
X    }
X
X    return *this;
X}
X
static inline stream	&stream::put
X(
X    char		    ch
X)
X{
X    if (!this->disabled)
X    {
X	if (--stdio->rest >= 0)
X	    *stdio->hand++ = (char unsigned) ch;
X	else
X	    this->disabled = _flsbuf((unsigned) ch,stdio) == EOF;
X    }
X
X    return *this;
X}
X
static inline signed	stream::eof()
X    const
X{
X    return this->disabled || ::feof(this->stdio);
X}
X
static inline signed	stream::bad()
X    const
X{
X    return this->disabled || ::ferror(this->stdio);
X}
X
static inline signed	stream::fail()
X    const
X{
X    return this->disabled;
X}
X
static inline signed	stream::good()
X    const
X{
X    return !this->disabled /* && fisok(this->stdio) */;
X}
X
static inline signed	stream::readable()
X    const
X{
X    return !this->disabled && this->stdio->flags & _iobufReadable;
X}
X
static inline signed	stream::writable()
X    const
X{
X    return !this->disabled && this->stdio->flags & _iobufWritable;
X}
X
static inline convert	stream::operator void *()
X    const
X{
X    return (this->disabled) ? nil(void *) : (void *) this;
X}
X
X#endif /* stream_H */
END_OF_FILE
if test 4541 -ne `wc -c <'stream.H'`; then
    echo shar: \"'stream.H'\" unpacked with wrong size!
fi
# end of 'stream.H'
fi
if test -f 'stream/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stream/Makefile'\"
else
echo shar: Extracting \"'stream/Makefile'\" \(2610 characters\)
sed "s/^X//" >'stream/Makefile' <<'END_OF_FILE'
X.SUFFIXES:	.C .a .s .o
X
I		=../
CFLAGS		=-O
C++FLAGS	=$(CFLAGS) -I$(I)
CC++		=g++
LD		=g++
LDFLAGS		=-s
X
X.C.s:;		$(CC++) $(C++FLAGS) -S $*.C
X.C.o:;		$(CC++) $(C++FLAGS) -c $*.C
X.C:;		$(CC++) $(C++FLAGS) -c $*.C -o $@
X
SRCS		=clear.C	close.C		cons-empty.C	\
X		cons-fd.C	cons-mode.C	cons-stdio.C	\
X		cons-stream.C	cons-string.C	destruct.C	\
X		error.C		fileno.C	flush.C		\
X		get.C		getline.C	gets.C		\
X		initialize.C	iocount.C	isopen.C	\
X		name.C		open-fd.C	open-mode.C	\
X		open-stdio.C	open-stream.C	put.C		\
X		putback.C	raw.C		read.C		\
X		readline.C	remove.C	\
X		restart.C	seek.C		setHandler.C	\
X		setbuf-buf.C	setbuf-flags.C	setname.C	\
X		streamName.C	tell.C		unget.C		\
X		write.C
X
OBJS		=clear.o	close.o		cons-empty.o	\
X		cons-fd.o	cons-mode.o	cons-stdio.o	\
X		cons-stream.o	cons-string.o	destruct.o	\
X		error.o		fileno.o	flush.o		\
X		get.o		getline.o	gets.o		\
X		initialize.o	iocount.o	isopen.o	\
X		name.o		open-fd.o	open-mode.o	\
X		open-stdio.o	open-stream.o	put.o		\
X		putback.o	raw.o		read.o		\
X		readline.o	remove.o	\
X		restart.o	seek.o		setHandler.o	\
X		setbuf-buf.o	setbuf-flags.o	setname.o	\
X		streamName.o	tell.o		unget.o		\
X		write.o
X
LIB		=../libstream.a
X
X$(LIB): $(OBJS)
X	rm -f $(LIB) && ar r $(LIB) $(OBJS)
X
clean:
X	rm -f $(LIB) *.o
X
clear.C:	$(I)stream.H
clear.C:	$(I)_iobuf.H
close.C:	$(I)stream.H
close.C:	$(I)_iobuf.H
cons-empty.C:	$(I)stream.H
cons-fd.C:	$(I)stream.H
cons-mode.C:	$(I)stream.H
cons-stdio.C:	$(I)stream.H
cons-stdio.C:	$(I)_iobuf.H
cons-stream.C:	$(I)stream.H
cons-string.C:	$(I)stream.H
cons-string.C:	$(I)_iobuf.H
destruct.C:	$(I)stream.H
destruct.C:	$(I)stdio.H
error.C:	$(I)stream.H
fileno.C:	$(I)stream.H
fileno.C:	$(I)_iobuf.H
flush.C:	$(I)stream.H
get.C:		$(I)stream.H
getline.C:	$(I)stream.H
gets.C:		$(I)stream.H
initialize.C:	$(I)stream.H
initialize.C:	$(I)_iobuf.H
iocount.C:	$(I)stream.H
isopen.C:	$(I)stream.H
isopen.C:	$(I)_iobuf.H
name.C:		$(I)stream.H
open-fd.C:	$(I)stream.H
open-mode.C:	$(I)stream.H
open-stdio.C:	$(I)stream.H
open-stdio.C:	$(I)_iobuf.H
open-stream.C:	$(I)stream.H
put.C:		$(I)stream.H
putback.C:	$(I)stream.H
raw.C:		$(I)stream.H
raw.C:		$(I)_iobuf.H
read.C:		$(I)stream.H
read.C:		$(I)_iobuf.H
readline.C:	$(I)stream.H
remove.C:	$(I)stream.H
restart.C:	$(I)stream.H
restart.C:	$(I)_iobuf.H
seek.C:		$(I)stream.H
seek.C:		$(I)_iobuf.H
setbuf-buf.C:	$(I)stream.H
setbuf-buf.C:	$(I)_iobuf.H
setbuf-flags.C:	$(I)stream.H
setbuf-flags.C:	$(I)_iobuf.H
setname.C:	$(I)stream.H
streamName.C:	$(I)stream.H
streamName.C:	$(I)_iobuf.H
streamName.C:	$(I)stdio.H
tell.C:		$(I)stream.H
unget.C:	$(I)stream.H
write.C:	$(I)stream.H
write.C:	$(I)_iobuf.H
END_OF_FILE
if test 2610 -ne `wc -c <'stream/Makefile'`; then
    echo shar: \"'stream/Makefile'\" unpacked with wrong size!
fi
# end of 'stream/Makefile'
fi
if test -f 'stream/open-stream.C' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stream/open-stream.C'\"
else
echo shar: Extracting \"'stream/open-stream.C'\" \(1610 characters\)
sed "s/^X//" >'stream/open-stream.C' <<'END_OF_FILE'
X#include "stream.H"
X
extern "C"
X{
X#include <sys/fcntl.h>
X
extern signed		open(const char *,int,int);
extern struct _iobuf	*fdopen(signed,const char *);
X}
X
enum _iobufType
X{                        
X    _iobufRead		= O_RDONLY,
X    _iobufWrite		= O_WRONLY,
X    _iobufUpdate	= O_RDWR,
X    _iobufAppend	= O_APPEND
X};
X
enum _iobufMode
X{
X    _iobufCreate	= O_CREAT,
X    _iobufTruncate	= O_TRUNC,
X    _iobufExclusive	= O_EXCL
X};
X
X    
static signed		streamUnixModes
X(
X    auto streamType	    type,
X    auto streamMode	    mode
X)
X{
X    auto signed		    flags;
X
X    switch (type)
X    {
X    case streamRead:	    flags = _iobufRead;		    	break;
X    case streamWrite:	    flags = _iobufWrite;		break;
X    case streamUpdate:	    flags = _iobufUpdate;		break;
X    case streamAppend:	    flags = (_iobufAppend|_iobufWrite); break;
X    case streamExtend:	    flags = (_iobufAppend|_iobufUpdate);break;
X
X    default:		    return -1;
X    };
X
X    switch (mode)
X    {
X    case streamCreate:      return flags | (_iobufCreate);
X    case streamRecreate:    return flags | (_iobufCreate|_iobufTruncate);
X    case streamUse:	    return flags;
X    case streamReuse:	    return flags | (_iobufCreate);
X
X    default:		    return -1;
X    }
X}
X
extern stream		&stream::open
X(
X    auto const char	    *const filename,
X    auto const streamType   type,
X    auto const streamMode   mode
X)
X{                                   
X    signed		    modes = streamUnixModes(type,mode);
X
X    if (modes == -1)
X	this->close();
X    else
X    {
X	signed			fd = ::open(filename,modes,0666);
X
X	if (fd >= 0)
X	    this->open(fd,type);
X    }
X
X    return *this;
X}
END_OF_FILE
if test 1610 -ne `wc -c <'stream/open-stream.C'`; then
    echo shar: \"'stream/open-stream.C'\" unpacked with wrong size!
fi
# end of 'stream/open-stream.C'
fi
if test -f 'stream/setHandler.C' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stream/setHandler.C'\"
else
echo shar: Extracting \"'stream/setHandler.C'\" \(1643 characters\)
sed "s/^X//" >'stream/setHandler.C' <<'END_OF_FILE'
X#ifndef _stddef_h
X#   include <stddef.h>
X#endif
X#ifndef _stdarg_h
X#   include <stdarg.h>
X#endif
X#ifndef _iobuf_H
X#   include "_iobuf.H"
X#endif
X#ifndef stream_H
X#   include "stream.H"
X#endif
X#ifndef stdio_H
X#   include "stdio.H"
X#endif
X
extern "C"
X{
extern char		*vsprintf(char *,const char *,...);
extern signed		perror(const char *);
extern signed		errno;
extern volatile void	abort();
X}
X
static void		*streamVerbose
X(
X    const char		    *format,
X    ...
X)
X{
X    auto va_list	    parms;
X    auto char		    line[BUFSIZ];
X
X    va_start(parms,format);
X    ::vsprintf(line,format,parms);
X    va_end(parms);
X
X    ::perror(line);
X    ::errno = 0;
X
X    return nil(void *);
X}
X
static void		*streamQuiet
X(
X    const char		    *format,
X    ...
X)
X{
X    ::errno = 0;
X
X    return nil(void *);
X}
X
static volatile void	*streamFatal
X(
X    auto const char	    *format,
X    ...
X)
X{
X    auto va_list	    parms;
X    char		    line[BUFSIZ];
X
X    va_start(parms,format);
X    ::vsprintf(line,format,parms);
X    va_end(parms);
X
X    ::perror(line);
X    ::abort();
X}
X
extern one_arg_error_handler_t	stream::verboseHandler = (one_arg_error_handler_t) streamVerbose;
extern one_arg_error_handler_t	stream::quietHandler = (one_arg_error_handler_t) streamQuiet;
extern one_arg_error_handler_t	stream::fatalHandler = (one_arg_error_handler_t) streamFatal;
X
extern one_arg_error_handler_t	stream::handler = (one_arg_error_handler_t) streamFatal;
X
extern one_arg_error_handler_t	stream::setHandler
X(
X    auto one_arg_error_handler_t    newHandler
X)
X{
X    one_arg_error_handler_t	    oldHandler = stream::handler;
X
X    stream::handler = newHandler;
X
X    return oldHandler;
X}
END_OF_FILE
if test 1643 -ne `wc -c <'stream/setHandler.C'`; then
    echo shar: \"'stream/setHandler.C'\" unpacked with wrong size!
fi
# end of 'stream/setHandler.C'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk