зеркало из https://github.com/github/ruby.git
* 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:
Родитель
018bdcadac
Коммит
b83cbb0c7c
|
@ -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
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(¤t_file);
|
||||
rb_define_readonly_variable("$FILENAME", &filename);
|
||||
filename = rb_str_new2("-");
|
||||
|
|
Загрузка…
Ссылка в новой задаче