home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff319.lzh / CNewsSrc / cnews.orig.lzh / libstdio / rdwr.c < prev    next >
C/C++ Source or Header  |  1989-06-27  |  2KB  |  108 lines

  1. /*
  2.  * fread and fwrite (optimised version)
  3.  * Could do i/o to/from the user's buffer directly if the transfer is long
  4.  * enough.  If there's a block-aligned block (or more) in the middle, could
  5.  * transfer it directly.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #ifndef PTR_TYPE
  10. #define    PTR_TYPE    char *        /* type of _ptr in stdio.h */
  11. #endif
  12.  
  13. #define THRESHOLD 12            /* memcpy vs in-line threshold */
  14.  
  15. typedef unsigned char putc_t;        /* cast putc args to this type */
  16.  
  17. int
  18. fread(ptr, size, count, fp)
  19. char *ptr;
  20. int size, count;
  21. register FILE *fp;
  22. {
  23.     register unsigned bytes = count * size;
  24.     unsigned origbytes = bytes;
  25.  
  26.     while (bytes > 0) {    /* bytes still to be read */
  27.         {
  28.             /* all of bytes in buffer */
  29.             register int copy = fp->_cnt;
  30.  
  31.             if (copy > bytes)    /* buffer longer than ptr */
  32.                 copy = bytes;    /* only fill ptr */
  33.             bytes -= copy;    /* adjust to reflect next loop */
  34.             fp->_cnt -= copy;
  35.             if (copy < THRESHOLD) {
  36.                 register char *rptr = ptr, *bp = (char *)fp->_ptr;
  37.  
  38.                 for (++copy; --copy > 0; )
  39.                     *rptr++ = *bp++;
  40.                 ptr = rptr;
  41.                 fp->_ptr = (PTR_TYPE)bp;
  42.             } else {
  43.                 memcpy(ptr, (char *)fp->_ptr, copy);
  44.                 ptr += copy;
  45.                 fp->_ptr += copy;
  46.             }
  47.         }
  48.         if (bytes > 0) {    /* more to read, but buffer is empty */
  49.             register int c = getc(fp);    /* refill buffer */
  50.  
  51.             if (c == EOF)
  52.                 break;
  53.             else {
  54.                 *ptr++ = c;
  55.                 --bytes;
  56.             }
  57.         }
  58.     }
  59.     if (size == 0)
  60.         return count;            /* or 0 */
  61.     else
  62.         return (origbytes - bytes) / size;
  63. }
  64.  
  65. int
  66. fwrite(ptr, size, count, fp)
  67. char *ptr;
  68. int size, count;
  69. register FILE *fp;
  70. {
  71.     register unsigned bytes = count * size;
  72.     unsigned origbytes = bytes;
  73.  
  74.     while (bytes > 0) {    /* bytes still to be written */
  75.         {
  76.             register int copy = fp->_cnt;
  77.  
  78.             if (copy > bytes)    /* buffer longer than ptr */
  79.                 copy = bytes;    /* only empty ptr */
  80.             bytes -= copy;    /* adjust to reflect next loop */
  81.             fp->_cnt -= copy;
  82.             if (copy < THRESHOLD) {
  83.                 register char *rptr = ptr, *bp = (char *)fp->_ptr;
  84.  
  85.                 for (++copy; --copy > 0; )
  86.                     *bp++ = *rptr++;
  87.                 ptr = rptr;
  88.                 fp->_ptr = (PTR_TYPE)bp;
  89.             } else {
  90.                 memcpy((char *)fp->_ptr, ptr, copy);
  91.                 ptr += copy;
  92.                 fp->_ptr += copy;
  93.             }
  94.         }
  95.         if (bytes > 0)    /* more to write, but buffer is full */
  96.             if (putc((putc_t)*ptr, fp) == EOF) /* flush buffer */
  97.                 break;
  98.             else {
  99.                 ptr++;
  100.                 --bytes;
  101.             }
  102.     }
  103.     if (size == 0)
  104.         return count;            /* or 0 */
  105.     else
  106.         return (origbytes - bytes) / size;
  107. }
  108.