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

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14497 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
davidflanagan 2007-12-22 16:21:09 +00:00
Родитель 018bdcadac
Коммит b83cbb0c7c
3 изменённых файлов: 72 добавлений и 8 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Sun Dec 23 01:18:06 2007 David Flanagan <david@davidflanagan.com>
* 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@ruby-lang.org>
* test/net/imap/test_imap.rb: added tests for SSL.

Просмотреть файл

@ -47,6 +47,7 @@ typedef struct rb_io_t {
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 @@ typedef struct rb_io_t {
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);

73
io.c
Просмотреть файл

@ -124,7 +124,7 @@ VALUE rb_default_rs;
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 @@ io_fwrite(VALUE str, rb_io_t *fptr)
{
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 @@ io_enc_str(VALUE str, rb_io_t *fptr)
{
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 @@ rb_io_binmode(VALUE io)
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 @@ void
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 @@ rb_io_mode_enc(rb_io_t *fptr, const char *mode)
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 @@ rb_io_external_encoding(VALUE io)
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 @@ Init_IO(void)
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 @@ Init_IO(void)
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("-");