[前][次][番号順一覧][スレッド一覧]

ruby-changes:14034

From: akr <ko1@a...>
Date: Wed, 18 Nov 2009 22:03:38 +0900 (JST)
Subject: [ruby-changes:14034] Ruby:r25845 (trunk): * io.c (fill_cbuf): extracted from more_char.

akr	2009-11-18 22:02:14 +0900 (Wed, 18 Nov 2009)

  New Revision: 25845

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25845

  Log:
    * io.c (fill_cbuf): extracted from more_char.
      (io_shift_cbuf): fix memmove condition.
      (read_all): use fill_cbuf directly to avoid ECONV_AFTER_OUTPUT.
      [ruby-dev:39708]

  Modified files:
    trunk/ChangeLog
    trunk/io.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25844)
+++ ChangeLog	(revision 25845)
@@ -1,3 +1,10 @@
+Wed Nov 18 22:00:13 2009  Tanaka Akira  <akr@f...>
+
+	* io.c (fill_cbuf): extracted from more_char.
+	  (io_shift_cbuf): fix memmove condition.
+	  (read_all): use fill_cbuf directly to avoid ECONV_AFTER_OUTPUT.
+	  [ruby-dev:39708]
+
 Wed Nov 18 18:25:09 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* thread.c (rb_thread_atfork_internal): reinitialize global lock
Index: io.c
===================================================================
--- io.c	(revision 25844)
+++ io.c	(revision 25845)
@@ -1582,17 +1582,22 @@
     }
 }
 
-static int
-more_char(rb_io_t *fptr)
+#define MORE_CHAR_CBUF_FULL Qtrue
+#define MORE_CHAR_FINISHED Qnil
+static VALUE
+fill_cbuf(rb_io_t *fptr, int ec_flags)
 {
     const unsigned char *ss, *sp, *se;
     unsigned char *ds, *dp, *de;
     rb_econv_result_t res;
     int putbackable;
     int cbuf_len0;
+    VALUE exc;
 
+    ec_flags |= ECONV_PARTIAL_INPUT;
+
     if (fptr->cbuf_len == fptr->cbuf_capa)
-        return 0; /* cbuf full */
+        return MORE_CHAR_CBUF_FULL; /* cbuf full */
     if (fptr->cbuf_len == 0)
         fptr->cbuf_off = 0;
     else if (fptr->cbuf_off + fptr->cbuf_len == fptr->cbuf_capa) {
@@ -1607,7 +1612,7 @@
         se = sp + fptr->rbuf_len;
         ds = dp = (unsigned char *)fptr->cbuf + fptr->cbuf_off + fptr->cbuf_len;
         de = (unsigned char *)fptr->cbuf + fptr->cbuf_capa;
-        res = rb_econv_convert(fptr->readconv, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
+        res = rb_econv_convert(fptr->readconv, &sp, se, &dp, de, ec_flags);
         fptr->rbuf_off += (int)(sp - ss);
         fptr->rbuf_len -= (int)(sp - ss);
         fptr->cbuf_len += (int)(dp - ds);
@@ -1619,13 +1624,15 @@
             fptr->rbuf_len += putbackable;
         }
 
-        rb_econv_check_error(fptr->readconv);
+        exc = rb_econv_make_exception(fptr->readconv);
+        if (!NIL_P(exc))
+            return exc;
 
         if (cbuf_len0 != fptr->cbuf_len)
-            return 0;
+            return MORE_CHAR_CBUF_FULL;
 
         if (res == econv_finished) {
-            return -1;
+            return MORE_CHAR_FINISHED;
 	}
 
         if (res == econv_source_buffer_empty) {
@@ -1645,6 +1652,16 @@
 }
 
 static VALUE
+more_char(rb_io_t *fptr)
+{
+    VALUE v;
+    v = fill_cbuf(fptr, ECONV_AFTER_OUTPUT);
+    if (v != MORE_CHAR_CBUF_FULL && v != MORE_CHAR_FINISHED)
+        rb_exc_raise(v);
+    return v;
+}
+
+static VALUE
 io_shift_cbuf(rb_io_t *fptr, int len, VALUE *strp)
 {
     VALUE str;
@@ -1665,7 +1682,7 @@
     /* xxx: set coderange */
     if (fptr->cbuf_len == 0)
         fptr->cbuf_off = 0;
-    if (fptr->cbuf_off < fptr->cbuf_capa/2) {
+    else if (fptr->cbuf_capa/2 < fptr->cbuf_off) {
         memmove(fptr->cbuf, fptr->cbuf+fptr->cbuf_off, fptr->cbuf_len);
         fptr->cbuf_off = 0;
     }
@@ -1686,21 +1703,19 @@
         else rb_str_set_len(str, 0);
         make_readconv(fptr, 0);
         while (1) {
-	    int fin, state = 0;
-
-            if (fptr->cbuf_len > fptr->cbuf_capa / 2) {
+            VALUE v;
+            if (fptr->cbuf_len) {
                 io_shift_cbuf(fptr, fptr->cbuf_len, &str);
             }
-
-	    fin = rb_protect((VALUE (*)(VALUE))more_char, (VALUE)fptr, &state);
-	    if (fin == -1 || state != 0) {
-		if (fptr->cbuf_len) {
-		    io_shift_cbuf(fptr, fptr->cbuf_len, &str);
-		}
-		if (state != 0) {
-		    rb_jump_tag(state);
-		}
-		clear_readconv(fptr);
+            v = fill_cbuf(fptr, 0);
+            if (v != MORE_CHAR_CBUF_FULL && v != MORE_CHAR_FINISHED) {
+                if (fptr->cbuf_len) {
+                    io_shift_cbuf(fptr, fptr->cbuf_len, &str);
+                }
+                rb_exc_raise(v);
+            }
+            if (v == MORE_CHAR_FINISHED) {
+                clear_readconv(fptr);
                 return io_enc_str(str, fptr);
             }
         }
@@ -2181,7 +2196,7 @@
                     return (unsigned char)RSTRING_PTR(str)[RSTRING_LEN(str)-1];
                 }
             }
-        } while (more_char(fptr) != -1);
+        } while (more_char(fptr) != MORE_CHAR_FINISHED);
         clear_readconv(fptr);
         *lp = limit;
         return EOF;
@@ -2695,7 +2710,8 @@
                 }
             }
 
-            if (more_char(fptr) == -1) {
+            if (more_char(fptr) == MORE_CHAR_FINISHED) {
+                clear_readconv(fptr);
                 if (fptr->cbuf_len == 0)
                     return Qnil;
                 /* return an incomplete character just before EOF */
@@ -2830,8 +2846,8 @@
 			rb_raise(rb_eIOError, "too long character");
 		    }
 		}
-		if (more_char(fptr) == -1) {
-		    clear_readconv(fptr);
+		if (more_char(fptr) == MORE_CHAR_FINISHED) {
+                    clear_readconv(fptr);
 		    /* ignore an incomplete character before EOF */
 		    return io;
 		}

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]