diff --git a/ChangeLog b/ChangeLog index 17d2f7a5c2..cad39ba42f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Fri Aug 29 02:45:29 2008 Tanaka Akira + + * transcode.c (econv_convert): new method. + Fri Aug 29 02:38:14 2008 Tanaka Akira * transcode.c (econv_primitive_convert): accept nil as diff --git a/test/ruby/test_econv.rb b/test/ruby/test_econv.rb index 7d6e78227b..8f29fb9f31 100644 --- a/test/ruby/test_econv.rb +++ b/test/ruby/test_econv.rb @@ -559,4 +559,13 @@ class TestEncodingConverter < Test::Unit::TestCase assert_equal(:finished, ret) assert_equal(["xyzabc", ""], [dst, src]) end + + def test_convert + ec = Encoding::Converter.new("utf-8", "euc-jp") + assert_raise(Encoding::InvalidByteSequence) { ec.convert("a\x80") } + assert_raise(Encoding::ConversionUndefined) { ec.convert("\ufffd") } + ret = ec.primitive_convert(nil, "", nil, nil) + assert_equal(:finished, ret) + assert_raise(ArgumentError) { ec.convert("a") } + end end diff --git a/transcode.c b/transcode.c index 52c6d27ef8..79450a43ae 100644 --- a/transcode.c +++ b/transcode.c @@ -2491,6 +2491,59 @@ econv_primitive_convert(int argc, VALUE *argv, VALUE self) return econv_result_to_symbol(res); } +/* + * call-seq: + * convert(source_string) -> destination_string + * + * convert source_string and return destination_string. + * + * source_string is assumed as a part of source. + * i.e. Encoding::Converter::PARTIAL_INPUT is used internally. + * + * If a conversion error occur, + * Encoding::ConversionUndefined or + * Encoding::InvalidByteSequence is raised. + * + */ +static VALUE +econv_convert(VALUE self, VALUE source_string) +{ + VALUE ret, dst; + VALUE av[5]; + int ac; + rb_econv_t *ec = check_econv(self); + + StringValue(source_string); + + dst = rb_str_new(NULL, 0); + + av[0] = rb_str_dup(source_string); + av[1] = dst; + av[2] = Qnil; + av[3] = Qnil; + av[4] = INT2NUM(ECONV_PARTIAL_INPUT); + ac = 5; + + ret = econv_primitive_convert(ac, av, self); + + if (ret == sym_invalid_byte_sequence || + ret == sym_undefined_conversion || + ret == sym_incomplete_input) { + VALUE exc = make_econv_exception(ec); + rb_exc_raise(exc); + } + + if (ret == sym_finished) { + rb_raise(rb_eArgError, "converter already finished"); + } + + if (ret != sym_source_buffer_empty) { + rb_bug("unexpected result of econv_primitive_convert"); + } + + return dst; +} + /* * call-seq: * primitive_errinfo -> array @@ -2721,6 +2774,7 @@ Init_transcode(void) rb_define_method(rb_cEncodingConverter, "source_encoding", econv_source_encoding, 0); rb_define_method(rb_cEncodingConverter, "destination_encoding", econv_destination_encoding, 0); rb_define_method(rb_cEncodingConverter, "primitive_convert", econv_primitive_convert, -1); + rb_define_method(rb_cEncodingConverter, "convert", econv_convert, 1); rb_define_method(rb_cEncodingConverter, "primitive_errinfo", econv_primitive_errinfo, 0); rb_define_method(rb_cEncodingConverter, "primitive_insert_output", econv_primitive_insert_output, 1); rb_define_method(rb_cEncodingConverter, "primitive_putback", econv_primitive_putback, 1);