From 1b1cedb02233863c5f13803de9bcd990804a4f54 Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 7 Sep 2008 03:13:29 +0000 Subject: * include/ruby/encoding.h (ECONV_XML_ATTR_CONTENT_ENCODER): defined. (ECONV_STATEFUL_ENCODER_MASK): defined. (ECONV_XML_ATTR_QUOTE_ENCODER): defined. (ECONV_XML_ATTR_ENCODER): removed. * enc/trans/escape.trans (rb_escape_xml_attr_content): defined. (rb_escape_xml_attr_quote): defined. (rb_escape_xml_attr): removed. * io.c (NEED_WRITECONV): writeconv is required if supplemental converter is used. (make_writeconv): apply stateful encoder in writeconv. * transcode.c: follow the constant change. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@19209 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- io.c | 62 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 27 deletions(-) (limited to 'io.c') diff --git a/io.c b/io.c index ac7c1f16b..5c43a062d 100644 --- a/io.c +++ b/io.c @@ -682,7 +682,7 @@ rb_io_wait_writable(int f) # define NEED_NEWLINE_ENCODER(fptr) 0 #endif #define NEED_READCONV(fptr) (fptr->encs.enc2 != NULL || NEED_NEWLINE_DECODER(fptr)) -#define NEED_WRITECONV(fptr) (fptr->encs.enc != NULL || NEED_NEWLINE_ENCODER(fptr)) +#define NEED_WRITECONV(fptr) (fptr->encs.enc != NULL || NEED_NEWLINE_ENCODER(fptr) || (fptr->encs.ecflags & (ECONV_DECODER_MASK|ECONV_ENCODER_MASK|ECONV_STATEFUL_ENCODER_MASK))) static void make_writeconv(rb_io_t *fptr) @@ -695,42 +695,50 @@ make_writeconv(rb_io_t *fptr) fptr->writeconv_initialized = 1; - /* ECONV_INVALID_XXX and ECONV_UNDEF_XXX should be set both. - * But ECONV_CRLF_NEWLINE_ENCODER should be set only for the first. */ - fptr->writeconv_pre_ecflags = fptr->encs.ecflags; - fptr->writeconv_pre_ecopts = fptr->encs.ecopts; ecflags = fptr->encs.ecflags; ecopts = fptr->encs.ecopts; - #ifdef TEXTMODE_NEWLINE_ENCODER + if (NEED_NEWLINE_ENCODER(fptr)) + ecflags |= TEXTMODE_NEWLINE_ENCODER; +#endif + if (!fptr->encs.enc) { - if (NEED_NEWLINE_ENCODER(fptr)) - ecflags |= TEXTMODE_NEWLINE_ENCODER; + /* no encoding conversion */ + fptr->writeconv_pre_ecflags = 0; + fptr->writeconv_pre_ecopts = Qnil; fptr->writeconv = rb_econv_open_opts("", "", ecflags, ecopts); if (!fptr->writeconv) rb_exc_raise(rb_econv_open_exc("", "", ecflags)); fptr->writeconv_stateless = Qnil; - return; - } - - if (NEED_NEWLINE_ENCODER(fptr)) - fptr->writeconv_pre_ecflags |= TEXTMODE_NEWLINE_ENCODER; -#endif - ecflags &= ECONV_ERROR_HANDLER_MASK; - - enc = fptr->encs.enc2 ? fptr->encs.enc2 : fptr->encs.enc; - senc = rb_econv_stateless_encoding(enc->name); - if (senc) { - denc = enc->name; - fptr->writeconv_stateless = rb_str_new2(senc); - fptr->writeconv = rb_econv_open_opts(senc, denc, ecflags, ecopts); - if (!fptr->writeconv) - rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags)); } else { - denc = NULL; - fptr->writeconv_stateless = Qnil; - fptr->writeconv = NULL; + enc = fptr->encs.enc2 ? fptr->encs.enc2 : fptr->encs.enc; + senc = rb_econv_stateless_encoding(enc->name); + if (!senc && !(fptr->encs.ecflags & ECONV_STATEFUL_ENCODER_MASK)) { + /* single conversion */ + fptr->writeconv_pre_ecflags = ecflags; + fptr->writeconv_pre_ecopts = ecopts; + fptr->writeconv = NULL; + fptr->writeconv_stateless = Qnil; + } + else { + /* double conversion */ + fptr->writeconv_pre_ecflags = ecflags & ~ECONV_STATEFUL_ENCODER_MASK; + fptr->writeconv_pre_ecopts = ecopts; + if (senc) { + denc = enc->name; + fptr->writeconv_stateless = rb_str_new2(senc); + } + else { + senc = denc = ""; + fptr->writeconv_stateless = rb_str_new2(enc->name); + } + ecflags = fptr->encs.ecflags & (ECONV_ERROR_HANDLER_MASK|ECONV_STATEFUL_ENCODER_MASK); + ecopts = fptr->encs.ecopts; + fptr->writeconv = rb_econv_open_opts(senc, denc, ecflags, ecopts); + if (!fptr->writeconv) + rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags)); + } } } } -- cgit