summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--test/ruby/test_econv.rb53
-rw-r--r--transcode.c42
3 files changed, 69 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index d6356aa79..acaab7484 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Aug 13 07:41:03 2008 Tanaka Akira <akr@fsij.org>
+
+ * transcode.c (rb_trans_conv): report last transcode_obuf_full.
+ (econv_max_output): new method Encoding::Converter#max_output.
+
Wed Aug 13 02:46:01 2008 NARUSE, Yui <naruse@ruby-lang.org>
* error.c (rb_eEncCompatError): add Exception.
diff --git a/test/ruby/test_econv.rb b/test/ruby/test_econv.rb
index 045a4a0e0..4bae60a87 100644
--- a/test/ruby/test_econv.rb
+++ b/test/ruby/test_econv.rb
@@ -1,24 +1,53 @@
require 'test/unit'
class TestEncodingConverter < Test::Unit::TestCase
- def assert_econv(ret_expected, src_expected, dst_expected, from, to, src, dst, flags=0)
+ def assert_econv(ret_expected, dst_expected, src_expected, to, from, src, opt={})
+ opt[:obuf_len] ||= 100
+ src = src.dup
ec = Encoding::Converter.new(from, to)
- ret = ec.primitive_convert(src, dst, flags)
- assert_equal(ret_expected, ret)
- assert_equal(src_expected, src)
- assert_equal(dst_expected, dst)
+ dst = ''
+ while true
+ ret = ec.primitive_convert(src, dst2=" "*opt[:obuf_len], 0)
+ dst << dst2
+ #p [ret, dst, src]
+ break if ret != :obuf_full
+ end
+ assert_equal([ret_expected, dst_expected, src_expected], [ret, dst, src])
end
def test_eucjp_to_utf8
- assert_econv(:finished, "", "", "EUC-JP", "UTF-8", "", "")
- assert_econv(:ibuf_empty, "", "", "EUC-JP", "UTF-8", "", "", Encoding::Converter::PARTIAL_INPUT)
- assert_econv(:finished, "", "", "EUC-JP", "UTF-8", "", " "*10)
- assert_econv(:obuf_full, "", "", "EUC-JP", "UTF-8", "a", "")
+ assert_econv(:finished, "", "", "EUC-JP", "UTF-8", "")
+ assert_econv(:finished, "a", "", "EUC-JP", "UTF-8", "a")
+ end
+
+ def test_iso2022jp
+ assert_econv(:finished, "", "", "ISO-2022-JP", "Shift_JIS", "")
end
def test_invalid
- assert_econv(:invalid_input, "", "", "EUC-JP", "UTF-8", "\x80", " "*10)
- assert_econv(:invalid_input, "", "a", "EUC-JP", "UTF-8", "a\x80", " "*10)
- assert_econv(:invalid_input, "\x80", "a", "EUC-JP", "UTF-8", "a\x80\x80", " "*10)
+ assert_econv(:invalid_input, "", "", "EUC-JP", "UTF-8", "\x80")
+ assert_econv(:invalid_input, "a", "", "EUC-JP", "UTF-8", "a\x80")
+ assert_econv(:invalid_input, "a", "\x80", "EUC-JP", "UTF-8", "a\x80\x80")
+ assert_econv(:invalid_input, "abc", "def", "EUC-JP", "UTF-8", "abc\xFFdef")
+ assert_econv(:invalid_input, "abc", "def", "EUC-JP", "Shift_JIS", "abc\xFFdef")
+ assert_econv(:invalid_input, "abc", "def", "EUC-JP", "Shift_JIS", "abc\xFFdef", :obuf_len=>1)
+ assert_econv(:invalid_input, "abc", "def", "Shift_JIS", "ISO-2022-JP", "abc\xFFdef")
+ end
+
+ def test_errors
+ ec = Encoding::Converter.new("UTF-16BE", "EUC-JP")
+ src = "\xFF\xFE\x00A\xDC\x00"
+ ret = ec.primitive_convert(src, dst=" "*10, 0)
+ assert_equal("", src)
+ assert_equal("", dst)
+ assert_equal(:undefined_conversion, ret)
+ ret = ec.primitive_convert(src, dst=" "*10, 0)
+ assert_equal("", src)
+ assert_equal("A", dst)
+ assert_equal(:invalid_input, ret)
+ ret = ec.primitive_convert(src, dst=" "*10, 0)
+ assert_equal("", src)
+ assert_equal("", dst)
+ assert_equal(:finished, ret)
end
end
diff --git a/transcode.c b/transcode.c
index 5f361e775..478b52ae5 100644
--- a/transcode.c
+++ b/transcode.c
@@ -749,7 +749,7 @@ rb_trans_conv(rb_trans_t *ts,
int flags)
{
int i;
- int start, err_index, no_error;
+ int start, err_index;
unsigned char empty_buf;
unsigned char *empty_ptr = &empty_buf;
@@ -764,20 +764,11 @@ rb_trans_conv(rb_trans_t *ts,
output_stop = empty_ptr;
}
- no_error = 1;
err_index = -1;
for (i = ts->num_trans-1; 0 <= i; i--) {
- if (ts->elems[i].last_result == transcode_invalid_input ||
- ts->elems[i].last_result == transcode_undefined_conversion) {
- if (no_error) {
- /* last error */
- no_error = 0;
- }
- else {
- /* second last error */
- err_index = i;
- break;
- }
+ if (ts->elems[i].last_result != transcode_ibuf_empty) {
+ err_index = i;
+ break;
}
}
@@ -786,12 +777,14 @@ rb_trans_conv(rb_trans_t *ts,
err_index = trans_sweep(ts, input_ptr, input_stop, output_ptr, output_stop, flags, start);
} while (err_index != -1 && err_index != ts->num_trans-1);
- if (err_index == ts->num_trans-1)
- return ts->elems[ts->num_trans-1].last_result;
- else if (start == 0)
- return ts->elems[ts->num_trans-1].last_result;
- else
- return ts->elems[start-1].last_result;
+ for (i = ts->num_trans-1; 0 <= i; i--) {
+ if (ts->elems[i].last_result != transcode_ibuf_empty) {
+ rb_trans_result_t res = ts->elems[i].last_result;
+ ts->elems[i].last_result = transcode_ibuf_empty;
+ return res;
+ }
+ }
+ return transcode_ibuf_empty;
}
static void
@@ -1303,6 +1296,16 @@ econv_primitive_convert(VALUE self, VALUE input, VALUE output, VALUE flags_v)
}
}
+static VALUE
+econv_max_output(VALUE self)
+{
+ rb_trans_t *ts = check_econv(self);
+ int n;
+ n = ts->elems[ts->num_trans-1].tc->transcoder->max_output;
+
+ return INT2FIX(n);
+}
+
void
Init_transcode(void)
{
@@ -1323,5 +1326,6 @@ Init_transcode(void)
rb_define_alloc_func(rb_cEncodingConverter, econv_s_allocate);
rb_define_method(rb_cEncodingConverter, "initialize", econv_init, 2);
rb_define_method(rb_cEncodingConverter, "primitive_convert", econv_primitive_convert, 3);
+ rb_define_method(rb_cEncodingConverter, "max_output", econv_max_output, 0);
rb_define_const(rb_cEncodingConverter, "PARTIAL_INPUT", INT2FIX(PARTIAL_INPUT));
}