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

ruby-changes:40066

From: nobu <ko1@a...>
Date: Sat, 17 Oct 2015 13:55:58 +0900 (JST)
Subject: [ruby-changes:40066] nobu:r52147 (trunk): string.c: rb_str_cat_conv_enc_opts

nobu	2015-10-17 13:55:47 +0900 (Sat, 17 Oct 2015)

  New Revision: 52147

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

  Log:
    string.c: rb_str_cat_conv_enc_opts
    
    * file.c (rb_file_expand_path_internal): concatenate converted
      string to the result instead of making converted string and
      append it.
    * string.c (rb_str_cat_conv_enc_opts): from rb_str_conv_enc_opts,
      separate function to concatenate with transcoding.

  Modified files:
    trunk/ChangeLog
    trunk/file.c
    trunk/internal.h
    trunk/string.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52146)
+++ ChangeLog	(revision 52147)
@@ -1,3 +1,21 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Oct 17 13:55:45 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* file.c (rb_file_expand_path_internal): concatenate converted
+	  string to the result instead of making converted string and
+	  append it.
+
+	* string.c (rb_str_cat_conv_enc_opts): from rb_str_conv_enc_opts,
+	  separate function to concatenate with transcoding.
+
+Sat Oct 17 13:55:32 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* file.c (rb_file_expand_path_internal): concatenate converted
+	  string to the result instead of making converted string and
+	  append it.
+
+	* string.c (rb_str_cat_conv_enc_opts): from rb_str_conv_enc_opts,
+	  separate function to concatenate with transcoding.
+
 Sat Oct 17 13:19:10 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* ruby.c (load_file): unify each preparations and clean-ups by
Index: string.c
===================================================================
--- string.c	(revision 52146)
+++ string.c	(revision 52147)
@@ -802,17 +802,16 @@ rb_tainted_str_new_cstr(const char *ptr) https://github.com/ruby/ruby/blob/trunk/string.c#L802
     return str;
 }
 
+static VALUE str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
+				   rb_encoding *from, rb_encoding *to,
+				   int ecflags, VALUE ecopts);
+
 VALUE
 rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
 {
-    rb_econv_t *ec;
-    rb_econv_result_t ret;
-    long len, olen;
-    VALUE econv_wrapper;
+    long len;
+    const char *ptr;
     VALUE newstr;
-    const unsigned char *start, *sp;
-    unsigned char *dest, *dp;
-    size_t converted_output = 0;
 
     if (!to) return str;
     if (!from) from = rb_enc_get(str);
@@ -826,18 +825,60 @@ rb_str_conv_enc_opts(VALUE str, rb_encod https://github.com/ruby/ruby/blob/trunk/string.c#L825
 	return str;
     }
 
-    len = RSTRING_LEN(str);
-    newstr = rb_str_new(0, len);
+    RSTRING_GETMEM(str, ptr, len);
+    newstr = str_cat_conv_enc_opts(rb_str_buf_new(len), 0, ptr, len,
+				   from, to, ecflags, ecopts);
+    if (NIL_P(newstr)) {
+	/* some error, return original */
+	return str;
+    }
     OBJ_INFECT(newstr, str);
-    olen = len;
+    return newstr;
+}
+
+VALUE
+rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
+			 rb_encoding *from, int ecflags, VALUE ecopts)
+{
+    long olen;
+
+    olen = RSTRING_LEN(newstr);
+    if (ofs < -olen || olen <= ofs)
+        rb_raise(rb_eIndexError, "index %ld out of string", ofs);
+    if (ofs < 0) ofs += olen;
+    if (!from) {
+	STR_SET_LEN(newstr, ofs);
+	return rb_str_cat(newstr, ptr, len);
+    }
+
+    rb_str_modify(newstr);
+    return str_cat_conv_enc_opts(newstr, ofs, ptr, len, from,
+				 rb_enc_get(newstr),
+				 ecflags, ecopts);
+}
+
+static VALUE
+str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
+		      rb_encoding *from, rb_encoding *to,
+		      int ecflags, VALUE ecopts)
+{
+    rb_econv_t *ec;
+    rb_econv_result_t ret;
+    long olen;
+    VALUE econv_wrapper;
+    const unsigned char *start, *sp;
+    unsigned char *dest, *dp;
+    size_t converted_output = (size_t)ofs;
+
+    olen = rb_str_capacity(newstr);
 
     econv_wrapper = rb_obj_alloc(rb_cEncodingConverter);
     RBASIC_CLEAR_CLASS(econv_wrapper);
     ec = rb_econv_open_opts(from->name, to->name, ecflags, ecopts);
-    if (!ec) return str;
+    if (!ec) return Qnil;
     DATA_PTR(econv_wrapper) = ec;
 
-    sp = (unsigned char*)RSTRING_PTR(str);
+    sp = (unsigned char*)ptr;
     start = sp;
     while ((dest = (unsigned char*)RSTRING_PTR(newstr)),
 	   (dp = dest + converted_output),
@@ -869,8 +910,7 @@ rb_str_conv_enc_opts(VALUE str, rb_encod https://github.com/ruby/ruby/blob/trunk/string.c#L910
 	return newstr;
 
       default:
-	/* some error, return original */
-	return str;
+	return Qnil;
     }
 }
 
Index: internal.h
===================================================================
--- internal.h	(revision 52146)
+++ internal.h	(revision 52147)
@@ -1101,6 +1101,8 @@ void rb_str_fill_terminator(VALUE str, c https://github.com/ruby/ruby/blob/trunk/internal.h#L1101
 VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
 #ifdef RUBY_ENCODING_H
 VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
+VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
+			       rb_encoding *from, int ecflags, VALUE ecopts);
 #endif
 #define STR_NOEMBED      FL_USER1
 #define STR_SHARED       FL_USER2 /* = ELTS_SHARED */
Index: file.c
===================================================================
--- file.c	(revision 52146)
+++ file.c	(revision 52147)
@@ -3604,14 +3604,16 @@ rb_file_expand_path_internal(VALUE fname https://github.com/ruby/ruby/blob/trunk/file.c#L3604
 	    ++p;
 	    wlen = (int)len;
 	    len = WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen, NULL, 0, NULL, NULL);
-	    BUFCHECK(bdiff + len >= buflen);
-	    WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen, p, len + 1, NULL, NULL);
-	    if (tmp != result) {
-		rb_str_buf_cat(tmp, p, len);
-		tmp = rb_str_encode(tmp, rb_enc_from_encoding(enc), 0, Qnil);
-		len = RSTRING_LEN(tmp);
+	    if (tmp == result) {
 		BUFCHECK(bdiff + len >= buflen);
-		memcpy(p, RSTRING_PTR(tmp), len);
+		WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen, p, len + 1, NULL, NULL);
+	    }
+	    else {
+		rb_str_modify_expand(tmp, len);
+		WideCharToMultiByte(CP_UTF8, 0, wfd.cFileName, wlen, RSTRING_PTR(tmp), len + 1, NULL, NULL);
+		rb_str_cat_conv_enc_opts(result, bdiff, RSTRING_PTR(tmp), len,
+					 rb_utf8_encoding(), 0, Qnil);
+		BUFINIT();
 		rb_str_resize(tmp, 0);
 	    }
 	    p += len;

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

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