guile-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

guile/guile-core/libguile ChangeLog fports.c io...


From: Gary Houston
Subject: guile/guile-core/libguile ChangeLog fports.c io...
Date: Sat, 06 Jan 2001 14:03:08 -0800

CVSROOT:        /cvs
Module name:    guile
Changes by:     Gary Houston <address@hidden>   01/01/06 14:03:07

Modified files:
        guile-core/libguile: ChangeLog fports.c ioext.c ioext.h ports.c 
                             ports.h 

Log message:
        * ioext.c (scm_read_string_x_partial): new procedure, implements
        read-string!/partial.
        * ports.c (scm_take_from_input_buffers): new procedure used by
        scm_read_string_x_partial.
        (scm_drain_input): use scm_take_from_input_buffers.

CVSWeb URLs:
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-core/libguile/ChangeLog.diff?r1=1.1229&r2=1.1230
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-core/libguile/fports.c.diff?r1=1.87&r2=1.88
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-core/libguile/ioext.c.diff?r1=1.73&r2=1.74
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-core/libguile/ioext.h.diff?r1=1.21&r2=1.22
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-core/libguile/ports.c.diff?r1=1.125&r2=1.126
http://subversions.gnu.org/cgi-bin/cvsweb/guile/guile-core/libguile/ports.h.diff?r1=1.69&r2=1.70

Patches:
Index: guile/guile-core/libguile/ChangeLog
diff -u guile/guile-core/libguile/ChangeLog:1.1229 
guile/guile-core/libguile/ChangeLog:1.1230
--- guile/guile-core/libguile/ChangeLog:1.1229  Sat Jan  6 10:47:12 2001
+++ guile/guile-core/libguile/ChangeLog Sat Jan  6 14:03:07 2001
@@ -1,3 +1,11 @@
+2001-01-06  Gary Houston  <address@hidden>
+
+       * ioext.c (scm_read_string_x_partial): new procedure, implements
+       read-string!/partial.
+       * ports.c (scm_take_from_input_buffers): new procedure used by
+       scm_read_string_x_partial.
+       (scm_drain_input): use scm_take_from_input_buffers.
+
 2001-01-06  Marius Vollmer  <address@hidden>
 
        * validate.h (SCM_VALIDATE_NUMBER): New.
Index: guile/guile-core/libguile/fports.c
diff -u guile/guile-core/libguile/fports.c:1.87 
guile/guile-core/libguile/fports.c:1.88
--- guile/guile-core/libguile/fports.c:1.87     Mon Jan  1 16:38:41 2001
+++ guile/guile-core/libguile/fports.c  Sat Jan  6 14:03:07 2001
@@ -486,9 +486,8 @@
 
 static void fport_flush (SCM port);
 
