]> sourceware.org Git - newlib-cygwin.git/commitdiff
2004-09-22 Jeff Johnston <jjohnstn@redhat.com>
authorJeff Johnston <jjohnstn@redhat.com>
Wed, 22 Sep 2004 21:22:07 +0000 (21:22 +0000)
committerJeff Johnston <jjohnstn@redhat.com>
Wed, 22 Sep 2004 21:22:07 +0000 (21:22 +0000)
        * libc/stdio/fread.c (fread):  For non-space-optimized case,
        add special code for unbuffered files to use user buffer and
        only require one low-level system read.

newlib/ChangeLog
newlib/libc/stdio/fread.c

index 22a13214583b7d77f36d49c0ed594b59212c73a5..1d4de3c9f6e12258a458e354548a10fdb7cf221c 100644 (file)
@@ -1,3 +1,9 @@
+2004-09-22  Jeff Johnston  <jjohnstn@redhat.com>
+
+       * libc/stdio/fread.c (fread):  For non-space-optimized case,
+       add special code for unbuffered files to use user buffer and
+       only require one low-level system read.
+
 2004-09-21  Ian Lance Taylor  <ian@wasabisystems.com>
 
        * libc/machine/xscale/setjmp.S: New file, copied from
index d8ceb8666b12f464bc1f9b856b2140be72ee0648..9a074dd4f1b21382b70ce57f30ee6e99d3bb1085 100644 (file)
@@ -130,30 +130,87 @@ _DEFUN(fread, (buf, size, count, fp),
   total = resid;
   p = buf;
 
-  while (resid > (r = fp->_r))
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+
+  /* Optimize unbuffered I/O.  */
+  if (fp->_flags & __SNBF)
+    {
+      /* First copy any available characters from ungetc buffer.  */
+      int copy_size = resid > fp->_r ? fp->_r : resid;
+      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) copy_size);
+      fp->_p += copy_size;
+      fp->_r -= copy_size;
+      p += copy_size;
+      resid -= copy_size;
+
+      /* If still more data needed, free any allocated ungetc buffer.  */
+      if (HASUB (fp) && resid > 0)
+       FREEUB (fp);
+
+      /* Finally read directly into user's buffer if needed.  */
+      if (resid > 0)
+       {
+         int rc = 0;
+         /* save fp buffering state */
+         void *old_base = fp->_bf._base;
+         void * old_p = fp->_p;
+         int old_size = fp->_bf._size;
+         /* allow __refill to use user's buffer */
+         fp->_bf._base = p;
+         fp->_bf._size = resid;
+         fp->_p = p;
+         rc = __srefill (fp);
+         /* restore fp buffering back to original state */
+         resid -= fp->_r;
+         fp->_r = 0;
+         fp->_bf._base = old_base;
+         fp->_bf._size = old_size;
+         fp->_p = old_p;
+         if (rc)
+           {
+             /* no more input: return partial result */
+#ifdef __SCLE
+             if (fp->_flags & __SCLE)
+               {
+                 _funlockfile (fp);
+                 return crlf (fp, buf, total-resid, 1) / size;
+               }
+#endif
+             _funlockfile (fp);
+             return (total - resid) / size;
+           }
+       }
+    }
+  else
+#endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */
     {
-      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r);
-      fp->_p += r;
-      /* fp->_r = 0 ... done in __srefill */
-      p += r;
-      resid -= r;
-      if (__srefill (fp))
+      while (resid > (r = fp->_r))
        {
-         /* no more input: return partial result */
+         _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, (size_t) r);
+         fp->_p += r;
+         /* fp->_r = 0 ... done in __srefill */
+         p += r;
+         resid -= r;
+         if (__srefill (fp))
+           {
+             /* no more input: return partial result */
 #ifdef __SCLE
-          if (fp->_flags & __SCLE)
-            {
-              _funlockfile (fp);
-              return crlf (fp, buf, total-resid, 1) / size;
-            }
+             if (fp->_flags & __SCLE)
+               {
+                 _funlockfile (fp);
+                 return crlf (fp, buf, total-resid, 1) / size;
+               }
 #endif
-          _funlockfile (fp);
-         return (total - resid) / size;
+             _funlockfile (fp);
+             return (total - resid) / size;
+           }
        }
+      _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid);
+      fp->_r -= resid;
+      fp->_p += resid;
     }
-  _CAST_VOID memcpy ((_PTR) p, (_PTR) fp->_p, resid);
-  fp->_r -= resid;
-  fp->_p += resid;
+
+  /* Perform any CR/LF clean-up if necessary.  */
 #ifdef __SCLE
   if (fp->_flags & __SCLE)
     {
This page took 0.04544 seconds and 5 git commands to generate.