diff options
author | Peter Zhu <[email protected]> | 2022-09-26 11:39:36 -0400 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2022-09-26 14:54:32 -0400 |
commit | aa2a428cfb3f4273f51358eb4e7fab235c7d36c2 (patch) | |
tree | 620e0c6ebd12428d2bee57c733e99c9bd82c1af4 /string.c | |
parent | 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275 (diff) |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6447
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 58 |
1 files changed, 21 insertions, 37 deletions
@@ -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); |