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(¤t_file); rb_define_readonly_variable("$FILENAME", &filename); filename = rb_str_new2("-"); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml