[MSVCRT #3]Lower fragmentation of Readfile calls for TEXT mode

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Sun Oct 5 09:54:18 CDT 2003


Changelog
	dlls/msvcrt/file.c: _read()
	In _O_TEXT mode make Readfile Calls in Chunks as big as possible

This increases the the speed of XILINX  ISE.
-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
--- wine/dlls/msvcrt/file.c_fread	2003-10-05 13:45:24.000000000 +0200
+++ wine/dlls/msvcrt/file.c	2003-10-05 13:52:30.000000000 +0200
@@ -1164,11 +1164,47 @@
 }
 
 /*********************************************************************
+ * (internal) remove_cr
+ *
+ *    Remove all \r inplace.
+ * return the number of \r removed
+ */
+
+static DWORD remove_cr(void *buf, unsigned int count)
+{
+  DWORD i=0;
+  char *bufstart=(char*)buf;
+  char *from;
+  char *to;
+
+  if (!count) return 0;
+  if (count == 1)
+    return (*bufstart == '\r')?1:0;
+  from= (char *)memchr((const void *) buf, '\r', count);
+  if (from)
+    to  = (char *)memchr((const void *) (from+1),'\r',bufstart + count - from - 1);
+  while (from && to)
+    {
+      i++;
+      memmove((void*)from,(void*)(from+i), to - from -i);
+      from += to - from -i;
+      to   = memchr((const void *) (to+1),'\r',bufstart + count - to +1);
+    }
+  if (from)
+    {
+      i++;
+      memmove((void*)from,(void*)(from+i), bufstart + count - from -i);
+    }
+  return i;
+}    
+
+/*********************************************************************
  *		_read (MSVCRT.@)
  */
 int _read(int fd, void *buf, unsigned int count)
 {
-  DWORD num_read;
+  DWORD num_read, all_read =0;
+  char *bufstart = (char*) buf;
   HANDLE hand = msvcrt_fdtoh(fd);
 
   /* Dont trace small reads, it gets *very* annoying */
@@ -1177,56 +1213,49 @@
   if (hand == INVALID_HANDLE_VALUE)
     return -1;
 
-  if (MSVCRT_flags[fd]& _O_BINARY)
+  /* Reading single bytes in O_TEXT mode makes things slow
+   * So read big chunks, then remove the \r in memory and try reading
+   * the rest until the request is satisfied or EOF is met
+   */
+  while (  all_read < count)
     {
-      if (ReadFile(hand, buf, count, &num_read, NULL))
+      if (ReadFile(hand, bufstart+all_read, count - all_read, &num_read, NULL))
 	{
-	  if (num_read != count && MSVCRT_files[fd])
+	  if (num_read != (count- all_read))
 	    {
 	      TRACE(":EOF\n");
+	      if ( MSVCRT_files[fd])
+		{
 	      MSVCRT_flags[fd] |= MSVCRT__IOEOF;
 	      /*
 		MSVCRT_files[fd]->_flag |= MSVCRT__IOEOF;
 	      */
 	    }
-	  TRACE("%s\n",debugstr_an(buf,num_read));
-	  return num_read;
-	}
-      TRACE(":failed-last error (%ld)\n",GetLastError());
-      if (MSVCRT_files[fd])
-	MSVCRT_files[fd]->_flag |= MSVCRT__IOERR;
-      return -1;
+	      if ((MSVCRT_flags[fd]& _O_BINARY ) !=  _O_BINARY )
+		num_read -= remove_cr(bufstart+all_read,num_read);
+	      all_read += num_read;
+	      if (count > 4)
+		TRACE("%s\n",debugstr_an(buf,all_read));
+	      return all_read;
     }
-  else
-    {
-      char cc, *s=(char*)buf,* buf_start=(char*)buf;
-      unsigned int i;
-      
-      for (i = 0 , num_read = 1; i < count && (num_read == 1);)
+	  if ((MSVCRT_flags[fd]& _O_BINARY ) !=  _O_BINARY )
 	{
-	  if (ReadFile(hand, &cc, 1, &num_read, NULL))
-	    if (num_read == 1)
-	      if ((cc != '\r') || MSVCRT_flags[fd] & _O_BINARY)
-		{
-		  *s++ = (char)cc;
-		  i++;
+	      num_read -= remove_cr(bufstart+all_read,num_read);
 		}
+	  all_read += num_read;
 	}
-      if (num_read != 1)
+      else
 	{
-	  TRACE(":EOF\n");
+	  TRACE(":failed-last error (%ld)\n",GetLastError());
 	  if (MSVCRT_files[fd])
-	    MSVCRT_flags[fd] |= MSVCRT__IOEOF;
-	  /*
-	    MSVCRT_files[fd]->_flag |= MSVCRT__IOEOF;
-	  */
+	    MSVCRT_files[fd]->_flag |= MSVCRT__IOERR;
+	  return -1;
+	}
 	}
   
       if (count > 4)
-	TRACE("%s\n",debugstr_an(buf_start, s-buf_start));
-      return s-buf_start;
-    }
-  return 0;
+    TRACE("%s\n",debugstr_an(buf, all_read));
+  return all_read;
 }
 
 /*********************************************************************



More information about the wine-patches mailing list