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

ruby-changes:3005

From: ko1@a...
Date: 23 Dec 2007 01:21:42 +0900
Subject: [ruby-changes:3005] davidflanagan - Ruby:r14497 (trunk): * io.c, io.h: temporary patch to partially implement transcode-on-read and transcode-on-write

davidflanagan	2007-12-23 01:21:09 +0900 (Sun, 23 Dec 2007)

  New Revision: 14497

  Modified files:
    trunk/ChangeLog
    trunk/include/ruby/io.h
    trunk/io.c

  Log:
    * io.c, io.h: temporary patch to partially implement transcode-on-read and transcode-on-write

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14497&r2=14496
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/io.c?r1=14497&r2=14496
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/include/ruby/io.h?r1=14497&r2=14496

Index: include/ruby/io.h
===================================================================
--- include/ruby/io.h	(revision 14496)
+++ include/ruby/io.h	(revision 14497)
@@ -47,6 +47,7 @@
     int rbuf_capa;
     VALUE tied_io_for_writing;
     rb_encoding *enc;
+    rb_encoding *enc2;
 } rb_io_t;
 
 #define HAVE_RB_IO_T 1
@@ -91,6 +92,7 @@
     fp->rbuf_capa = 0;\
     fp->tied_io_for_writing = 0;\
     fp->enc = 0;\
+    fp->enc2 = 0;\
 } while (0)
 
 FILE *rb_io_stdio_file(rb_io_t *fptr);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 14496)
+++ ChangeLog	(revision 14497)
@@ -1,3 +1,8 @@
+Sun Dec 23 01:18:06 2007  David Flanagan  <david@d...>
+
+	* io.c, io.h: temporary patch to partially implement
+          transcode-on-read and transcode-on-write
+
 Sun Dec 23 00:48:05 2007  Shugo Maeda  <shugo@r...>
 
 	* test/net/imap/test_imap.rb: added tests for SSL.
Index: io.c
===================================================================
--- io.c	(revision 14496)
+++ io.c	(revision 14497)
@@ -124,7 +124,7 @@
 
 static VALUE argf;
 
-static ID id_write, id_read, id_getc, id_flush;
+static ID id_write, id_read, id_getc, id_flush, id_encode;
 
 extern char *ruby_inplace_mode;
 
@@ -622,6 +622,26 @@
 {
     long len, n, r, l, offset = 0;
 
+    /*
+     * If an external encoding was specified and it differs from
+     * the strings encoding then we must transcode before writing.
+     * We must also transcode if two encodings were specified
+     */
+    if (fptr->enc && (fptr->enc2 || fptr->enc != rb_enc_get(str))) {
+	/* transcode str before output */
+	/* the methods in transcode.c are static, so call indirectly */
+	/* Can't use encode! because puts writes a frozen newline */
+	if (fptr->enc2) {
+	    str = rb_funcall(str, id_encode, 2, 
+			     rb_enc_from_encoding(fptr->enc),
+			     rb_enc_from_encoding(fptr->enc2));
+	}
+	else {
+	    str = rb_funcall(str, id_encode, 1, 
+			     rb_enc_from_encoding(fptr->enc));
+	}
+    }
+
     len = RSTRING_LEN(str);
     if ((n = len) <= 0) return n;
     if (fptr->wbuf == NULL && !(fptr->mode & FMODE_SYNC)) {
@@ -1279,7 +1299,17 @@
 {
     OBJ_TAINT(str);
     if (fptr->enc) {
-	rb_enc_associate(str, fptr->enc);
+	if (fptr->enc2) {
+	    /* two encodings, so transcode from enc2 to enc */
+            /* the methods in transcode.c are static, so call indirectly */
+	    str = rb_funcall(str, id_encode, 2, 
+			     rb_enc_from_encoding(fptr->enc2),
+			     rb_enc_from_encoding(fptr->enc));
+	}
+	else {
+	    /* just one encoding, so associate it with the string */
+	    rb_enc_associate(str, fptr->enc);
+	}
     }
     return str;
 }
@@ -2878,11 +2908,11 @@
 static VALUE
 rb_io_binmode_m(VALUE io)
 {
+    rb_io_binmode(io);
+
 #if defined(_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__)
     VALUE write_io;
 
-    rb_io_binmode(io);
-
     write_io = GetWriteIO(io);
     if (write_io != io)
         rb_io_binmode(write_io);
@@ -3063,7 +3093,8 @@
 rb_io_mode_enc(rb_io_t *fptr, const char *mode)
 {
     const char *p0, *p1;
-    int idx;
+    char *enc2name;
+    int idx, idx2;
     
     p0 = strrchr(mode, ':');
     if (p0) {
@@ -3071,13 +3102,31 @@
 	if (idx >= 0) {
 	    fptr->enc = rb_enc_from_index(idx);
 	}
-#if 0
+	else {
+	    rb_warn("Unsupported encoding %s ignored", p0+1);
+	}
 	p1 = strchr(mode, ':');
 	if (p1 < p0) {
+	    enc2name = ALLOCA_N(char, p0-p1);
+	    strncpy(enc2name, p1+1, p0-p1-1);
+	    enc2name[p0-p1-1] = '\0';
+	    idx2=rb_enc_find_index(enc2name);
+	    if (idx2 == idx) {
+		rb_warn("Ignoring internal encoding %s: it is identical to external encoding %s",
+			enc2name, p0+1);
+	    }
+	    else if (idx2 >= 0) {
+		fptr->enc2 = rb_enc_from_index(idx2);
+	    }
+	    else {
+		rb_warn("Unsupported encoding %s ignored", enc2name);
+	    }
 	}
-#endif
     }
-    else if (!(fptr->mode & FMODE_BINMODE)) {
+    else if (fptr->mode & FMODE_BINMODE) {
+	fptr->enc = rb_ascii_encoding();
+    }
+    else {
 	fptr->enc = rb_default_external_encoding();
     }
 }
@@ -5703,6 +5752,11 @@
     return rb_enc_from_encoding(fptr->enc);
 }
 
+static VALUE
+argf_external_encoding(void)
+{
+    return rb_enc_default_external();
+}
 
 static VALUE
 argf_tell(void)
@@ -6155,6 +6209,7 @@
     id_read = rb_intern("read");
     id_getc = rb_intern("getc");
     id_flush = rb_intern("flush");
+    id_encode = rb_intern("encode");
 
     rb_define_global_function("syscall", rb_f_syscall, -1);
 
@@ -6339,6 +6394,8 @@
     rb_define_singleton_method(argf, "lineno",   argf_lineno, 0);
     rb_define_singleton_method(argf, "lineno=",  argf_set_lineno, 1);
 
+    rb_define_singleton_method(argf, "external_encoding", argf_external_encoding, 0);
+
     rb_global_variable(&current_file);
     rb_define_readonly_variable("$FILENAME", &filename);
     filename = rb_str_new2("-");

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

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