ruby-changes:7316
From: akr <ko1@a...>
Date: Mon, 25 Aug 2008 22:04:37 +0900 (JST)
Subject: [ruby-changes:7316] Ruby:r18835 (trunk): * transcode.c (rb_econv_open_by_transcoder_entries): initialize
akr 2008-08-25 22:04:16 +0900 (Mon, 25 Aug 2008) New Revision: 18835 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18835 Log: * transcode.c (rb_econv_open_by_transcoder_entries): initialize last_error. num_trans may be zero. (rb_econv_convert0): num_trans may be zero. (rb_econv_putbackable): ditto. (rb_econv_putback): ditto. (rb_econv_convert): input_ptr and output_ptr may be NULL. Modified files: trunk/ChangeLog trunk/test/ruby/test_econv.rb trunk/transcode.c Index: ChangeLog =================================================================== --- ChangeLog (revision 18834) +++ ChangeLog (revision 18835) @@ -1,3 +1,12 @@ +Mon Aug 25 22:02:35 2008 Tanaka Akira <akr@f...> + + * transcode.c (rb_econv_open_by_transcoder_entries): initialize + last_error. num_trans may be zero. + (rb_econv_convert0): num_trans may be zero. + (rb_econv_putbackable): ditto. + (rb_econv_putback): ditto. + (rb_econv_convert): input_ptr and output_ptr may be NULL. + Mon Aug 25 19:05:27 2008 Yukihiro Matsumoto <matz@r...> * compile.c (defined_expr): should handle NODE_{AND,OR} as Index: test/ruby/test_econv.rb =================================================================== --- test/ruby/test_econv.rb (revision 18834) +++ test/ruby/test_econv.rb (revision 18835) @@ -480,5 +480,45 @@ assert_equal("abcdef", dst) end + def test_noconv + ec = Encoding::Converter.new("", "") + assert_equal(nil, ec.source_encoding) + assert_equal(nil, ec.destination_encoding) + assert_equal([:source_buffer_empty, nil, nil, nil, nil, nil], ec.primitive_errinfo) + a = ["", "abcdefg", ec, nil, 2] + check_ec("ab", "cdefg", :destination_buffer_full, *a) + check_ec("abcd", "efg", :destination_buffer_full, *a) + check_ec("abcdef", "g", :destination_buffer_full, *a) + check_ec("abcdefg", "", :finished, *a) + end + def test_noconv_partial + ec = Encoding::Converter.new("", "") + a = ["", "abcdefg", ec, nil, 2, Encoding::Converter::PARTIAL_INPUT] + check_ec("ab", "cdefg", :destination_buffer_full, *a) + check_ec("abcd", "efg", :destination_buffer_full, *a) + check_ec("abcdef", "g", :destination_buffer_full, *a) + check_ec("abcdefg", "", :source_buffer_empty, *a) + end + + def test_noconv_output_followed_by_input + ec = Encoding::Converter.new("", "") + a = ["", "abcdefg", ec, nil, 2, Encoding::Converter::OUTPUT_FOLLOWED_BY_INPUT] + check_ec("a", "bcdefg", :output_followed_by_input, *a) + check_ec("ab", "cdefg", :output_followed_by_input, *a) + check_ec("abc", "defg", :output_followed_by_input, *a) + check_ec("abcd", "efg", :output_followed_by_input, *a) + check_ec("abcde", "fg", :output_followed_by_input, *a) + check_ec("abcdef", "g", :output_followed_by_input, *a) + check_ec("abcdefg", "", :output_followed_by_input, *a) + check_ec("abcdefg", "", :finished, *a) + end + + def test_noconv_insert_output + ec = Encoding::Converter.new("", "") + ec.primitive_insert_output("xyz") + ret = ec.primitive_convert(src="abc", dst="", nil, 20) + assert_equal(:finished, ret) + assert_equal(["xyzabc", ""], [dst, src]) + end end Index: transcode.c =================================================================== --- transcode.c (revision 18834) +++ transcode.c (revision 18835) @@ -688,6 +688,14 @@ ec->num_finished = 0; ec->last_tc = NULL; ec->last_trans_index = -1; + ec->last_error.result = econv_source_buffer_empty; + ec->last_error.error_tc = NULL; + ec->last_error.source_encoding = NULL; + ec->last_error.destination_encoding = NULL; + ec->last_error.error_bytes_start = NULL; + ec->last_error.error_bytes_len = 0; + ec->last_error.readagain_len = 0; + ec->last_error.partial_input = 0; ec->source_encoding = NULL; ec->destination_encoding = NULL; for (i = 0; i < ec->num_trans; i++) { @@ -699,7 +707,8 @@ ec->elems[i].out_buf_end = NULL; ec->elems[i].last_result = econv_source_buffer_empty; } - ec->last_tc = ec->elems[ec->num_trans-1].tc; + if (ec->num_trans) + ec->last_tc = ec->elems[ec->num_trans-1].tc; ec->last_trans_index = ec->num_trans-1; for (i = 0; i < ec->num_trans-1; i++) { @@ -984,6 +993,49 @@ memset(&ec->last_error, 0, sizeof(ec->last_error)); + if (ec->num_trans == 0) { + size_t len; + if (ec->in_buf_start && ec->in_data_start != ec->in_data_end) { + if (output_stop - *output_ptr < ec->in_data_end - ec->in_data_start) { + len = output_stop - *output_ptr; + memcpy(*output_ptr, ec->in_data_start, len); + *output_ptr = output_stop; + ec->in_data_start += len; + res = econv_destination_buffer_full; + goto gotresult; + } + len = ec->in_data_end - ec->in_data_start; + memcpy(*output_ptr, ec->in_data_start, len); + *output_ptr += len; + ec->in_data_start = ec->in_data_end = ec->in_buf_start; + if (flags & ECONV_OUTPUT_FOLLOWED_BY_INPUT) { + res = econv_output_followed_by_input; + goto gotresult; + } + } + if (output_stop - *output_ptr < input_stop - *input_ptr) { + len = output_stop - *output_ptr; + } + else { + len = input_stop - *input_ptr; + } + if (0 < len && (flags & ECONV_OUTPUT_FOLLOWED_BY_INPUT)) { + *(*output_ptr)++ = *(*input_ptr)++; + res = econv_output_followed_by_input; + goto gotresult; + } + memcpy(*output_ptr, *input_ptr, len); + *output_ptr += len; + *input_ptr += len; + if (*input_ptr != input_stop) + res = econv_destination_buffer_full; + else if (flags & ECONV_PARTIAL_INPUT) + res = econv_source_buffer_empty; + else + res = econv_finished; + goto gotresult; + } + if (ec->elems[ec->num_trans-1].out_data_start) { unsigned char *data_start = ec->elems[ec->num_trans-1].out_data_start; unsigned char *data_end = ec->elems[ec->num_trans-1].out_data_end; @@ -1061,6 +1113,19 @@ { rb_econv_result_t ret; + unsigned char empty_buf; + unsigned char *empty_ptr = &empty_buf; + + if (!input_ptr) { + input_ptr = (const unsigned char **)&empty_ptr; + input_stop = empty_ptr; + } + + if (!output_ptr) { + output_ptr = &empty_ptr; + output_stop = empty_ptr; + } + resume: ret = rb_econv_convert0(ec, input_ptr, input_stop, output_ptr, output_stop, flags); @@ -1283,13 +1348,18 @@ int rb_econv_putbackable(rb_econv_t *ec) { + if (ec->num_trans == 0) + return 0; return ec->elems[0].tc->readagain_len; } void rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n) { - rb_transcoding *tc = ec->elems[0].tc; + rb_transcoding *tc; + if (ec->num_trans == 0 || n == 0) + return; + tc = ec->elems[0].tc; memcpy(p, TRANSCODING_READBUF(tc) + tc->recognized_len, n); tc->readagain_len -= n; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/