summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2022-09-26 11:39:36 -0400
committerPeter Zhu <peter@peterzhu.ca>2022-09-26 14:54:32 -0400
commitaa2a428cfb3f4273f51358eb4e7fab235c7d36c2 (patch)
tree620e0c6ebd12428d2bee57c733e99c9bd82c1af4 /string.c
parent830b5b5c351c5c6efa5ad461ae4ec5085e5f0275 (diff)
downloadruby-aa2a428cfb3f4273f51358eb4e7fab235c7d36c2.tar.gz
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.
Diffstat (limited to 'string.c')
-rw-r--r--string.c58
1 files changed, 21 insertions, 37 deletions
diff --git a/string.c b/string.c
index 1e7b16fbba..b9c567cbe2 100644
--- a/string.c
+++ b/string.c
@@ -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);