home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / cnews.tar / libstdio / rdwr.c < prev    next >
C/C++ Source or Header  |  1992-11-07  |  3KB  |  130 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. #include <string.h>            /* the ANSI one, for memcpy */
  10.  
  11. #ifndef PTR_TYPE
  12. #define    PTR_TYPE char *            /* type of _ptr in stdio.h */
  13. #endif
  14.  
  15. #ifndef voidstar
  16. #ifdef __STDC__
  17. #define voidstar void *
  18. #else                    /* __STDC__ */
  19. #define voidstar char *
  20. #endif                    /* __STDC__ */
  21. #endif                    /* voidstar */
  22.  
  23. #ifndef size_type
  24. #ifdef __STDC__
  25. #define size_type size_t
  26. #else                    /* __STDC__ */
  27. #define size_type int
  28. #endif                    /* __STDC__ */
  29. #endif                    /* size_type */
  30.  
  31. #ifndef THRESHOLD
  32. #define THRESHOLD 12            /* memcpy vs in-line threshold */
  33. #endif
  34.  
  35. typedef unsigned char putc_t;        /* cast putc args to this type */
  36.  
  37. size_type
  38. fread(aptr, size, count, fp)
  39. voidstar aptr;
  40. size_type size, count;
  41. register FILE *fp;
  42. {
  43.     register unsigned bytes = count * size;
  44.     unsigned origbytes = bytes;
  45.     char *ptr = aptr;
  46.  
  47.     while (bytes > 0) {    /* bytes still to be read */
  48.         {
  49.             /* all of bytes in buffer */
  50.             register int copy = fp->_cnt;
  51.  
  52.             if (copy < 0)
  53.                 copy = 0;
  54.             if (copy > bytes)    /* buffer longer than ptr */
  55.                 copy = bytes;    /* only fill ptr */
  56.             bytes -= copy;    /* adjust to reflect next loop */
  57.             fp->_cnt -= copy;
  58.             if (copy < THRESHOLD) {
  59.                 register char *rptr = ptr,
  60.                         *bp = (char *)fp->_ptr;
  61.  
  62.                 for (++copy; --copy > 0; )
  63.                     *rptr++ = *bp++;
  64.                 ptr = rptr;
  65.                 fp->_ptr = (PTR_TYPE)bp;
  66.             } else {
  67.                 (void) memcpy(ptr, (char *)fp->_ptr, copy);
  68.                 ptr += copy;
  69.                 fp->_ptr += copy;
  70.             }
  71.         }
  72.         if (bytes > 0) {    /* more to read, but buffer is empty */
  73.             register int c = getc(fp);    /* refill buffer */
  74.  
  75.             if (c == EOF)
  76.                 break;
  77.             else {
  78.                 *ptr++ = c;
  79.                 --bytes;
  80.             }
  81.         }
  82.     }
  83.     return size == 0? count: (origbytes - bytes) / size;
  84. }
  85.  
  86. size_type
  87. fwrite(aptr, size, count, fp)
  88. voidstar aptr;
  89. size_type size, count;
  90. register FILE *fp;
  91. {
  92.     register unsigned bytes = count * size;
  93.     unsigned origbytes = bytes;
  94.     char *ptr = aptr;
  95.  
  96.     while (bytes > 0) {    /* bytes still to be written */
  97.         {
  98.             register int copy = fp->_cnt;
  99.  
  100.             if (copy < 0)
  101.                 copy = 0;
  102.             if (copy > bytes)    /* buffer longer than ptr */
  103.                 copy = bytes;    /* only empty ptr */
  104.             bytes -= copy;    /* adjust to reflect next loop */
  105.             fp->_cnt -= copy;
  106.             if (copy < THRESHOLD) {
  107.                 register char *rptr = ptr,
  108.                         *bp = (char *)fp->_ptr;
  109.  
  110.                 for (++copy; --copy > 0; )
  111.                     *bp++ = *rptr++;
  112.                 ptr = rptr;
  113.                 fp->_ptr = (PTR_TYPE)bp;
  114.             } else {
  115.                 (void) memcpy((char *)fp->_ptr, ptr, copy);
  116.                 ptr += copy;
  117.                 fp->_ptr += copy;
  118.             }
  119.         }
  120.         if (bytes > 0)    /* more to write, but buffer is full */
  121.             if (putc((putc_t)*ptr, fp) == EOF) /* flush buffer */
  122.                 break;
  123.             else {
  124.                 ptr++;
  125.                 --bytes;
  126.             }
  127.     }
  128.     return size == 0? count: (origbytes - bytes) / size;
  129. }
  130.