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 >
Wrap
C/C++ Source or Header
|
1989-06-27
|
2KB
|
108 lines
/*
* fread and fwrite (optimised version)
* Could do i/o to/from the user's buffer directly if the transfer is long
* enough. If there's a block-aligned block (or more) in the middle, could
* transfer it directly.
*/
#include <stdio.h>
#ifndef PTR_TYPE
#define PTR_TYPE char * /* type of _ptr in stdio.h */
#endif
#define THRESHOLD 12 /* memcpy vs in-line threshold */
typedef unsigned char putc_t; /* cast putc args to this type */
int
fread(ptr, size, count, fp)
char *ptr;
int size, count;
register FILE *fp;
{
register unsigned bytes = count * size;
unsigned origbytes = bytes;
while (bytes > 0) { /* bytes still to be read */
{
/* all of bytes in buffer */
register int copy = fp->_cnt;
if (copy > bytes) /* buffer longer than ptr */
copy = bytes; /* only fill ptr */
bytes -= copy; /* adjust to reflect next loop */
fp->_cnt -= copy;
if (copy < THRESHOLD) {
register char *rptr = ptr, *bp = (char *)fp->_ptr;
for (++copy; --copy > 0; )
*rptr++ = *bp++;
ptr = rptr;
fp->_ptr = (PTR_TYPE)bp;
} else {
memcpy(ptr, (char *)fp->_ptr, copy);
ptr += copy;
fp->_ptr += copy;
}
}
if (bytes > 0) { /* more to read, but buffer is empty */
register int c = getc(fp); /* refill buffer */
if (c == EOF)
break;
else {
*ptr++ = c;
--bytes;
}
}
}
if (size == 0)
return count; /* or 0 */
else
return (origbytes - bytes) / size;
}
int
fwrite(ptr, size, count, fp)
char *ptr;
int size, count;
register FILE *fp;
{
register unsigned bytes = count * size;
unsigned origbytes = bytes;
while (bytes > 0) { /* bytes still to be written */
{
register int copy = fp->_cnt;
if (copy > bytes) /* buffer longer than ptr */
copy = bytes; /* only empty ptr */
bytes -= copy; /* adjust to reflect next loop */
fp->_cnt -= copy;
if (copy < THRESHOLD) {
register char *rptr = ptr, *bp = (char *)fp->_ptr;
for (++copy; --copy > 0; )
*bp++ = *rptr++;
ptr = rptr;
fp->_ptr = (PTR_TYPE)bp;
} else {
memcpy((char *)fp->_ptr, ptr, copy);
ptr += copy;
fp->_ptr += copy;
}
}
if (bytes > 0) /* more to write, but buffer is full */
if (putc((putc_t)*ptr, fp) == EOF) /* flush buffer */
break;
else {
ptr++;
--bytes;
}
}
if (size == 0)
return count; /* or 0 */
else
return (origbytes - bytes) / size;
}