1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Refactor str_substr and str_subseq

This commit extracts common code between str_substr and rb_str_subseq
into a function called str_subseq.

This commit also applies optimizations in commit 2e88bca to
rb_str_subseq.
This commit is contained in:
Peter Zhu 2022-09-26 11:39:36 -04:00
parent 830b5b5c35
commit aa2a428cfb
Notes: git 2022-09-27 03:55:08 +09:00

View file

@ -2797,26 +2797,32 @@ rb_str_sublen(VALUE str, long pos)
}
}
VALUE
rb_str_subseq(VALUE str, long beg, long len)
static VALUE
str_subseq(VALUE str, long beg, long len)
{
VALUE str2;
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) &&
SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) {
long olen;
str2 = rb_str_new_shared(rb_str_new_frozen_String(str));
SHARABLE_SUBSTRING_P(beg, len, RSTRING_LEN(str))) {
str2 = rb_str_new_shared(str);
RSTRING(str2)->as.heap.ptr += beg;
olen = RSTRING(str2)->as.heap.len;
if (olen > len) RSTRING(str2)->as.heap.len = len;
if (RSTRING(str2)->as.heap.len > len) {
RSTRING(str2)->as.heap.len = len;
}
}
else {
str2 = rb_str_new(RSTRING_PTR(str)+beg, len);
str2 = rb_str_new(RSTRING_PTR(str) + beg, len);
RB_GC_GUARD(str);
}
rb_enc_cr_str_copy_for_substr(str2, str);
return str2;
}
VALUE
rb_str_subseq(VALUE str, long beg, long len)
{
VALUE str2 = str_subseq(str, beg, len);
rb_enc_cr_str_copy_for_substr(str2, str);
return str2;
}
@ -2916,25 +2922,15 @@ rb_str_substr(VALUE str, long beg, long len)
static VALUE
str_substr(VALUE str, long beg, long len, int empty)
{
VALUE str2;
char *p = rb_str_subpos(str, beg, &len);
if (!p) return Qnil;
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) &&
SHARABLE_SUBSTRING_P(p, len, RSTRING_END(str))) {
long ofs = p - RSTRING_PTR(str);
str2 = str_new_shared(rb_cString, str);
RSTRING(str2)->as.heap.ptr += ofs;
RSTRING(str2)->as.heap.len = len;
ENC_CODERANGE_CLEAR(str2);
}
else {
if (!len && !empty) return Qnil;
str2 = rb_str_new(p, len);
RB_GC_GUARD(str);
}
rb_enc_cr_str_copy_for_substr(str2, str);
if (!len && !empty) return Qnil;
beg = p - RSTRING_PTR(str);
VALUE str2 = str_subseq(str, beg, len);
rb_enc_cr_str_copy_for_substr(str2, str);
return str2;
}
@ -6141,9 +6137,7 @@ rb_str_setbyte(VALUE str, VALUE index, VALUE value)
static VALUE
str_byte_substr(VALUE str, long beg, long len, int empty)
{
char *p, *s = RSTRING_PTR(str);
long n = RSTRING_LEN(str);
VALUE str2;
if (beg > n || len < 0) return Qnil;
if (beg < 0) {
@ -6155,19 +6149,9 @@ str_byte_substr(VALUE str, long beg, long len, int empty)
if (len <= 0) {
if (!empty) return Qnil;
len = 0;
p = 0;
}
else
p = s + beg;
if (!STR_EMBEDDABLE_P(len, TERM_LEN(str)) && SHARABLE_SUBSTRING_P(beg, len, n)) {
str2 = str_new_shared(rb_cString, str);
RSTRING(str2)->as.heap.ptr += beg;
RSTRING(str2)->as.heap.len = len;
}
else {
str2 = rb_str_new(p, len);
}
VALUE str2 = str_subseq(str, beg, len);
str_enc_copy(str2, str);