[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]