]> pd.if.org Git - pdclib/blobdiff - functions/stdio/fread.c
Merged PDPCLIB and Therx code.
[pdclib] / functions / stdio / fread.c
index 905ff4dc906c674f2d5ab776569e772066c5a258..b580fe529e97f92cf4a5c97fe8dd0bba234e8438 100644 (file)
@@ -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
+*/