-/* fill a port's read-buffer with a single read.
-   returns the first char and moves the read_pos pointer past it.
-   or returns EOF if end of file.  */
+/* fill a port's read-buffer with a single read.  returns the first
+   char or EOF if end of file.  */
 static int
 fport_fill_input (SCM port)
 {
Index: guile/guile-core/libguile/ioext.c
diff -u guile/guile-core/libguile/ioext.c:1.73 
guile/guile-core/libguile/ioext.c:1.74
--- guile/guile-core/libguile/ioext.c:1.73      Fri Nov 17 08:25:03 2000
+++ guile/guile-core/libguile/ioext.c   Sat Jan  6 14:03:07 2001
@@ -69,6 +69,110 @@
 #endif
 
 
+SCM_DEFINE (scm_read_string_x_partial, "read-string!/partial", 1, 3, 0,
+           (SCM str, SCM port_or_fdes, SCM start, SCM end),
+           "Read characters from an fport or file descriptor into a\n"
+           "string @var{str}.  This procedure is scsh-compatible\n"
+           "and can efficiently read large strings.  It will:\n\n"
+           "@itemize\n"
+           "@item\n"
+           "attempt to fill the entire string, unless the @var{start}\n"
+           "and/or @var{end} arguments are supplied.  i.e., @var{start}\n"
+           "defaults to 0 and @var{end} defaults to\n"
+           "@code{(string-length str)}\n"
+           "@item\n"
+           "use the current input port if @var{port_or_fdes} is not\n"
+           "supplied.\n" 
+           "@item\n"
+           "read any characters that are currently available,\n"
+           "without waiting for the rest (short reads are possible).\n\n"
+           "@item\n"
+           "wait for as long as it needs to for the first character to\n"
+           "become available, unless the port is in non-blocking mode\n"
+           "@item\n"
+           "return @code{#f} if end-of-file is encountered before reading\n"
+            "any characters, otherwise return the number of characters\n"
+           "read.\n"
+           "@item\n"
+           "return 0 if the port is in non-blocking mode and no characters\n"
+           "are immediately available.\n"
+           "@item\n"
+           "return 0 if the request is for 0 bytes, with no\n"
+           "end-of-file check\n"
+           "@end itemize")
+#define FUNC_NAME s_scm_read_string_x_partial
+{
+  char *dest;
+  long read_len;
+  long chars_read = 0;
+  int fdes = -1;
+  SCM port = SCM_BOOL_F;
+
+  SCM_VALIDATE_STRING_COPY (1, str, dest);
+  if (SCM_UNBNDP (port_or_fdes))
+    port = scm_cur_inp;
+  else if (SCM_INUMP (port_or_fdes))
+    fdes = SCM_INUM (port_or_fdes);
+  else
+    {
+      SCM_VALIDATE_OPFPORT (2, port_or_fdes);
+      SCM_VALIDATE_INPUT_PORT (2, port_or_fdes);
+      port = port_or_fdes;
+    }
+
+  {
+    long string_len = SCM_STRING_LENGTH (str);
+    long offset = SCM_NUM2LONG_DEF (3, start, 0);
+    long last = SCM_NUM2LONG_DEF (4, end, string_len);
+
+    if (offset < 0 || offset > string_len)
+      SCM_OUT_OF_RANGE (3, start);
+    if (last < offset || last > string_len)
+      SCM_OUT_OF_RANGE (4, end);
+
+    dest += offset;
+    read_len = last - offset;
+  }
+
+  if (fdes == -1)
+    {
+      /* if there's anything in the port buffers, use it.  but if
+        something is read from the buffers, don't touch the file
+        descriptor.  otherwise the "return immediately if something
+        is available" rule may be violated.  */
+      chars_read = scm_take_from_input_buffers (port, dest, read_len);
+
+    }
+
+  if (chars_read == 0 && read_len > 0) /* don't confuse read_len == 0 with
+                                         EOF.  */
+    {
+      if (fdes == -1)
+       fdes = SCM_FPORT_FDES (port);
+      
+      SCM_SYSCALL (chars_read = read (fdes, dest, read_len));
+      if (chars_read == -1)
+       {
+#if defined (EWOULDBLOCK) || defined (EAGAIN)
+         if (
+#if defined (EWOULDBLOCK)
+             errno == EWOULDBLOCK
+#else
+             errno == EAGAIN
+#endif
+             )
+           chars_read = 0;
+         else
+#endif
+           SCM_SYSERROR;
+        }
+      else if (chars_read == 0)
+       return SCM_BOOL_F;
+    }
+  return scm_long2num (chars_read);
+}
+#undef FUNC_NAME
+
 SCM_DEFINE (scm_read_delimited_x, "%read-delimited!", 3, 3, 0,
             (SCM delims, SCM buf, SCM gobble, SCM port, SCM start, SCM end),
            "Read characters from @var{port} into @var{buf} until one of the\n"
Index: guile/guile-core/libguile/ioext.h
diff -u guile/guile-core/libguile/ioext.h:1.21 
guile/guile-core/libguile/ioext.h:1.22
--- guile/guile-core/libguile/ioext.h:1.21      Tue Nov  7 13:34:45 2000
+++ guile/guile-core/libguile/ioext.h   Sat Jan  6 14:03:07 2001
@@ -48,7 +48,10 @@
 
 
 
-extern SCM scm_read_delimited_x (SCM delims, SCM buf, SCM gobble, SCM port, 
SCM offset, SCM length);
+extern SCM scm_read_string_x_partial (SCM str, SCM port_or_fdes, SCM start,
+                                     SCM end);
+extern SCM scm_read_delimited_x (SCM delims, SCM buf, SCM gobble, SCM port,
+                                SCM offset, SCM length);
 extern SCM scm_read_line (SCM port);
 extern SCM scm_write_line (SCM obj, SCM port);
 extern SCM scm_ftell (SCM object);
Index: guile/guile-core/libguile/ports.c
diff -u guile/guile-core/libguile/ports.c:1.125 
guile/guile-core/libguile/ports.c:1.126
--- guile/guile-core/libguile/ports.c:1.125     Fri Dec  8 09:32:56 2000
+++ guile/guile-core/libguile/ports.c   Sat Jan  6 14:03:07 2001
@@ -272,6 +272,37 @@
 }
 #undef FUNC_NAME
 
+/* move up to read_len chars from port's putback and/or read buffers
+   into memory starting at dest.  returns the number of chars moved.  */
+size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len)
+{
+  scm_port *pt = SCM_PTAB_ENTRY (port);
+  size_t chars_read = 0;
+  size_t from_buf = min (pt->read_end - pt->read_pos, read_len);
+
+  if (from_buf > 0)
+    {
+      memcpy (dest, pt->read_pos, from_buf);
+      pt->read_pos += from_buf;
+      chars_read += from_buf;
+      read_len -= from_buf;
+      dest += from_buf;
+    }
+
+  /* if putback was active, try the real input buffer too.  */
+  if (pt->read_buf == pt->putback_buf)
+    {
+      from_buf = min (pt->saved_read_end - pt->saved_read_pos, read_len);
+      if (from_buf > 0)
+       {
+         memcpy (dest, pt->saved_read_pos, from_buf);
+         pt->saved_read_pos += from_buf;
+         chars_read += from_buf;
+       }
+    }
+  return chars_read;
+}
+
 /* Clear a port's read buffers, returning the contents.  */
 SCM_DEFINE (scm_drain_input, "drain-input", 1, 0, 0, 
             (SCM port),
@@ -282,7 +313,6 @@
   SCM result;
   scm_port *pt = SCM_PTAB_ENTRY (port);
   int count;
-  char *dst;
 
   SCM_VALIDATE_OPINPORT (1,port);
 
@@ -291,16 +321,7 @@
     count += pt->saved_read_end - pt->saved_read_pos;
 
   result = scm_makstr (count, 0);
-  dst = SCM_STRING_CHARS (result);
-
-  while (pt->read_pos < pt->read_end)
-    *dst++ = *(pt->read_pos++);
-  
-  if (pt->read_buf == pt->putback_buf)
-    {
-      while (pt->saved_read_pos < pt->saved_read_end)
-       *dst++ = *(pt->saved_read_pos++);
-    }
+  scm_take_from_input_buffers (port, SCM_STRING_CHARS (result), count);
 
   return result;
 }
Index: guile/guile-core/libguile/ports.h
diff -u guile/guile-core/libguile/ports.h:1.69 
guile/guile-core/libguile/ports.h:1.70
--- guile/guile-core/libguile/ports.h:1.69      Thu Nov  9 14:44:09 2000
+++ guile/guile-core/libguile/ports.h   Sat Jan  6 14:03:07 2001
@@ -244,6 +244,7 @@
                                                     off_t length));
 extern void scm_set_port_input_waiting (long tc, int (*input_waiting) (SCM));
 extern SCM scm_char_ready_p (SCM port);
+size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
 extern SCM scm_drain_input (SCM port);
 extern SCM scm_current_input_port (void);
 extern SCM scm_current_output_port (void);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]