home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / k95source / p_brw.c < prev    next >
C/C++ Source or Header  |  2000-06-11  |  7KB  |  285 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 "ckcdeb.h"
  13. #ifndef NOXFER
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include <fcntl.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <malloc.h>
  21.  
  22. #ifdef OS2
  23. #ifdef NT
  24. #include <windows.h>
  25. #define close _close
  26. #define lseek _lseek
  27. #define read  _read
  28. #define sopen _sopen
  29. #define tell  _tell
  30. #define write _write
  31. #else
  32. #include <os2.h>
  33. #undef COMMENT
  34. #endif
  35. #endif /* OS2 */
  36.  
  37. #include "p_type.h"
  38. #include "p_brw.h"
  39.  
  40. /* Open the file. Returns a pointer to BRWF structure if successful. If file */
  41. /* does not exist or some other error occurs a NULL value will be returned.  */
  42.  
  43. BRWF *
  44. #ifdef CK_ANSIC
  45. brw_open(U8 *path,
  46.           U32 inbuf_size,
  47.           U32 outbuf_size,
  48.           S32 oflag,
  49.           S32 shflag,
  50.           S32 pmode)
  51. #else
  52. brw_open(path,inbuf_size,outbuf_size,oflag,shflag,pmode)
  53.           U8 *path;
  54.           U32 inbuf_size;
  55.           U32 outbuf_size;
  56.           S32 oflag;
  57.           S32 shflag;
  58.           S32 pmode;
  59. #endif
  60. {
  61.  
  62.   S32 fd;
  63.   BRWF *brwf;
  64.  
  65.   if ((fd = sopen(path, oflag, shflag, pmode)) == -1)
  66.     return(NULL);
  67.   if ((brwf = (BRWF *) malloc(sizeof(BRWF))) == NULL) {
  68.     fprintf(stderr, "Failed to allocate memory\n");
  69.     exit(1);
  70.   }
  71.   brwf->fd = fd;
  72.   if (inbuf_size != 0) {
  73.     if ((brwf->inbuf = (char *) malloc(inbuf_size)) == NULL) {
  74.       fprintf(stderr, "Failed to allocate memory\n");
  75.       exit(1);
  76.     }
  77.   } else
  78.     brwf->inbuf = NULL;
  79.   brwf->inbuf_size = inbuf_size;
  80.   brwf->inbuf_idx = 0;
  81.   brwf->inbuf_len = 0;
  82.   if (outbuf_size != 0) {
  83.     if ((brwf->outbuf = (char *) malloc(outbuf_size)) == NULL) {
  84.       fprintf(stderr, "Failed to allocate memory\n");
  85.       exit(1);
  86.     }
  87.   } else
  88.     brwf->outbuf = NULL;
  89.   brwf->outbuf_size = outbuf_size;
  90.   brwf->outbuf_idx = 0;
  91.   return(brwf);
  92. }
  93.  
  94. /* Closes the file */
  95.  
  96. VOID
  97. #ifdef CK_ANSIC
  98. brw_close(BRWF **brwf)
  99. #else
  100. brw_close(brwf) BRWF ** brwf ;
  101. #endif
  102. {
  103.  
  104.   close((*brwf)->fd);
  105.   if ((*brwf)->inbuf != NULL)
  106.     free((*brwf)->inbuf);
  107.   if ((*brwf)->outbuf != NULL)
  108.     free((*brwf)->outbuf);
  109.   *brwf = NULL;
  110. }
  111.  
  112. /* Read buf_len bytes from the file and save them to buf. Returns the number */
  113. /* of bytes read, or in case of an error, -1 */
  114.  
  115. S32
  116. #ifdef CK_ANSIC
  117. brw_read(BRWF *brwf, U8 *buf, U32 buf_len)
  118. #else
  119. brw_read(brwf,buf,buf_len) BRWF * brwf; U8 *buf; U32 buf_len ;
  120. #endif
  121. {
  122.  
  123.   static S32 rw_ret;
  124.   static U32 buf_idx;
  125.  
  126.   if (brwf->inbuf == NULL)      /* If no buffering */
  127.     return(read(brwf->fd, buf, buf_len));
  128.  
  129.   buf_idx = 0;
  130.   while (1) {
  131.     if (brwf->inbuf_len - brwf->inbuf_idx < buf_len - buf_idx) {
  132.       /****************************************/
  133.       /* Let's copy all that is in the buffer */
  134.       /****************************************/
  135.       memcpy(&buf[buf_idx],
  136.              &brwf->inbuf[brwf->inbuf_idx],
  137.              brwf->inbuf_len - brwf->inbuf_idx);
  138.       buf_idx += brwf->inbuf_len - brwf->inbuf_idx;
  139.  
  140.       /****************************/
  141.       /* Let's fill up the buffer */
  142.       /****************************/
  143.       rw_ret = read(brwf->fd, brwf->inbuf, brwf->inbuf_size);
  144.       if (rw_ret == -1)
  145.         return(-1);
  146.       if (rw_ret == 0)
  147.         return(buf_idx);
  148.       brwf->inbuf_idx = 0;
  149.       brwf->inbuf_len = rw_ret;
  150.     } else {
  151.       memcpy(&buf[buf_idx], &brwf->inbuf[brwf->inbuf_idx], buf_len - buf_idx);
  152.       brwf->inbuf_idx += buf_len - buf_idx;
  153.       buf_idx += buf_len - buf_idx;
  154.       break;
  155.     }
  156.   }
  157.   return(buf_idx);
  158. }
  159.  
  160. /* Writes data in the write buffer to the disk. Important to call before */
  161. /* closing the file being written to. Returns 0 when buffer written */
  162. /* successfully, -1 when some sort of error occurred and 1 when all of the */
  163. /* data was not written (disk full condition). */
  164.  
  165. S32
  166. #ifdef CK_ANSIC
  167. brw_flush(BRWF *brwf)
  168. #else
  169. brw_flush(brwf) BRWF * brwf ;
  170. #endif
  171. {
  172.  
  173.   S32 rw_ret;
  174.  
  175.   if (brwf->outbuf_idx > 0) {
  176.     rw_ret = write(brwf->fd, brwf->outbuf, brwf->outbuf_idx);
  177.     if (rw_ret != brwf->outbuf_idx) {
  178.       if (rw_ret == -1)
  179.         return(-1);
  180.       else
  181.         return(1);
  182.     }
  183.   }
  184.   return(0);
  185. }
  186.  
  187. /* Writes data to the file. Returns 0 when successful, -1 when some sort of */
  188. /* error has occurred and 1 when only some of the data got successfully */
  189. /* written (which is an implication of disk full condition). */
  190.  
  191. S32
  192. #ifdef CK_ANSIC
  193. brw_write(BRWF *brwf, U8 *buf, U32 buf_len)
  194. #else
  195. brw_write(brwf,buf,buf_len) BRWF *brwf; U8 *buf; U32 buf_len;
  196. #endif
  197. {
  198.  
  199.   static S32 rw_ret;
  200.   static U32 buf_idx;
  201.  
  202.   if (brwf->outbuf == NULL) {   /* If no buffering */
  203.     rw_ret = write(brwf->fd, buf, buf_len);
  204.     if (rw_ret == buf_len)
  205.       return(0);
  206.     else if (rw_ret == -1)
  207.      return(-1);
  208.     else
  209.      return(1);
  210.   }
  211.  
  212.   buf_idx = 0;
  213.   while (1) {
  214.     if (brwf->outbuf_size - brwf->outbuf_idx < buf_len - buf_idx) {
  215.         /* If data doesn't fit the buffer */
  216.       memcpy(&brwf->outbuf[brwf->outbuf_idx],
  217.              &buf[buf_idx],
  218.              brwf->outbuf_size - brwf->outbuf_idx);
  219.       buf_idx += brwf->outbuf_size - brwf->outbuf_idx;
  220.       brwf->outbuf_idx += brwf->outbuf_size - brwf->outbuf_idx;
  221.  
  222.       rw_ret = write(brwf->fd, brwf->outbuf, brwf->outbuf_idx);
  223.       if (rw_ret != brwf->outbuf_idx) {
  224.           /* Something went wrong while writing */
  225.         if (rw_ret == -1)
  226.           return(-1);
  227.         else
  228.           return(1);
  229.       }
  230.       brwf->outbuf_idx = 0;
  231.     } else {                    /* Data fits in the buffer */
  232.       memcpy(&brwf->outbuf[brwf->outbuf_idx], &buf[buf_idx], buf_len - buf_idx);
  233.       brwf->outbuf_idx += buf_len - buf_idx;
  234.       buf_idx += buf_len - buf_idx;
  235.       break;
  236.     }
  237.   }
  238.   return(0);            /* Everything A-OK */
  239. }
  240.  
  241. /* Change the current read or write position in the file. Returns -1 when */
  242. /* some sort of error has occurred and 0 when seek was successful. */
  243.  
  244. S32
  245. #ifdef CK_ANSIC
  246. brw_seek(BRWF *brwf, U32 new_pos)
  247. #else
  248. brw_seek(brwf,new_pos) BRWF * brwf; U32 new_pos ;
  249. #endif
  250. {
  251.  
  252.   static U32 old_pos;
  253.  
  254.   if (brwf->inbuf == NULL) {    /* If no input buffering */
  255.     if (lseek(brwf->fd, new_pos, SEEK_SET) == -1)
  256.       return(-1);
  257.     else
  258.       return(0);
  259.   }
  260.  
  261.   if ((old_pos = tell(brwf->fd)) == -1)
  262.     return(-1);
  263.  
  264.   if (new_pos < old_pos) {      /* If we're moving backwards... */
  265.     if (old_pos - brwf->inbuf_len <= new_pos) { /* If the new position is in the buffer */
  266.       brwf->inbuf_idx = new_pos - (old_pos - brwf->inbuf_len);
  267.     } else {                    /* New position is not in the buffer */
  268.       if (lseek(brwf->fd, new_pos, SEEK_SET) == -1)
  269.         return(-1);
  270.       brwf->inbuf_idx = 0;
  271.       brwf->inbuf_len = 0;
  272.     }
  273.   } else {                      /* Else we're moving backwards... */
  274.     if (old_pos >= new_pos) {   /* If the new position is in the buffer */
  275.       brwf->inbuf_idx += old_pos - new_pos;
  276.     } else {                    /* New position is not in the buffer */
  277.       if (lseek(brwf->fd, new_pos, SEEK_SET) == -1)
  278.         return(-1);
  279.       brwf->inbuf_idx = 0;
  280.       brwf->inbuf_len = 0;
  281.     }
  282.   }
  283.   return(0);                    /* Everything A-OK */
  284. }
  285. #endif /* NOXFER */