home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / bin / p205.zip / exesrc / brw.c next >
C/C++ Source or Header  |  1994-12-18  |  7KB  |  231 lines

  1. /*****************************************************************************/
  2. /*           Copyright (c) 1994 by Jyrki Salmi <jytasa@jyu.fi>             */
  3. /*        You may modify, recompile and distribute this file freely.         */
  4. /*****************************************************************************/
  5.  
  6. /*
  7.    Buffered file read and write routines. Not for generic use. Routines will
  8.    break if same file is written and read without first closing and reopening
  9.    it.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdarg.h>
  14. #include <string.h>
  15. #include <stdlib.h>
  16. #include <io.h>
  17. #include <fcntl.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <malloc.h>
  21. #include <os2.h>
  22. #include "typedefs.h"
  23. #include "brw.h"
  24.  
  25. /* Open the file. Returns a pointer to BRWF structure if successful. If file */
  26. /* does not exist or some other error occurs a NULL value will be returned.  */
  27.  
  28. BRWF *brw_open(U8 *path,
  29.            U32 inbuf_size,
  30.            U32 outbuf_size,
  31.            S32 oflag,
  32.            S32 shflag, ...) {
  33.   
  34.   S32 fd;
  35.   S32 mode;
  36.   va_list argptr;
  37.   BRWF *brwf;
  38.   
  39.   va_start(argptr, shflag);
  40.   mode = va_arg(argptr, S32);
  41.   va_end(argptr);
  42.   
  43.   if ((fd = sopen(path, oflag, shflag, mode)) == -1)
  44.     return(NULL);
  45.   if ((brwf = malloc(sizeof(BRWF))) == NULL) {
  46.     fprintf(stderr, "Failed to allocate memory\n");
  47.     exit(1);
  48.   }
  49.   brwf->fd = fd;
  50.   if (inbuf_size != 0) {
  51.     if ((brwf->inbuf = malloc(inbuf_size)) == NULL) {
  52.       fprintf(stderr, "Failed to allocate memory\n");
  53.       exit(1);
  54.     }
  55.   } else
  56.     brwf->inbuf = NULL;
  57.   brwf->inbuf_size = inbuf_size;
  58.   brwf->inbuf_idx = 0;
  59.   brwf->inbuf_len = 0;
  60.   if (outbuf_size != 0) {
  61.     if ((brwf->outbuf = malloc(outbuf_size)) == NULL) {
  62.       fprintf(stderr, "Failed to allocate memory\n");
  63.       exit(1);
  64.     }
  65.   } else
  66.     brwf->outbuf = NULL;
  67.   brwf->outbuf_size = outbuf_size;
  68.   brwf->outbuf_idx = 0;
  69.   return(brwf);
  70. }
  71.  
  72. /* Closes the file */
  73.  
  74. void brw_close(BRWF **brwf) {
  75.   
  76.   close((*brwf)->fd);
  77.   if ((*brwf)->inbuf != NULL)
  78.     free((*brwf)->inbuf);
  79.   if ((*brwf)->outbuf != NULL)
  80.     free((*brwf)->outbuf);
  81.   *brwf = NULL;
  82. }
  83.  
  84. /* Read buf_len bytes from the file and save them to buf. Returns the number */
  85. /* of bytes read, or in case of an error, -1 */
  86.  
  87. S32 brw_read(BRWF *brwf, U8 *buf, U32 buf_len) {
  88.   
  89.   static S32 rw_ret;
  90.   static U32 buf_idx;
  91.   
  92.   if (brwf->inbuf == NULL)      /* If no buffering */
  93.     return(read(brwf->fd, buf, buf_len));
  94.  
  95.   buf_idx = 0;
  96.   while (1) {
  97.     if (brwf->inbuf_len - brwf->inbuf_idx < buf_len - buf_idx) {
  98.       /****************************************/
  99.       /* Let's copy all that is in the buffer */
  100.       /****************************************/
  101.       memcpy(&buf[buf_idx],
  102.          &brwf->inbuf[brwf->inbuf_idx],
  103.          brwf->inbuf_len - brwf->inbuf_idx);
  104.       buf_idx += brwf->inbuf_len - brwf->inbuf_idx;
  105.  
  106.       /****************************/
  107.       /* Let's fill up the buffer */
  108.       /****************************/
  109.       rw_ret = read(brwf->fd, brwf->inbuf, brwf->inbuf_size);
  110.       if (rw_ret == -1)
  111.     return(-1);
  112.       if (rw_ret == 0)
  113.     return(buf_idx);
  114.       brwf->inbuf_idx = 0;
  115.       brwf->inbuf_len = rw_ret;
  116.     } else {
  117.       memcpy(&buf[buf_idx], &brwf->inbuf[brwf->inbuf_idx], buf_len - buf_idx);
  118.       brwf->inbuf_idx += buf_len - buf_idx;
  119.       buf_idx += buf_len - buf_idx;
  120.       break;
  121.     }
  122.   }
  123.   return(buf_idx);
  124. }
  125.  
  126. /* Writes data in the write buffer to the disk. Important to call before */
  127. /* closing the file being written to. Returns 0 when buffer written */
  128. /* successfully, -1 when some sort of error occurred and 1 when all of the */
  129. /* data was not written (disk full condition). */
  130.  
  131. S32 brw_flush(BRWF *brwf) {
  132.  
  133.   S32 rw_ret;
  134.  
  135.   if (brwf->outbuf_idx > 0) {
  136.     rw_ret = write(brwf->fd, brwf->outbuf, brwf->outbuf_idx);
  137.     if (rw_ret != brwf->outbuf_idx) {
  138.       if (rw_ret == -1)
  139.     return(-1);
  140.       else
  141.     return(1);
  142.     }
  143.   }
  144.   return(0);
  145. }
  146.  
  147. /* Writes data to the file. Returns 0 when successful, -1 when some sort of */
  148. /* error has occurred and 1 when only some of the data got successfully */
  149. /* written (which is an implication of disk full condition). */
  150.  
  151. S32 brw_write(BRWF *brwf, U8 *buf, U32 buf_len) {
  152.   
  153.   static S32 rw_ret;
  154.   static U32 buf_idx;
  155.  
  156.   if (brwf->outbuf == NULL) {     /* If no buffering */
  157.     rw_ret = write(brwf->fd, buf, buf_len);
  158.     if (rw_ret == buf_len)
  159.       return(0);
  160.     else if (rw_ret == -1)
  161.      return(-1);
  162.     else
  163.      return(1);
  164.   }
  165.  
  166.   buf_idx = 0;
  167.   while (1) {
  168.     if (brwf->outbuf_size - brwf->outbuf_idx < buf_len - buf_idx) { /* If data doesn't fit the buffer */
  169.       memcpy(&brwf->outbuf[brwf->outbuf_idx],
  170.          &buf[buf_idx],
  171.          brwf->outbuf_size - brwf->outbuf_idx);
  172.       buf_idx += brwf->outbuf_size - brwf->outbuf_idx;
  173.       brwf->outbuf_idx += brwf->outbuf_size - brwf->outbuf_idx;
  174.  
  175.       rw_ret = write(brwf->fd, brwf->outbuf, brwf->outbuf_idx);
  176.       if (rw_ret != brwf->outbuf_idx) {    /* Something went wrong while writing */
  177.     if (rw_ret == -1)
  178.       return(-1);
  179.     else
  180.       return(1);
  181.       }
  182.       brwf->outbuf_idx = 0;
  183.     } else {            /* Data fits in the buffer */
  184.       memcpy(&brwf->outbuf[brwf->outbuf_idx], &buf[buf_idx], buf_len - buf_idx);
  185.       brwf->outbuf_idx += buf_len - buf_idx;
  186.       buf_idx += buf_len - buf_idx;
  187.       break;
  188.     }
  189.   }
  190.   return(0);        /* Everything A-OK */
  191. }
  192.  
  193. /* Change the current read or write position in the file. Returns -1 when */
  194. /* some sort of error has occurred and 0 when seek was successful. */
  195.  
  196. S32 brw_seek(BRWF *brwf, U32 new_pos) {
  197.  
  198.   static U32 old_pos;
  199.  
  200.   if (brwf->inbuf == NULL) {    /* If no input buffering */
  201.     if (lseek(brwf->fd, new_pos, SEEK_SET) == -1)
  202.       return(-1);
  203.     else
  204.       return(0);
  205.   }
  206.  
  207.   if ((old_pos = tell(brwf->fd)) == -1)
  208.     return(-1);
  209.  
  210.   if (new_pos < old_pos) {    /* If we're moving backwards... */
  211.     if (old_pos - brwf->inbuf_len <= new_pos) { /* If the new position is in the buffer */
  212.       brwf->inbuf_idx = new_pos - (old_pos - brwf->inbuf_len);
  213.     } else {            /* New position is not in the buffer */
  214.       if (lseek(brwf->fd, new_pos, SEEK_SET) == -1)
  215.     return(-1);
  216.       brwf->inbuf_idx = 0;
  217.       brwf->inbuf_len = 0;
  218.     }
  219.   } else {            /* Else we're moving backwards... */
  220.     if (old_pos >= new_pos) {    /* If the new position is in the buffer */
  221.       brwf->inbuf_idx += old_pos - new_pos;
  222.     } else {            /* New position is not in the buffer */
  223.       if (lseek(brwf->fd, new_pos, SEEK_SET) == -1)
  224.     return(-1);
  225.       brwf->inbuf_idx = 0;
  226.       brwf->inbuf_len = 0;
  227.     }
  228.   }
  229.   return(0);            /* Everything A-OK */
  230. }
  231.