home *** CD-ROM | disk | FTP | other *** search
- /*
- frw.c
-
- % Routines for generic (bfile/file) file i/o.
-
- 5/02/89 by Ted.
-
- OWL 1.1
- Copyright (c) 1988, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 7/28/89 ted: Added writing.
- 8/14/89 jmd added some casts
- */
-
- #include "oakhead.h"
- #include "frwdecl.h"
-
- OSTATIC SIZE_T OWLPRIV frw_readbuf(_arg3(struct frw_struct *frw, VOID *buf, SIZE_T n));
- OSTATIC SIZE_T OWLPRIV frw_writebuf(_arg3(struct frw_struct *frw, VOID *buf, SIZE_T n));
- OSTATIC boolean OWLPRIV frw_flushbuf(_arg1(frw_type frw));
- /* -------------------------------------------------------------------------- */
-
- boolean frw_openbuf(frw, bufsize, writemode)
- struct frw_struct *frw;
- SIZE_T bufsize;
- boolean writemode;
- /*
- Initialize the file read/write interface by allocating a buffer of given
- size and setting pointer and flag values. A value of TRUE in the 'writemode'
- argument initializes for writing; FALSE initializes for reading.
- */
- {
- frw->buf = (byte *) omalloc(OA_FRW, bufsize);
-
- frw->bufsize = frw->bufend = bufsize;
-
- frw->writemode = (unsigned) writemode;
- if (frw->writemode) {
- frw->bufptr = 0;
- }
- else { /* read mode */
- frw->bufptr = frw->bufend;
- }
- return(frw->buf != NULL);
- }
- /* -------------------------------------------------------------------------- */
-
- void frw_closebuf(frw)
- struct frw_struct *frw;
- {
- if (frw->writemode) {
- frw_flushbuf(frw);
- }
- ofree(OA_FRW, frw->buf);
- frw->buf = NULL;
- frw->bufsize = frw->bufptr = frw->bufend = 0;
- }
- /* -------------------------------------------------------------------------- */
-
- SIZE_T frw_read(frw, buf, n)
- struct frw_struct *frw;
- VOID *buf;
- SIZE_T n;
- /*
- Buffered read working for either Oakland bfiles or regular files.
- Not advisable for writing large buffers while buffered because the memory
- in that case is copied twice; once here and once by the stdlib buffering.
- */
- {
- SIZE_T nmove;
- SIZE_T nread;
-
- if (frw->buf == NULL) {
- return(frw_readbuf(frw, buf, n));
- }
- else {
- nread = 0;
-
- for (;;) {
- if (n == 0) {
- return(nread);
- }
- if (frw->bufptr < frw->bufend) {
- nmove = frw->bufend - frw->bufptr;
- if (n < nmove) {
- nmove = n;
- }
- memmove(buf, &frw->buf[frw->bufptr], nmove);
- frw->bufptr += nmove;
- buf = (VOID *) ((byte *) buf + nmove);
- n -= nmove;
- nread += nmove;
- }
- else { /* buffer all used up */
- if (frw->bufend == frw->bufsize) {
- frw->bufend = frw_readbuf(frw, frw->buf, frw->bufsize);
- frw->bufptr = 0;
- }
- else {
- return(nread);
- }
- }
- }
- }
- }
- /* -------------------------------------------------------------------------- */
-
- unsigned frw_readb(frw)
- struct frw_struct *frw;
- /*
- Returns the next byte from the file frw, w/ hi byte 0;
- Returns hi byte nonzero w/ lo byte 0 if EOF.
- Don't even bother using this if the buffer is not set up.
- */
- {
- /* If buffer is empty, fill it up */
- if (frw->bufptr >= frw->bufend) {
- if (frw->bufend == frw->bufsize) {
- frw->bufend = frw_readbuf(frw, frw->buf, frw->bufsize);
- frw->bufptr = 0;
- }
- }
- /* If buffer is still empty, fail */
- if (frw->bufptr >= frw->bufend) {
- return(0x0100);
- }
- else {
- return((unsigned) frw->buf[frw->bufptr++]);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static SIZE_T OWLPRIV frw_readbuf(frw, buf, n)
- struct frw_struct *frw;
- VOID *buf;
- SIZE_T n;
- {
- if (n == 0) {
- return(0);
- }
-
- if (frw->isbfile) {
- return(bfile_Read(frw->bfile, buf, n));
- }
- else {
- return(fread(buf, sizeof(byte), n, frw->fd));
- }
- }
- /* -------------------------------------------------------------------------- */
-
- SIZE_T frw_write(frw, buf, n)
- struct frw_struct *frw;
- VOID *buf;
- SIZE_T n;
- /*
- Buffered write working for either Oakland bfiles or regular files.
- Not advisable for writing large buffers while buffered because the memory
- in that case is copied twice; once here and once by the stdlib buffering.
- */
- {
- SIZE_T nmove;
- SIZE_T nwrite;
- SIZE_T wrote;
-
- if (frw->buf == NULL) {
- return(frw_writebuf(frw, buf, n));
- }
- else {
- nwrite = 0;
-
- for (;;) {
- if (n == 0) {
- return(nwrite);
- }
- if (frw->bufptr < frw->bufsize) {
- nmove = frw->bufsize - frw->bufptr;
- if (n < nmove) {
- nmove = n;
- }
- memmove(&frw->buf[frw->bufptr], buf, nmove);
- frw->bufptr += nmove;
- buf = (VOID *) ((byte *) buf + nmove);
- n -= nmove;
- nwrite += nmove;
- }
- else { /* buffer all used up */
- wrote = frw_writebuf(frw, frw->buf, frw->bufsize);
- if (wrote != frw->bufsize) { /* Write Error */
- return(nwrite - (frw->bufsize - wrote));
- }
- frw->bufptr = 0;
- }
- }
- }
- }
- /* -------------------------------------------------------------------------- */
-
- boolean frw_writeb(frw, b)
- struct frw_struct *frw;
- byte b;
- /*
- Returns the next byte from the file frw, w/ hi byte 0;
- Returns hi byte nonzero w/ lo byte 0 if EOF.
- Don't even bother using this if the buffer is not set up.
- */
- {
- /* If buffer is full, write it out */
- if (frw->bufptr >= frw->bufsize) {
- if (frw_writebuf(frw, frw->buf, frw->bufsize) != frw->bufsize) {
- return(FALSE); /* Write Error */
- }
- frw->bufptr = 0;
- }
- frw->buf[frw->bufptr++] = b;
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean OWLPRIV frw_flushbuf(frw)
- struct frw_struct *frw;
- {
- if (frw_writebuf(frw, frw->buf, frw->bufptr) != frw->bufptr) {
- frw->bufptr = 0;
- return(FALSE); /* Write Error */
- }
- frw->bufptr = 0;
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- static SIZE_T OWLPRIV frw_writebuf(frw, buf, n)
- struct frw_struct *frw;
- VOID *buf;
- SIZE_T n;
- {
- if (n == 0) return(0);
-
- if (frw->isbfile) {
- return(bfile_Write(frw->bfile, buf, n));
- }
- else {
- return(fwrite(buf, sizeof(byte), n, frw->fd));
- }
- }
- /* -------------------------------------------------------------------------- */
-
-