なかだです。

At Fri, 14 Dec 2007 15:51:27 +0900,
Martin Duerst wrote in [ruby-dev:32591]:
> transcode.c で
>     if (from_enc && to_enc && rb_enc_asciicompat(from_enc) && rb_enc_asciicompat(to_enc)) {
>         if (ENC_CODERANGE(str) == ENC_CODERANGE_7BIT)
>             return Qnil;
>     }
> という部分がありますが、そこで「return Qnil;」にあたれば結果の文字列の
> Encoding は元の Encoding のままになっています。こちらで修正が
> できますが、そうすると中田さんがせっかく rb_str_transcode
> と rb_str_transcode_bang に refactor した部分をまだごっちゃになる
> 可能性が高いので、このあたりお願いできますでしょうか。

変換結果と別にencodingを返すしかないですかねぇ。もう一つ、一連の
bang methodにあわせるなら、変換元と変換先のencodingが同じ場合に
はnilを返すべきかもしれません。


Index: transcode.c =================================================================== --- transcode.c (revision 14226) +++ transcode.c (working copy) @@ -251,8 +251,9 @@ str_transcoding_resize(transcoding *my_t } -static VALUE -str_transcode(int argc, VALUE *argv, VALUE str) +static int +str_transcode(int argc, VALUE *argv, VALUE *self) { VALUE dest; + VALUE str = *self; long blen, slen; char *buf, *bp, *sp, *fromp; @@ -290,12 +291,13 @@ str_transcode(int argc, VALUE *argv, VAL if (from_enc && from_enc == to_enc) { - return Qnil; + return -1; } if (from_enc && to_enc && rb_enc_asciicompat(from_enc) && rb_enc_asciicompat(to_enc)) { - if (ENC_CODERANGE(str) == ENC_CODERANGE_7BIT) - return Qnil; + if (ENC_CODERANGE(str) == ENC_CODERANGE_7BIT) { + return to_encidx; + } } if (strcasecmp(from_e, to_e) == 0) { - return Qnil; + return -1; } if (!(my_transcoder = transcode_dispatch(from_e, to_e))) { @@ -323,9 +325,8 @@ str_transcode(int argc, VALUE *argv, VAL if (!to_enc) { to_encidx = rb_enc_replicate(to_e, rb_default_encoding()); - to_enc = rb_enc_from_index(to_encidx); } - rb_enc_associate(dest, to_enc); + *self = dest; - return dest; + return to_encidx; } @@ -345,8 +346,10 @@ static VALUE rb_str_transcode_bang(int argc, VALUE *argv, VALUE str) { - VALUE newstr = str_transcode(argc, argv, str); - if (NIL_P(newstr)) return str; + VALUE newstr = str; + int encidx = str_transcode(argc, argv, &newstr); + + if (encidx < 0) return Qnil; rb_str_shared_replace(str, newstr); - rb_enc_copy(str, newstr); + rb_enc_associate_index(str, encidx); return str; } @@ -365,8 +368,16 @@ static VALUE rb_str_transcode(int argc, VALUE *argv, VALUE str) { - VALUE newstr = str_transcode(argc, argv, str); - if (NIL_P(newstr)) return rb_str_dup(str); - RBASIC(newstr)->klass = rb_obj_class(str); - OBJ_INFECT(newstr, str); + VALUE newstr = str; + int encidx = str_transcode(argc, argv, &newstr); + + if (newstr == str) { + newstr = rb_str_new3(str); + if (encidx >= 0) rb_enc_associate_index(newstr, encidx); + } + else { + RBASIC(newstr)->klass = rb_obj_class(str); + OBJ_INFECT(newstr, str); + rb_enc_associate_index(newstr, encidx); + } return newstr; }
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