* string.c (rb_str_substr): perfomance improvement. [ruby-dev:31806]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13791 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b088414390
commit
2ae60f1634
@ -1,3 +1,7 @@
|
|||||||
|
Mon Oct 29 17:58:16 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* string.c (rb_str_substr): perfomance improvement. [ruby-dev:31806]
|
||||||
|
|
||||||
Mon Oct 29 17:20:13 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Mon Oct 29 17:20:13 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* encoding.c (rb_enc_replicate): new function to replicate encoding.
|
* encoding.c (rb_enc_replicate): new function to replicate encoding.
|
||||||
|
51
string.c
51
string.c
@ -787,27 +787,50 @@ rb_str_substr(VALUE str, long beg, long len)
|
|||||||
{
|
{
|
||||||
rb_encoding *enc = rb_enc_get(str);
|
rb_encoding *enc = rb_enc_get(str);
|
||||||
VALUE str2;
|
VALUE str2;
|
||||||
int slen = str_strlen(str, enc);
|
char *p, *s = RSTRING_PTR(str), *e = s + RSTRING_LEN(str);
|
||||||
|
|
||||||
if (len < 0) return Qnil;
|
if (len < 0) return Qnil;
|
||||||
if (beg > slen) return Qnil;
|
if (!RSTRING_LEN(str)) {
|
||||||
if (beg < 0) {
|
|
||||||
beg += slen;
|
|
||||||
if (beg < 0) return Qnil;
|
|
||||||
}
|
|
||||||
if (beg + len > slen) {
|
|
||||||
len = slen - beg;
|
|
||||||
}
|
|
||||||
if (len < 0) {
|
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
if (len == 0) {
|
if (beg < 0) {
|
||||||
str2 = rb_str_new5(str,0,0);
|
if (len > -beg) len = -beg;
|
||||||
|
if (-beg * rb_enc_mbmaxlen(enc) < RSTRING_LEN(str) / 8) {
|
||||||
|
beg = -beg;
|
||||||
|
while (len++ < beg && (e = rb_enc_prev_char(s, e, enc)) != 0);
|
||||||
|
p = e;
|
||||||
|
if (!p) return Qnil;
|
||||||
|
while (beg-- > 0 && (p = rb_enc_prev_char(s, p, enc)) != 0);
|
||||||
|
if (!p) return Qnil;
|
||||||
|
len = e - p;
|
||||||
|
goto sub;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *p = str_nth(RSTRING_PTR(str), RSTRING_END(str), beg, enc);
|
beg += str_strlen(str, enc);
|
||||||
str2 = rb_str_new5(str, p, str_offset(p, RSTRING_END(str), len, enc));
|
if (beg < 0) return Qnil;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (beg > 0 && beg > str_strlen(str, enc)) {
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
p = 0;
|
||||||
|
}
|
||||||
|
else if ((p = str_nth(s, e, beg, enc)) == e) {
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
else if (rb_enc_mbmaxlen(enc) == rb_enc_mbminlen(enc)) {
|
||||||
|
long rest = (e - p) / rb_enc_mbmaxlen(enc);
|
||||||
|
if (len > rest)
|
||||||
|
len = rest;
|
||||||
|
else
|
||||||
|
len *= rb_enc_mbmaxlen(enc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
len = str_offset(p, e, len, enc);
|
||||||
|
}
|
||||||
|
sub:
|
||||||
|
str2 = rb_str_new5(str, p, len);
|
||||||
rb_enc_copy(str2, str);
|
rb_enc_copy(str2, str);
|
||||||
OBJ_INFECT(str2, str);
|
OBJ_INFECT(str2, str);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user