X-Git-Url: https://pd.if.org/git/?p=pdclib;a=blobdiff_plain;f=functions%2Fstdio%2Ffread.c;h=b580fe529e97f92cf4a5c97fe8dd0bba234e8438;hp=905ff4dc906c674f2d5ab776569e772066c5a258;hb=0a5395faab237ba9008352b0f4bee9659bbd3d5f;hpb=34893ecc2200dc7017c36a54cb6c5f4c2378b5ec diff --git a/functions/stdio/fread.c b/functions/stdio/fread.c index 905ff4d..b580fe5 100644 --- a/functions/stdio/fread.c +++ b/functions/stdio/fread.c @@ -6,3 +6,352 @@ // ---------------------------------------------------------------------------- size_t fread( void * restrict ptr, size_t size, size_t nelem, FILE * restrict stream ) { /* TODO */ }; + +/* PDPC code - unreviewed, verbatim. +Read the note in fopen.c. +{ + size_t toread; + size_t elemRead; + size_t actualRead; +#ifdef __OS2__ + APIRET rc; + ULONG tempRead; +#endif +#ifdef __MSDOS__ + int errind; + size_t tempRead; +#endif + + if (nmemb == 1) + { + toread = size; + } + else if (size == 1) + { + toread = nmemb; + } + else + { + toread = size * nmemb; + } + if (toread < stream->szfbuf) + { + stream->quickBin = 0; + } + if (!stream->quickBin) + { + if (stream->textMode) + { + freadSlowT(ptr, stream, toread, &actualRead); + } + else + { + if (toread <= (stream->endbuf - stream->upto)) + { + memcpy(ptr, stream->upto, toread); + actualRead = toread; + stream->upto += toread; + } + else + { + freadSlowB(ptr, stream, toread, &actualRead); + } + } + if (nmemb == 1) + { + if (actualRead == size) + { + elemRead = 1; + } + else + { + elemRead = 0; + } + } + else if (size == 1) + { + elemRead = actualRead; + } + else + { + elemRead = actualRead / size; + } + return (elemRead); + } + else + { +#ifdef __OS2__ + rc = DosRead(stream->hfile, ptr, toread, &tempRead); + if (rc != 0) + { + actualRead = 0; + stream->errorInd = 1; + errno = rc; + } + else + { + actualRead = tempRead; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, ptr, toread, &errind); + if (errind) + { + errno = tempRead; + actualRead = 0; + stream->errorInd = 1; + } + else + { + actualRead = tempRead; + } +#endif + if (nmemb == 1) + { + if (actualRead == size) + { + elemRead = 1; + } + else + { + elemRead = 0; + stream->eofInd = 1; + } + } + else if (size == 1) + { + elemRead = actualRead; + if (nmemb != actualRead) + { + stream->eofInd = 1; + } + } + else + { + elemRead = actualRead / size; + if (toread != actualRead) + { + stream->eofInd = 1; + } + } + stream->bufStartR += actualRead; + return (elemRead); + } +} + + +/* +while toread has not been satisfied +{ + scan stuff out of buffer, replenishing buffer as required +} +*/ + +static void freadSlowT(void *ptr, + FILE *stream, + size_t toread, + size_t *actualRead) +{ + int finReading = 0; + size_t avail; + size_t need; + char *p; + size_t got; +#ifdef __OS2__ + ULONG tempRead; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t tempRead; + int errind; +#endif + + *actualRead = 0; + while (!finReading) + { + if (stream->upto == stream->endbuf) + { + stream->bufStartR += (stream->upto - stream->fbuf); +#ifdef __OS2__ + rc = DosRead(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempRead); + if (rc != 0) + { + tempRead = 0; + stream->errorInd = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + if (errind) + { + errno = tempRead; + tempRead = 0; + stream->errorInd = 1; + } +#endif + if (tempRead == 0) + { + stream->eofInd = 1; + break; + } + stream->endbuf = stream->fbuf + tempRead; + *stream->endbuf = '\n'; + stream->upto = stream->fbuf; + } + avail = (size_t)(stream->endbuf - stream->upto) + 1; + need = toread - *actualRead; + p = memchr(stream->upto, '\n', avail); + got = (size_t)(p - stream->upto); + if (need < got) + { + memcpy((char *)ptr + *actualRead, stream->upto, need); + stream->upto += need; + *actualRead += need; + } + else + { + memcpy((char *)ptr + *actualRead, stream->upto, got); + stream->upto += got; + *actualRead += got; + if (p != stream->endbuf) + { + if (*(stream->upto - 1) == '\r') + { + *((char *)ptr + *actualRead - 1) = '\n'; + } + else + { + *((char *)ptr + *actualRead) = '\n'; + *actualRead += 1; + } + stream->upto++; + } + else + { + if (*(stream->upto - 1) == '\r') + { + *actualRead -= 1; + } + } + } + if (*actualRead == toread) + { + finReading = 1; + } + } + return; +} + +static void freadSlowB(void *ptr, + FILE *stream, + size_t toread, + size_t *actualRead) +{ + size_t avail; +#ifdef __OS2__ + ULONG tempRead; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t tempRead; + int errind; +#endif + + avail = (size_t)(stream->endbuf - stream->upto); + memcpy(ptr, stream->upto, avail); + *actualRead = avail; + stream->bufStartR += (stream->endbuf - stream->fbuf); + if (toread >= stream->szfbuf) + { + stream->upto = stream->endbuf; + stream->quickBin = 1; +#ifdef __OS2__ + rc = DosRead(stream->hfile, + (char *)ptr + *actualRead, + toread - *actualRead, + &tempRead); + if (rc != 0) + { + tempRead = 0; + stream->errorInd = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, + (char *)ptr + *actualRead, + toread - *actualRead, + &errind); + if (errind) + { + errno = tempRead; + tempRead = 0; + stream->errorInd = 1; + } +#endif + else if (tempRead != (toread - *actualRead)) + { + stream->eofInd = 1; + } + *actualRead += tempRead; + stream->bufStartR += tempRead; + } + else + { + size_t left; + + stream->upto = stream->fbuf; +#ifdef __OS2__ + rc = DosRead(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempRead); + left = toread - *actualRead; + if (rc != 0) + { + tempRead = 0; + stream->errorInd = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + left = toread - *actualRead; + if (errind) + { + errno = tempRead; + tempRead = 0; + stream->errorInd = 1; + } +#endif + else if (tempRead < left) + { + stream->eofInd = 1; + } + stream->endbuf = stream->fbuf + tempRead; + *stream->endbuf = '\n'; + avail = (size_t)(stream->endbuf - stream->upto); + if (avail > left) + { + avail = left; + } + memcpy((char *)ptr + *actualRead, + stream->upto, + avail); + stream->upto += avail; + *actualRead += avail; + } + return; +} +#endif +*/