home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c185 / 2.ddi / OWLSRC.EXE / CSCAPE / SOURCE / FRW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-06  |  6.0 KB  |  250 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.1
  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. */
  17.  
  18. #include "oakhead.h"
  19. #include "frwdecl.h"
  20.  
  21. OSTATIC SIZE_T  OWLPRIV frw_readbuf(_arg3(struct frw_struct *frw, VOID *buf, SIZE_T n));
  22. OSTATIC SIZE_T  OWLPRIV frw_writebuf(_arg3(struct frw_struct *frw, VOID *buf, SIZE_T n));
  23. OSTATIC boolean    OWLPRIV frw_flushbuf(_arg1(frw_type frw));
  24. /* -------------------------------------------------------------------------- */
  25.  
  26. boolean frw_openbuf(frw, bufsize, writemode)
  27.     struct frw_struct *frw;
  28.     SIZE_T bufsize;
  29.     boolean writemode;
  30. /*
  31.     Initialize the file read/write interface by allocating a buffer of given
  32.     size and setting pointer and flag values. A value of TRUE in the 'writemode'
  33.     argument initializes for writing; FALSE initializes for reading.
  34. */
  35. {
  36.     frw->buf = (byte *) omalloc(OA_FRW, bufsize);
  37.  
  38.     frw->bufsize = frw->bufend = bufsize;
  39.  
  40.     frw->writemode = (unsigned) writemode;
  41.     if (frw->writemode) {
  42.         frw->bufptr = 0;
  43.     }
  44.     else {    /* read mode */
  45.         frw->bufptr = frw->bufend;
  46.     }
  47.     return(frw->buf != NULL);
  48. }
  49. /* -------------------------------------------------------------------------- */
  50.  
  51. void frw_closebuf(frw)
  52.     struct frw_struct *frw;
  53. {
  54.     if (frw->writemode) {
  55.         frw_flushbuf(frw);
  56.     }
  57.     ofree(OA_FRW, frw->buf);
  58.     frw->buf = NULL;
  59.     frw->bufsize = frw->bufptr = frw->bufend = 0;
  60. }
  61. /* -------------------------------------------------------------------------- */
  62.  
  63. SIZE_T frw_read(frw, buf, n)
  64.     struct frw_struct *frw;
  65.     VOID *buf;
  66.     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.                 memmove(buf, &frw->buf[frw->bufptr], nmove);
  92.                 frw->bufptr += nmove;
  93.                 buf = (VOID *) ((byte *) buf + nmove);
  94.                 n -= nmove;
  95.                 nread += nmove;
  96.             }
  97.             else {    /* buffer all used up */
  98.                 if (frw->bufend == frw->bufsize) {
  99.                     frw->bufend = frw_readbuf(frw, frw->buf, frw->bufsize);
  100.                     frw->bufptr = 0;
  101.                 }
  102.                 else {
  103.                     return(nread);
  104.                 }
  105.             }
  106.         }
  107.     }
  108. }
  109. /* -------------------------------------------------------------------------- */
  110.  
  111. unsigned frw_readb(frw)
  112.     struct frw_struct *frw;
  113. /*
  114.     Returns the next byte from the file frw, w/ hi byte 0;
  115.     Returns hi byte nonzero w/ lo byte 0 if EOF.
  116.     Don't even bother using this if the buffer is not set up.
  117. */
  118. {
  119.     /* If buffer is empty, fill it up */
  120.     if (frw->bufptr >= frw->bufend) {
  121.         if (frw->bufend == frw->bufsize) {
  122.             frw->bufend = frw_readbuf(frw, frw->buf, frw->bufsize);
  123.             frw->bufptr = 0;
  124.         }
  125.     }
  126.     /* If buffer is still empty, fail */
  127.     if (frw->bufptr >= frw->bufend) {
  128.         return(0x0100);
  129.     }
  130.     else {
  131.         return((unsigned) frw->buf[frw->bufptr++]);
  132.     }
  133. }
  134. /* -------------------------------------------------------------------------- */
  135.  
  136. static SIZE_T OWLPRIV frw_readbuf(frw, buf, n)
  137.     struct frw_struct *frw;
  138.     VOID *buf;
  139.     SIZE_T n;
  140. {
  141.     if (n == 0) {
  142.         return(0);
  143.     }
  144.  
  145.     if (frw->isbfile) {
  146.         return(bfile_Read(frw->bfile, buf, n));
  147.     }
  148.     else {
  149.         return(fread(buf, sizeof(byte), n, frw->fd));
  150.     }
  151. }
  152. /* -------------------------------------------------------------------------- */
  153.  
  154. SIZE_T frw_write(frw, buf, n)
  155.     struct frw_struct *frw;
  156.     VOID *buf;
  157.     SIZE_T n;
  158. /*
  159.     Buffered write working for either Oakland bfiles or regular files.
  160.     Not advisable for writing large buffers while buffered because the memory
  161.     in that case is copied twice; once here and once by the stdlib buffering.
  162. */
  163. {
  164.     SIZE_T nmove;
  165.     SIZE_T nwrite;
  166.     SIZE_T wrote;
  167.  
  168.     if (frw->buf == NULL) {
  169.         return(frw_writebuf(frw, buf, n));
  170.     }
  171.     else {
  172.         nwrite = 0;
  173.  
  174.         for (;;) {
  175.             if (n == 0) {
  176.                 return(nwrite);
  177.             }
  178.             if (frw->bufptr < frw->bufsize) {
  179.                 nmove = frw->bufsize - frw->bufptr;
  180.                 if (n < nmove) {
  181.                     nmove = n;
  182.                 }
  183.                 memmove(&frw->buf[frw->bufptr], buf, nmove);
  184.                 frw->bufptr += nmove;
  185.                 buf = (VOID *) ((byte *) buf + nmove);
  186.                 n -= nmove;
  187.                 nwrite += nmove;
  188.             }
  189.             else {    /* buffer all used up */
  190.                 wrote = frw_writebuf(frw, frw->buf, frw->bufsize);
  191.                 if (wrote != frw->bufsize) {    /* Write Error */
  192.                     return(nwrite - (frw->bufsize - wrote));
  193.                 }
  194.                 frw->bufptr = 0;
  195.             }
  196.         }
  197.     }
  198. }
  199. /* -------------------------------------------------------------------------- */
  200.  
  201. boolean frw_writeb(frw, b)
  202.     struct frw_struct *frw;
  203.     byte b;
  204. /*
  205.     Returns the next byte from the file frw, w/ hi byte 0;
  206.     Returns hi byte nonzero w/ lo byte 0 if EOF.
  207.     Don't even bother using this if the buffer is not set up.
  208. */
  209. {
  210.     /* If buffer is full, write it out */
  211.     if (frw->bufptr >= frw->bufsize) {
  212.         if (frw_writebuf(frw, frw->buf, frw->bufsize) != frw->bufsize) {
  213.             return(FALSE);    /* Write Error */
  214.         }
  215.         frw->bufptr = 0;
  216.     }
  217.     frw->buf[frw->bufptr++] = b;
  218.     return(TRUE);
  219. }
  220. /* -------------------------------------------------------------------------- */
  221.  
  222. static boolean OWLPRIV frw_flushbuf(frw)
  223.     struct frw_struct *frw;
  224. {
  225.     if (frw_writebuf(frw, frw->buf, frw->bufptr) != frw->bufptr) {
  226.         frw->bufptr = 0;
  227.         return(FALSE);    /* Write Error */
  228.     }
  229.     frw->bufptr = 0;
  230.     return(TRUE);
  231. }
  232. /* -------------------------------------------------------------------------- */
  233.  
  234. static SIZE_T OWLPRIV frw_writebuf(frw, buf, n)
  235.     struct frw_struct *frw;
  236.     VOID *buf;
  237.     SIZE_T n;
  238. {
  239.     if (n == 0) return(0);
  240.  
  241.     if (frw->isbfile) {
  242.         return(bfile_Write(frw->bfile, buf, n));
  243.     }
  244.     else {
  245.         return(fwrite(buf, sizeof(byte), n, frw->fd));
  246.     }
  247. }
  248. /* -------------------------------------------------------------------------- */
  249.  
  250.