diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-31 14:27:20 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-31 14:27:20 +0000 |
commit | de3f2adb53561c99630478e8372326c0d0a63153 (patch) | |
tree | fdb5396870cf2d3b92dc410a0ce8d03ec43e13ce /string.c | |
parent | aaf78dec43d85058d56dda5518fc757398ccf781 (diff) | |
download | ruby-de3f2adb53561c99630478e8372326c0d0a63153.tar.gz |
* string.c (rb_str_resize): embeds if ptr is null. [ruby-dev:32819]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14817 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -924,25 +924,37 @@ rb_str_set_len(VALUE str, long len) VALUE rb_str_resize(VALUE str, long len) { + long slen; + if (len < 0) { rb_raise(rb_eArgError, "negative string size (or size too big)"); } rb_str_modify(str); - if (len != RSTRING_LEN(str)) { + slen = RSTRING_LEN(str); + if (len != slen) { if (STR_EMBED_P(str)) { char *ptr; if (len <= RSTRING_EMBED_LEN_MAX) { STR_SET_EMBED_LEN(str, len); - RSTRING_PTR(str)[len] = '\0'; + RSTRING(str)->as.ary[len] = '\0'; return str; } ptr = ALLOC_N(char,len+1); - MEMCPY(ptr, RSTRING_PTR(str), char, RSTRING_LEN(str)); + MEMCPY(ptr, RSTRING(str)->as.ary, char, slen); RSTRING(str)->as.heap.ptr = ptr; STR_SET_NOEMBED(str); } - else if (RSTRING_LEN(str) < len || RSTRING_LEN(str) - len > 1024) { + else if (len <= RSTRING_EMBED_LEN_MAX) { + char *ptr = RSTRING(str)->as.heap.ptr; + STR_SET_EMBED(str); + MEMCPY(RSTRING(str)->as.ary, ptr, char, len); + RSTRING(str)->as.ary[len] = '\0'; + STR_SET_EMBED_LEN(str, len); + xfree(ptr); + return str; + } + else if (slen < len || slen - len > 1024) { REALLOC_N(RSTRING(str)->as.heap.ptr, char, len+1); } if (!STR_NOCAPA_P(str)) { |