mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
string.c: share middle of a string
* string.c (rb_str_new_frozen): consider the shared string at middle. * string.c (rb_str_subseq, rb_str_substr, str_byte_substr): share middle of a string. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45628 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
95013cd5c0
commit
609a6ebac5
3 changed files with 28 additions and 11 deletions
|
@ -1,3 +1,11 @@
|
|||
Fri Apr 18 21:48:24 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* string.c (rb_str_new_frozen): consider the shared string at
|
||||
middle.
|
||||
|
||||
* string.c (rb_str_subseq, rb_str_substr, str_byte_substr): share
|
||||
middle of a string.
|
||||
|
||||
Fri Apr 18 15:40:05 2014 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* string.c: use uintptr_t instead of VALUE because they are not ruby
|
||||
|
|
5
NEWS
5
NEWS
|
@ -107,3 +107,8 @@ with all sufficient information, see the ChangeLog file.
|
|||
Ruby's heaps.
|
||||
|
||||
* rb_str_cat_cstr() added. This is same as `rb_str_cat2()`.
|
||||
|
||||
* `rb_str_substr()` and `rb_str_subseq()` now share middle of a string,
|
||||
but not only the end of a string. Therefore, result strings may not
|
||||
be NULL-terminated, `StringValueCStr()` is needed calling to obtain a
|
||||
NULL-terminated C string.
|
||||
|
|
26
string.c
26
string.c
|
@ -823,16 +823,17 @@ rb_str_new_frozen(VALUE orig)
|
|||
else {
|
||||
if (FL_TEST(orig, STR_SHARED)) {
|
||||
VALUE shared = RSTRING(orig)->as.heap.aux.shared;
|
||||
long ofs = RSTRING_LEN(shared) - RSTRING_LEN(orig);
|
||||
long ofs = RSTRING_PTR(orig) - RSTRING_PTR(shared);
|
||||
long rest = RSTRING_LEN(shared) - ofs - RSTRING_LEN(orig);
|
||||
assert(OBJ_FROZEN(shared));
|
||||
|
||||
if ((ofs > 0) ||
|
||||
if ((ofs > 0) || (rest > 0) ||
|
||||
(klass != RBASIC(shared)->klass) ||
|
||||
((RBASIC(shared)->flags ^ RBASIC(orig)->flags) & FL_TAINT) ||
|
||||
ENCODING_GET(shared) != ENCODING_GET(orig)) {
|
||||
str = str_new_shared(klass, shared);
|
||||
RSTRING(str)->as.heap.ptr += ofs;
|
||||
RSTRING(str)->as.heap.len -= ofs;
|
||||
RSTRING(str)->as.heap.len -= ofs + rest;
|
||||
}
|
||||
else {
|
||||
return shared;
|
||||
|
@ -1789,10 +1790,12 @@ rb_str_subseq(VALUE str, long beg, long len)
|
|||
{
|
||||
VALUE str2;
|
||||
|
||||
if (RSTRING_LEN(str) == beg + len &&
|
||||
RSTRING_EMBED_LEN_MAX < len) {
|
||||
str2 = rb_str_new_shared(rb_str_new_frozen(str));
|
||||
rb_str_drop_bytes(str2, beg);
|
||||
if (RSTRING_EMBED_LEN_MAX < len) {
|
||||
long olen;
|
||||
str2 = rb_str_new_shared(rb_str_new_frozen(str));
|
||||
RSTRING(str2)->as.heap.ptr += beg;
|
||||
olen = RSTRING(str2)->as.heap.len;
|
||||
if (olen > len) RSTRING(str2)->as.heap.len = len;
|
||||
}
|
||||
else {
|
||||
str2 = rb_str_new_with_class(str, RSTRING_PTR(str)+beg, len);
|
||||
|
@ -1897,10 +1900,11 @@ rb_str_substr(VALUE str, long beg, long len)
|
|||
char *p = rb_str_subpos(str, beg, &len);
|
||||
|
||||
if (!p) return Qnil;
|
||||
if (len > RSTRING_EMBED_LEN_MAX && p + len == RSTRING_END(str)) {
|
||||
if (len > RSTRING_EMBED_LEN_MAX) {
|
||||
long ofs = p - RSTRING_PTR(str);
|
||||
str2 = rb_str_new_frozen(str);
|
||||
str2 = str_new_shared(rb_obj_class(str2), str2);
|
||||
RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;
|
||||
RSTRING(str2)->as.heap.ptr += ofs;
|
||||
RSTRING(str2)->as.heap.len = len;
|
||||
}
|
||||
else {
|
||||
|
@ -4409,10 +4413,10 @@ str_byte_substr(VALUE str, long beg, long len)
|
|||
else
|
||||
p = s + beg;
|
||||
|
||||
if (len > RSTRING_EMBED_LEN_MAX && beg + len == n) {
|
||||
if (len > RSTRING_EMBED_LEN_MAX) {
|
||||
str2 = rb_str_new_frozen(str);
|
||||
str2 = str_new_shared(rb_obj_class(str2), str2);
|
||||
RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;
|
||||
RSTRING(str2)->as.heap.ptr += beg;
|
||||
RSTRING(str2)->as.heap.len = len;
|
||||
}
|
||||
else {
|
||||
|
|
Loading…
Add table
Reference in a new issue