Rewrote fread/fwrite for a better/faster handling of reads/writes requests.
authorHartmut Birr <osexpert@googlemail.com>
Mon, 10 Jun 2002 21:26:36 +0000 (21:26 +0000)
committerHartmut Birr <osexpert@googlemail.com>
Mon, 10 Jun 2002 21:26:36 +0000 (21:26 +0000)
svn path=/trunk/; revision=3039

reactos/lib/msvcrt/stdio/fread.c
reactos/lib/msvcrt/stdio/fwrite.c

index 96a3968..d5f3369 100644 (file)
@@ -7,8 +7,9 @@
 
 size_t fread(void *vptr, size_t size, size_t count, FILE *iop)
 {
-  char *ptr = (char *)vptr;
+  unsigned char *ptr = (unsigned char *)vptr;
   size_t  to_read ,n_read;
+  int c, copy;
 
   to_read = size * count;
   
@@ -29,25 +30,58 @@ size_t fread(void *vptr, size_t size, size_t count, FILE *iop)
   if (vptr == NULL || to_read == 0)
     return 0;
 
-  while(iop->_cnt > 0 && to_read > 0 )
-    {
-      to_read--;
-      *ptr++ = getc(iop);
-    }
-
-  // if the buffer is dirty it will have to be written now
-  // otherwise the file pointer won't match anymore.
-
-  fflush(iop);
+  if (iop->_base == NULL)
+  {
+    int c = _filbuf(iop);
+    if (c == EOF)
+      return 0;
+    *ptr++ = c;
+    if (--to_read == 0)
+      return 1;
+  }
 
-  // check to see if this will work with in combination with ungetc
+  if (iop->_cnt > 0 && to_read > 0)
+  {
+     copy = min(iop->_cnt, to_read);
+     memcpy(ptr, iop->_ptr, copy);
+     ptr += copy;
+     iop->_ptr += copy;
+     iop->_cnt -= copy;
+     to_read -= copy;
+     if (to_read == 0)
+       return count;
+  }
 
-  n_read = _read(fileno(iop), ptr, to_read);
-  if ( n_read != -1 )
-    to_read -= n_read;
+  if (to_read > 0)
+  {
 
-  // the file buffer is empty and there is no read ahead information anymore.
-  iop->_flag &= ~_IOAHEAD;
+    if (to_read >= iop->_bufsiz)
+    {
+       n_read = _read(fileno(iop), ptr, to_read);
+          if (n_read < 0)
+                 iop->_flag |= _IOERR;
+          else if (n_read == 0)
+                 iop->_flag |= _IOEOF;
+          else
+          to_read -= n_read;
 
+       // the file buffer is empty and there is no read ahead information anymore.
+       iop->_flag &= ~_IOAHEAD;
+    }
+    else
+    {
+       c = _filbuf(iop);
+       if (c != EOF)
+       {
+             *ptr++ = c;
+             to_read--;
+          copy = min(iop->_cnt, to_read);
+          memcpy(ptr, iop->_ptr, copy);
+          iop->_ptr += copy;
+          iop->_cnt -= copy;
+          to_read -= copy;
+       }
+    }
+  }
   return count - (to_read/size);
 }
index 87d01d1..c5f573e 100644 (file)
@@ -3,12 +3,17 @@
 #include <msvcrt/string.h>
 #include <msvcrt/errno.h>
 #include <msvcrt/internal/file.h>
+#define NDEBUG
+#include <msvcrt/msvcrtdbg.h>
 
 
 size_t fwrite(const void *vptr, size_t size, size_t count, FILE *iop)
 {
   size_t to_write, n_written;
-  char *ptr = (char *)vptr;
+  unsigned char *ptr = (unsigned char *)vptr;
+  int copy;
+
+  DPRINT("fwrite(%x, %d, %d, %x)\n", vptr, size, count, iop);
 
   to_write = size*count;
   if (!OPEN4WRITING(iop))
@@ -28,24 +33,79 @@ size_t fwrite(const void *vptr, size_t size, size_t count, FILE *iop)
   if (vptr == NULL || to_write == 0)
     return 0;
 
-  while(iop->_cnt > 0 && to_write > 0)
-    {
-      to_write--;
-      putc(*ptr++,iop);
-    }
+  if (iop->_base == NULL && !(iop->_flag&_IONBF))
+  {
+     if (EOF == _flsbuf(*ptr++, iop))
+        return 0;
+     if (--to_write == 0)
+        return 1;
+  }
 
-  // if the buffer is dirty it will have to be written now
-  // otherwise the file pointer won't match anymore.
-  fflush(iop);
+  if (iop->_flag & _IOLBF)
+  {
+     while (to_write > 0)
+     {
+        if (EOF == putc(*ptr++, iop))
+       {
+          iop->_flag |= _IOERR;
+          break;
+       }
+       to_write--;
+     }
+  }
+  else
+  {
+     if (iop->_cnt > 0 && to_write > 0)
+     {
+        copy = min(iop->_cnt, to_write);
+        memcpy(iop->_ptr, ptr, copy);
+        ptr += copy;
+        iop->_ptr += copy;
+        iop->_cnt -= copy;
+        to_write -= copy;
+        iop->_flag |= _IODIRTY;
+     }
 
-  n_written = _write(fileno(iop), ptr,to_write);
-  if (n_written != -1)
-    to_write -= n_written;
+     if (to_write > 0)
+     {
+        // if the buffer is dirty it will have to be written now
+        // otherwise the file pointer won't match anymore.
+        fflush(iop);
+        if (to_write >= iop->_bufsiz)
+       {
+          while (to_write > 0)
+          {
+             n_written = _write(fileno(iop), ptr, to_write);
+             if (n_written <= 0)
+             {
+                iop->_flag |= _IOERR;
+                break;
+             }
+             to_write -= n_written;
+             ptr += n_written;
+          }
 
-  // check to see if this will work with in combination with ungetc
+           // check to see if this will work with in combination with ungetc
 
-  // the file buffer is empty and there is no read ahead information anymore.
-  iop->_flag &= ~_IOAHEAD;
+           // the file buffer is empty and there is no read ahead information anymore.
+           iop->_flag &= ~_IOAHEAD;
+       }
+        else
+       {
+           if (EOF != _flsbuf(*ptr++, iop))
+          {
+             if (--to_write > 0)
+             {
+                 memcpy(iop->_ptr, ptr, to_write);
+                 iop->_ptr += to_write;
+                 iop->_cnt -= to_write;
+                 iop->_flag |= _IODIRTY;
+                return count;
+             }
+          }
+       }
+     }
+  }
 
   return count - (to_write/size);
 }