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

ruby-changes:7638

From: akr <ko1@a...>
Date: Sat, 6 Sep 2008 03:20:40 +0900 (JST)
Subject: [ruby-changes:7638] Ruby:r19159 (trunk): * transcode.c (allocate_converted_string): add arguments for a buffer

akr	2008-09-06 03:20:20 +0900 (Sat, 06 Sep 2008)

  New Revision: 19159

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19159

  Log:
    * transcode.c (allocate_converted_string): add arguments for a buffer
      allocated by caller.
      (rb_econv_insert_output): provide caller allocated buffer to
      allocate_converted_string.

  Modified files:
    trunk/ChangeLog
    trunk/transcode.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 19158)
+++ ChangeLog	(revision 19159)
@@ -1,3 +1,10 @@
+Sat Sep  6 03:18:17 2008  Tanaka Akira  <akr@f...>
+
+	* transcode.c (allocate_converted_string): add arguments for a buffer
+	  allocated by caller.
+	  (rb_econv_insert_output): provide caller allocated buffer to
+	  allocate_converted_string.
+
 Sat Sep  6 02:58:53 2008  Tanaka Akira  <akr@f...>
 
 	* transcode.c (str_transcode_enc_args): local variables renamed.
Index: transcode.c
===================================================================
--- transcode.c	(revision 19158)
+++ transcode.c	(revision 19159)
@@ -1327,11 +1327,12 @@
 static unsigned char *
 allocate_converted_string(const char *sname, const char *dname,
         const unsigned char *str, size_t len,
+        unsigned char *caller_dst_buf, size_t caller_dst_bufsize,
         size_t *dst_len_ptr)
 {
     unsigned char *dst_str;
     size_t dst_len;
-    size_t dst_bufsize = len;
+    size_t dst_bufsize;
 
     rb_econv_t *ec;
     rb_econv_result_t res;
@@ -1339,13 +1340,20 @@
     const unsigned char *sp;
     unsigned char *dp;
 
-    if (dst_bufsize == 0)
-        dst_bufsize += 1;
+    if (caller_dst_buf)
+        dst_bufsize = caller_dst_bufsize;
+    else if (len == 0)
+        dst_bufsize = 1;
+    else
+        dst_bufsize = len;
 
     ec = rb_econv_open(sname, dname, 0);
     if (ec == NULL)
         return NULL;
-    dst_str = xmalloc(dst_bufsize);
+    if (caller_dst_buf)
+        dst_str = caller_dst_buf;
+    else
+        dst_str = xmalloc(dst_bufsize);
     dst_len = 0;
     sp = str;
     dp = dst_str+dst_len;
@@ -1353,24 +1361,34 @@
     dst_len = dp - dst_str;
     while (res == econv_destination_buffer_full) {
         if (dst_bufsize * 2 < dst_bufsize) {
-            xfree(dst_str);
-            rb_econv_close(ec);
-            return NULL;
+            goto fail;
         }
         dst_bufsize *= 2;
-        dst_str = xrealloc(dst_str, dst_bufsize);
+        if (dst_str == caller_dst_buf) {
+            unsigned char *tmp;
+            tmp = xmalloc(dst_bufsize);
+            memcpy(tmp, dst_str, dst_bufsize/2);
+            dst_str = tmp;
+        }
+        else {
+            dst_str = xrealloc(dst_str, dst_bufsize);
+        }
         dp = dst_str+dst_len;
         res = rb_econv_convert(ec, &sp, str+len, &dp, dst_str+dst_bufsize, 0);
         dst_len = dp - dst_str;
     }
     if (res != econv_finished) {
-        xfree(dst_str);
-        rb_econv_close(ec);
-        return NULL;
+        goto fail;
     }
     rb_econv_close(ec);
     *dst_len_ptr = dst_len;
     return dst_str;
+
+  fail:
+    if (dst_str != caller_dst_buf)
+        xfree(dst_str);
+    rb_econv_close(ec);
+    return NULL;
 }
 
 /* result: 0:success -1:failure */
@@ -1379,7 +1397,8 @@
     const unsigned char *str, size_t len, const char *str_encoding)
 {
     const char *insert_encoding = rb_econv_encoding_to_insert_output(ec);
-    const unsigned char *insert_str;
+    unsigned char insert_buf[4096];
+    const unsigned char *insert_str = NULL;
     size_t insert_len;
 
     rb_transcoding *tc;
@@ -1399,7 +1418,8 @@
         insert_len = len;
     }
     else {
-        insert_str = allocate_converted_string(str_encoding, insert_encoding, str, len, &insert_len);
+        insert_str = allocate_converted_string(str_encoding, insert_encoding,
+                str, len, insert_buf, sizeof(insert_buf), &insert_len);
         if (insert_str == NULL)
             return -1;
     }
@@ -1471,12 +1491,12 @@
     memcpy(*data_end_p, insert_str, insert_len);
     *data_end_p += insert_len;
 
-    if (insert_str != str)
+    if (insert_str != str && insert_str != insert_buf)
         xfree((void*)insert_str);
     return 0;
 
   fail:
-    if (insert_str != str)
+    if (insert_str != str && insert_str != insert_buf)
         xfree((void*)insert_str);
     return -1;
 }
@@ -1809,7 +1829,7 @@
 
     ins_enc = rb_econv_encoding_to_insert_output(ec);
     if (*repl_enc && !encoding_equal(repl_enc, ins_enc)) {
-        replacement = allocate_converted_string(repl_enc, ins_enc, replacement, len, &len);
+        replacement = allocate_converted_string(repl_enc, ins_enc, replacement, len, NULL, 0, &len);
         if (!replacement)
             return -1;
         allocated = 1;
@@ -1839,7 +1859,7 @@
         encname2 = encname;
     }
     else {
-        str2 = allocate_converted_string(encname, encname2, str, len, &len2);
+        str2 = allocate_converted_string(encname, encname2, str, len, NULL, 0, &len2);
         if (!str2)
             return -1;
     }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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