* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18835 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cc3cbd2965
commit
aeffc67dbb
@ -1,3 +1,12 @@
|
|||||||
|
Mon Aug 25 22:02:35 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Mon Aug 25 19:05:27 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* compile.c (defined_expr): should handle NODE_{AND,OR} as
|
* compile.c (defined_expr): should handle NODE_{AND,OR} as
|
||||||
|
@ -480,5 +480,45 @@ class TestEncodingConverter < Test::Unit::TestCase
|
|||||||
assert_equal("abcdef", dst)
|
assert_equal("abcdef", dst)
|
||||||
end
|
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
|
end
|
||||||
|
72
transcode.c
72
transcode.c
@ -688,6 +688,14 @@ rb_econv_open_by_transcoder_entries(int n, transcoder_entry_t **entries)
|
|||||||
ec->num_finished = 0;
|
ec->num_finished = 0;
|
||||||
ec->last_tc = NULL;
|
ec->last_tc = NULL;
|
||||||
ec->last_trans_index = -1;
|
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->source_encoding = NULL;
|
||||||
ec->destination_encoding = NULL;
|
ec->destination_encoding = NULL;
|
||||||
for (i = 0; i < ec->num_trans; i++) {
|
for (i = 0; i < ec->num_trans; i++) {
|
||||||
@ -699,6 +707,7 @@ rb_econv_open_by_transcoder_entries(int n, transcoder_entry_t **entries)
|
|||||||
ec->elems[i].out_buf_end = NULL;
|
ec->elems[i].out_buf_end = NULL;
|
||||||
ec->elems[i].last_result = econv_source_buffer_empty;
|
ec->elems[i].last_result = econv_source_buffer_empty;
|
||||||
}
|
}
|
||||||
|
if (ec->num_trans)
|
||||||
ec->last_tc = ec->elems[ec->num_trans-1].tc;
|
ec->last_tc = ec->elems[ec->num_trans-1].tc;
|
||||||
ec->last_trans_index = ec->num_trans-1;
|
ec->last_trans_index = ec->num_trans-1;
|
||||||
|
|
||||||
@ -984,6 +993,49 @@ rb_econv_convert0(rb_econv_t *ec,
|
|||||||
|
|
||||||
memset(&ec->last_error, 0, sizeof(ec->last_error));
|
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) {
|
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_start = ec->elems[ec->num_trans-1].out_data_start;
|
||||||
unsigned char *data_end = ec->elems[ec->num_trans-1].out_data_end;
|
unsigned char *data_end = ec->elems[ec->num_trans-1].out_data_end;
|
||||||
@ -1061,6 +1113,19 @@ rb_econv_convert(rb_econv_t *ec,
|
|||||||
{
|
{
|
||||||
rb_econv_result_t ret;
|
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:
|
resume:
|
||||||
ret = rb_econv_convert0(ec, input_ptr, input_stop, output_ptr, output_stop, flags);
|
ret = rb_econv_convert0(ec, input_ptr, input_stop, output_ptr, output_stop, flags);
|
||||||
|
|
||||||
@ -1283,13 +1348,18 @@ rb_econv_close(rb_econv_t *ec)
|
|||||||
int
|
int
|
||||||
rb_econv_putbackable(rb_econv_t *ec)
|
rb_econv_putbackable(rb_econv_t *ec)
|
||||||
{
|
{
|
||||||
|
if (ec->num_trans == 0)
|
||||||
|
return 0;
|
||||||
return ec->elems[0].tc->readagain_len;
|
return ec->elems[0].tc->readagain_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_econv_putback(rb_econv_t *ec, unsigned char *p, int n)
|
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);
|
memcpy(p, TRANSCODING_READBUF(tc) + tc->recognized_len, n);
|
||||||
tc->readagain_len -= n;
|
tc->readagain_len -= n;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user