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

ruby-changes:4355

From: ko1@a...
Date: Fri, 28 Mar 2008 19:58:44 +0900 (JST)
Subject: [ruby-changes:4355] yugui - Ruby:r15845 (trunk): * io.c (rb_io_each_char, rb_io_chars, argf_each_char, io_getc): Added character-wise

yugui	2008-03-28 19:58:31 +0900 (Fri, 28 Mar 2008)

  New Revision: 15845

  Modified files:
    trunk/io.c

  Log:
    * io.c (rb_io_each_char, rb_io_chars, argf_each_char, io_getc): Added character-wise
      iterators; IO#each_char, IO#chars, ARGF#each_char. [ruby-dev:34052]


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/io.c?r1=15845&r2=15844&diff_format=u

Index: io.c
===================================================================
--- io.c	(revision 15844)
+++ io.c	(revision 15845)
@@ -2227,8 +2227,79 @@
     return io;
 }
 
+static VALUE 
+io_getc(rb_io_t *fptr, rb_encoding *enc)
+{
+    int r, n;
+    VALUE str;
+
+    if (io_fillbuf(fptr) < 0) {
+	return Qnil;
+    }
+    r = rb_enc_precise_mbclen(fptr->rbuf+fptr->rbuf_off, fptr->rbuf+fptr->rbuf_off+fptr->rbuf_len, enc);
+    if (MBCLEN_CHARFOUND_P(r) &&
+        (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf_len) {
+	str = rb_str_new(fptr->rbuf+fptr->rbuf_off, n);
+	fptr->rbuf_off += n;
+	fptr->rbuf_len -= n;
+    }
+    else if (MBCLEN_NEEDMORE_P(r)) {
+	str = rb_str_new(fptr->rbuf+fptr->rbuf_off, fptr->rbuf_len);
+        fptr->rbuf_len = 0;
+      getc_needmore:
+        if (io_fillbuf(fptr) != -1) {
+            rb_str_cat(str, fptr->rbuf+fptr->rbuf_off, 1);
+            fptr->rbuf_off++;
+            fptr->rbuf_len--;
+            r = rb_enc_precise_mbclen(RSTRING_PTR(str), RSTRING_PTR(str)+RSTRING_LEN(str), enc);
+            if (MBCLEN_NEEDMORE_P(r)) {
+                goto getc_needmore;
+            }
+        }
+    }
+    else {
+	str = rb_str_new(fptr->rbuf+fptr->rbuf_off, 1);
+	fptr->rbuf_off++;
+	fptr->rbuf_len--;
+    }
+    return io_enc_str(str, fptr);
+}
+
 /*
  *  call-seq:
+ *     ios.each_char {|c| block }  => ios
+ *
+ *  Calls the given block once for each character in <em>ios</em>,
+ *  passing the character as an argument. The stream must be opened for
+ *  reading or an <code>IOError</code> will be raised.
+ *
+ *     f = File.new("testfile")
+ *     f.each_char {|c| print c, ' ' }   #=> #<File:testfile>
+ */
+
+static VALUE
+rb_io_each_char(VALUE io)
+{
+    rb_io_t *fptr;
+    rb_encoding *enc;
+    VALUE c;
+
+    RETURN_ENUMERATOR(io, 0, 0);
+    GetOpenFile(io, fptr);
+    rb_io_check_readable(fptr);
+
+    enc = io_input_encoding(fptr);
+    READ_CHECK(fptr);
+    while (!NIL_P(c = io_getc(fptr, enc))) {
+        rb_yield(c);
+    }
+    return io;
+}
+
+
+
+/*
+ *  call-seq:
  *     str.lines(sep=$/)     => anEnumerator
  *     str.lines(limit)      => anEnumerator
  *     str.lines(sep, limit) => anEnumerator
@@ -2240,9 +2311,9 @@
  */
 
 static VALUE
-rb_io_lines(int argc, VALUE *argv, VALUE str)
+rb_io_lines(int argc, VALUE *argv, VALUE io)
 {
-    return rb_enumeratorize(str, ID2SYM(rb_intern("each_line")), argc, argv);
+    return rb_enumeratorize(io, ID2SYM(rb_intern("each_line")), argc, argv);
 }
 
 /*
@@ -2255,13 +2326,31 @@
  */
 
 static VALUE
-rb_io_bytes(VALUE str)
+rb_io_bytes(VALUE io)
 {
-    return rb_enumeratorize(str, ID2SYM(rb_intern("each_byte")), 0, 0);
+    return rb_enumeratorize(io, ID2SYM(rb_intern("each_byte")), 0, 0);
 }
 
 /*
  *  call-seq:
+ *     ios.chars   => anEnumerator
+ *  
+ *  Returns an enumerator that gives each character in <em>ios</em>.
+ *  The stream must be opened for reading or an <code>IOError</code>
+ *  will be raised.
+ *     
+ *     f = File.new("testfile)
+ *     f.chars.each {|c| print c, ' ' }
+ */
+
+static VALUE
+rb_io_chars(VALUE io)
+{
+    return rb_enumeratorize(io, ID2SYM(rb_intern("each_char")), 0, 0);
+}
+
+/*
+ *  call-seq:
  *     ios.getc   => fixnum or nil
  *
  *  Reads a one-character string from <em>ios</em>. Returns
@@ -2285,38 +2374,8 @@
 
     enc = io_input_encoding(fptr);
     READ_CHECK(fptr);
-    if (io_fillbuf(fptr) < 0) {
-	return Qnil;
-    }
-    r = rb_enc_precise_mbclen(fptr->rbuf+fptr->rbuf_off, fptr->rbuf+fptr->rbuf_off+fptr->rbuf_len, enc);
-    if (MBCLEN_CHARFOUND_P(r) &&
-        (n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf_len) {
-	str = rb_str_new(fptr->rbuf+fptr->rbuf_off, n);
-	fptr->rbuf_off += n;
-	fptr->rbuf_len -= n;
-    }
-    else if (MBCLEN_NEEDMORE_P(r)) {
-	str = rb_str_new(fptr->rbuf+fptr->rbuf_off, fptr->rbuf_len);
-        fptr->rbuf_len = 0;
-      getc_needmore:
-        if (io_fillbuf(fptr) != -1) {
-            rb_str_cat(str, fptr->rbuf+fptr->rbuf_off, 1);
-            fptr->rbuf_off++;
-            fptr->rbuf_len--;
-            r = rb_enc_precise_mbclen(RSTRING_PTR(str), RSTRING_PTR(str)+RSTRING_LEN(str), enc);
-            if (MBCLEN_NEEDMORE_P(r)) {
-                goto getc_needmore;
-            }
-        }
-    }
-    else {
-	str = rb_str_new(fptr->rbuf+fptr->rbuf_off, 1);
-	fptr->rbuf_off++;
-	fptr->rbuf_len--;
-    }
-    return io_enc_str(str, fptr);
+    return io_getc(fptr, enc);
 }
-
 int
 rb_getc(FILE *f)
 {
@@ -6535,6 +6594,17 @@
 }
 
 static VALUE
+argf_each_char(VALUE argf)
+{
+    RETURN_ENUMERATOR(argf, 0, 0);
+    for (;;) {
+	if (!next_argv()) return Qnil;
+	rb_block_call(current_file, rb_intern("each_char"), 0, 0, rb_yield, 0);
+	next_p = 1;
+    }
+}
+
+static VALUE
 argf_filename(VALUE argf)
 {
     next_argv();
@@ -6831,8 +6901,10 @@
     rb_define_method(rb_cIO, "each",  rb_io_each_line, -1);
     rb_define_method(rb_cIO, "each_line",  rb_io_each_line, -1);
     rb_define_method(rb_cIO, "each_byte",  rb_io_each_byte, 0);
+    rb_define_method(rb_cIO, "each_char",  rb_io_each_char, 0);
     rb_define_method(rb_cIO, "lines",  rb_io_lines, -1);
     rb_define_method(rb_cIO, "bytes",  rb_io_bytes, 0);
+    rb_define_method(rb_cIO, "chars",  rb_io_chars, 0);
 
     rb_define_method(rb_cIO, "syswrite", rb_io_syswrite, 1);
     rb_define_method(rb_cIO, "sysread",  rb_io_sysread, -1);
@@ -6929,6 +7001,7 @@
     rb_define_method(rb_cARGF, "each",  argf_each_line, -1);
     rb_define_method(rb_cARGF, "each_line",  argf_each_line, -1);
     rb_define_method(rb_cARGF, "each_byte",  argf_each_byte, 0);
+    rb_define_method(rb_cARGF, "each_char",  argf_each_char, 0);
 
     rb_define_method(rb_cARGF, "read",  argf_read, -1);
     rb_define_method(rb_cARGF, "readpartial",  argf_readpartial, -1);

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

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