#849: MacRuby throws the exception of "Encoding::CompatibilityError" with various cases. ----------------------------------+----------------------------------------- Reporter: watson1978@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ----------------------------------+----------------------------------------- Comment(by watson1978@…): I think pack('U') to be repaired by the following patch. {{{ #!diff diff --git a/encoding.c b/encoding.c index d3295a0..dc590a8 100644 --- a/encoding.c +++ b/encoding.c @@ -519,9 +519,7 @@ rb_enc_get_index(VALUE obj) void rb_enc_set_index(VALUE obj, int encindex) { - if (encindex < ENCODINGS_COUNT) { - return ; - } + assert(encindex >= 0 && encindex < ENCODINGS_COUNT); rb_str_force_encoding(obj, rb_encodings[encindex]); } diff --git a/include/ruby/intern.h b/include/ruby/intern.h index d8b3940..58fc56a 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -174,6 +174,9 @@ VALUE rb_fiber_resume(VALUE fib, int argc, VALUE *args); VALUE rb_fiber_yield(int argc, VALUE *args); VALUE rb_fiber_current(void); VALUE rb_fiber_alive_p(VALUE); +/* encoding.c */ +void rb_enc_set_index(VALUE obj, int encindex); +int rb_utf8_encindex(void); /* enum.c */ /* error.c */ VALUE rb_exc_new(VALUE, const char*, long); diff --git a/pack.c b/pack.c index 9d073cb..89c9142 100644 --- a/pack.c +++ b/pack.c @@ -446,6 +446,7 @@ pack_pack(VALUE ary, SEL sel, VALUE fmt) char type; long items, len, idx, plen; const char *ptr; + int enc_info = 1; /* 0 - BINARY, 1 - US-ASCII, 2 - UTF-8 */ #ifdef NATINT_PACK int natint; /* native integer */ #endif @@ -508,6 +509,20 @@ pack_pack(VALUE ary, SEL sel, VALUE fmt) } switch (type) { + case 'U': + /* if encoding is US-ASCII, upgrade to UTF-8 */ + if (enc_info == 1) enc_info = 2; + break; + case 'm': case 'M': case 'u': + /* keep US-ASCII (do nothing) */ + break; + default: + /* fall back to BINARY */ + enc_info = 0; + break; + } + + switch (type) { case 'A': case 'a': case 'Z': case 'B': case 'b': case 'H': case 'h': @@ -1014,6 +1029,20 @@ pack_pack(VALUE ary, SEL sel, VALUE fmt) } } + OBJ_INFECT(data, fmt); + switch (enc_info) { + case 1: + // TODO + // ENCODING_CODERANGE_SET(data, rb_usascii_encindex(), ENC_CODERANGE_7BIT); + break; + case 2: + rb_enc_set_index(data, rb_utf8_encindex()); + break; + default: + /* do nothing, keep ASCII-8BIT */ + break; + } + // Taint the ByteString accordingly. if (OBJ_TAINTED(fmt)) { OBJ_TAINT(data); }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/849#comment:5> MacRuby <http://macruby.org/>