home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / FRW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-21  |  6.2 KB  |  239 lines

  1. /*
  2.     frw.c
  3.  
  4.     % Routines for generic (bfile/file) file i/o.
  5.  
  6.     5/02/89  by Ted.
  7.  
  8.     OWL 1.2
  9.     Copyright (c) 1988, by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      7/28/89 ted:    Added writing.
  15.      8/14/89 jmd    added some casts
  16.      9/20/89 ted    Added check for NULL 'buf' arg in buffered mode of frw_read.
  17.  
  18.     11/29/89 jmd    added casts for DG
  19.     12/11/89 jmd    added includes
  20.      3/28/90 jmd    ansi-fied
  21.     09/21/90 jsm    added casts for Turbo-C++ to bfile_Read and bfile_Write
  22. */
  23.  
  24. #include "oakhead.h"
  25. #include "frwdecl.h"
  26.  
  27. OSTATIC SIZE_T  OWLPRIV frw_readbuf(struct frw_struct *frw, VOID *buf, SIZE_T n);
  28. OSTATIC boolean OWLPRIV frw_flushbuf(struct frw_struct *frw);
  29. OSTATIC SIZE_T  OWLPRIV frw_writebuf(struct frw_struct *frw, VOID *buf, SIZE_T n);
  30.  
  31. /* -------------------------------------------------------------------------- */
  32.  
  33. boolean frw_openbuf(struct frw_struct *frw, SIZE_T bufsize, boolean writemode)
  34. /*
  35.     Initialize the file read/write interface by allocating a buffer of given
  36.     size and setting pointer and flag values. A value of TRUE in the 'writemode'
  37.     argument initializes for writing; FALSE initializes for reading.
  38. */
  39. {
  40.     frw->buf = (byte *) omalloc(OA_FRW, bufsize);
  41.  
  42.     frw->bufsize = frw->bufend = bufsize;
  43.  
  44.     frw->writemode = (unsigned) writemode;
  45.     if (frw->writemode) {
  46.         frw->bufptr = 0;
  47.     }
  48.     else {    /* read mode */
  49.         frw->bufptr = frw->bufend;
  50.     }
  51.     return(frw->buf != NULL);
  52. }
  53. /* -------------------------------------------------------------------------- */
  54.  
  55. void frw_closebuf(struct frw_struct *frw)
  56. {
  57.     if (frw->writemode) {
  58.         frw_flushbuf(frw);
  59.     }
  60.     ofree(OA_FRW, frw->buf);
  61.     frw->buf = NULL;
  62.     frw->bufsize = frw->bufptr = frw->bufend = 0;
  63. }
  64. /* -------------------------------------------------------------------------- */
  65.  
  66. SIZE_T frw_read(struct frw_struct *frw, VOID *buf, SIZE_T n)
  67. /*
  68.     Buffered read working for either Oakland bfiles or regular files.
  69.     Not advisable for writing large buffers while buffered because the memory
  70.     in that case is copied twice; once here and once by the stdlib buffering.
  71. */
  72. {
  73.     SIZE_T nmove;
  74.     SIZE_T nread;
  75.  
  76.     if (frw->buf == NULL) {
  77.         return(frw_readbuf(frw, buf, n));
  78.     }
  79.     else {
  80.         nread = 0;
  81.  
  82.         for (;;) {
  83.             if (n == 0) {
  84.                 return(nread);
  85.             }
  86.             if (frw->bufptr < frw->bufend) {
  87.                 nmove = frw->bufend - frw->bufptr;
  88.                 if (n < nmove) {
  89.                     nmove = n;
  90.                 }
  91.                 if (buf != NULL) {
  92.                     memmove((VOID *) buf, (VOID *) &frw->buf[frw->bufptr], nmove);
  93.                     buf = (VOID *) ((byte *) buf + nmove);
  94.                 }
  95.                 frw->bufptr += nmove;
  96.                 n -= nmove;
  97.                 nread += nmove;
  98.             }
  99.             else {    /* buffer all used up */
  100.                 if (frw->bufend == frw->bufsize) {
  101.                     frw->bufend = frw_readbuf(frw, frw->buf, frw->bufsize);
  102.                     frw->bufptr = 0;
  103.                 }
  104.                 else {
  105.                     return(nread);
  106.                 }
  107.             }
  108.         }
  109.     }
  110. }
  111. /* -------------------------------------------------------------------------- */
  112.  
  113. unsigned frw_readb(struct frw_struct *frw)
  114. /*
  115.     Returns the next byte from the file frw, w/ hi byte 0;
  116.     Returns hi byte nonzero w/ lo byte 0 if EOF.
  117.     Don't even bother using this if the buffer is not set up.
  118. */
  119. {
  120.     /* If buffer is empty, fill it up */
  121.     if (frw->bufptr >= frw->bufend) {
  122.         if (frw->bufend == frw->bufsize) {
  123.             frw->bufend = frw_readbuf(frw, frw->buf, frw->bufsize);
  124.             frw->bufptr = 0;
  125.         }
  126.     }
  127.     /* If buffer is still empty, fail */
  128.     if (frw->bufptr >= frw->bufend) {
  129.         return(0x0100);
  130.     }
  131.     else {
  132.         return((unsigned) frw->buf[frw->bufptr++]);
  133.     }
  134. }
  135. /* -------------------------------------------------------------------------- */
  136.  
  137. static SIZE_T OWLPRIV frw_readbuf(struct frw_struct *frw, VOID *buf, SIZE_T n)
  138. {
  139.     if (n == 0) {
  140.         return(0);
  141.     }
  142.  
  143.     if (frw->isbfile) {
  144.         return(bfile_Read(frw->bfile, (char *) buf, n));
  145.     }
  146.     else {
  147.         return(fread(buf, sizeof(byte), n, frw->fd));
  148.     }
  149. }
  150. /* -------------------------------------------------------------------------- */
  151.  
  152. SIZE_T frw_write(struct frw_struct *frw, VOID *buf, SIZE_T n)
  153. /*
  154.     Buffered write working for either Oakland bfiles or regular files.
  155.     Not advisable for writing large buffers while buffered because the memory
  156.     in that case is copied twice; once here and once by the stdlib buffering.
  157. */
  158. {
  159.     SIZE_T nmove;
  160.     SIZE_T nwrite;
  161.     SIZE_T wrote;
  162.  
  163.     if (frw->buf == NULL) {
  164.         return(frw_writebuf(frw, buf, n));
  165.     }
  166.     else {
  167.         nwrite = 0;
  168.  
  169.         for (;;) {
  170.             if (n == 0) {
  171.                 return(nwrite);
  172.             }
  173.             if (frw->bufptr < frw->bufsize) {
  174.                 nmove = frw->bufsize - frw->bufptr;
  175.                 if (n < nmove) {
  176.                     nmove = n;
  177.                 }
  178.                 memmove((VOID *) &frw->buf[frw->bufptr], buf, nmove);
  179.                 frw->bufptr += nmove;
  180.                 buf = (VOID *) ((byte *) buf + nmove);
  181.                 n -= nmove;
  182.                 nwrite += nmove;
  183.             }
  184.             else {    /* buffer all used up */
  185.                 wrote = frw_writebuf(frw, frw->buf, frw->bufsize);
  186.                 if (wrote != frw->bufsize) {    /* Write Error */
  187.                     return(nwrite - (frw->bufsize - wrote));
  188.                 }
  189.                 frw->bufptr = 0;
  190.             }
  191.         }
  192.     }
  193. }
  194. /* -------------------------------------------------------------------------- */
  195.  
  196. boolean frw_writeb(struct frw_struct *frw, byte b)
  197. /*
  198.     Returns the next byte from the file frw, w/ hi byte 0;
  199.     Returns hi byte nonzero w/ lo byte 0 if EOF.
  200.     Don't even bother using this if the buffer is not set up.
  201. */
  202. {
  203.     /* If buffer is full, write it out */
  204.     if (frw->bufptr >= frw->bufsize) {
  205.         if (frw_writebuf(frw, frw->buf, frw->bufsize) != frw->bufsize) {
  206.             return(FALSE);    /* Write Error */
  207.         }
  208.         frw->bufptr = 0;
  209.     }
  210.     frw->buf[frw->bufptr++] = b;
  211.     return(TRUE);
  212. }
  213. /* -------------------------------------------------------------------------- */
  214.  
  215. static boolean OWLPRIV frw_flushbuf(struct frw_struct *frw)
  216. {
  217.     if (frw_writebuf(frw, frw->buf, frw->bufptr) != frw->bufptr) {
  218.         frw->bufptr = 0;
  219.         return(FALSE);    /* Write Error */
  220.     }
  221.     frw->bufptr = 0;
  222.     return(TRUE);
  223. }
  224. /* -------------------------------------------------------------------------- */
  225.  
  226. static SIZE_T OWLPRIV frw_writebuf(struct frw_struct *frw, VOID *buf, SIZE_T n)
  227. {
  228.     if (n == 0) return(0);
  229.  
  230.     if (frw->isbfile) {
  231.         return(bfile_Write(frw->bfile, (char *) buf, n));
  232.     }
  233.     else {
  234.         return(fwrite(buf, sizeof(byte), n, frw->fd));
  235.     }
  236. }
  237. /* -------------------------------------------------------------------------- */
  238.  
  239.