Unverified Commit 014f9282 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #4524 from dearblue/reverse-utf8

Change to UTF-8 string reversing with in place
parents 84779f01 11e09dc5
...@@ -1674,6 +1674,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p) ...@@ -1674,6 +1674,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
return mrb_obj_value(p_str); return mrb_obj_value(p_str);
} }
static inline void
str_reverse(char *p, char *e)
{
char c;
while (p < e) {
c = *p;
*p++ = *e;
*e-- = c;
}
}
/* 15.2.10.5.30 */ /* 15.2.10.5.30 */
/* /*
* call-seq: * call-seq:
...@@ -1684,53 +1696,35 @@ mrb_ptr_to_str(mrb_state *mrb, void *p) ...@@ -1684,53 +1696,35 @@ mrb_ptr_to_str(mrb_state *mrb, void *p)
static mrb_value static mrb_value
mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
{ {
struct RString *s = mrb_str_ptr(str);
char *p, *e;
#ifdef MRB_UTF8_STRING #ifdef MRB_UTF8_STRING
mrb_int utf8_len = RSTRING_CHAR_LEN(str); mrb_int utf8_len = RSTRING_CHAR_LEN(str);
mrb_int len = RSTRING_LEN(str); mrb_int len = RSTR_LEN(s);
if (utf8_len == len) goto bytes;
if (utf8_len > 1) {
char *buf;
char *p, *e, *r;
mrb_str_modify(mrb, mrb_str_ptr(str));
len = RSTRING_LEN(str);
buf = (char*)mrb_malloc(mrb, (size_t)len);
p = buf;
e = buf + len;
memcpy(buf, RSTRING_PTR(str), len);
r = RSTRING_PTR(str) + len;
if (utf8_len < 2) return str;
if (utf8_len < len) {
mrb_str_modify(mrb, s);
p = RSTR_PTR(s);
e = p + RSTR_LEN(s);
while (p<e) { while (p<e) {
mrb_int clen = utf8len(p, e); mrb_int clen = utf8len(p, e);
r -= clen; str_reverse(p, p + clen - 1);
memcpy(r, p, clen);
p += clen; p += clen;
} }
mrb_free(mrb, buf); goto bytes;
} }
return str;
bytes:
#endif #endif
{
struct RString *s = mrb_str_ptr(str);
char *p, *e;
char c;
mrb_str_modify(mrb, s);
if (RSTR_LEN(s) > 1) { if (RSTR_LEN(s) > 1) {
mrb_str_modify(mrb, s);
bytes:
p = RSTR_PTR(s); p = RSTR_PTR(s);
e = p + RSTR_LEN(s) - 1; e = p + RSTR_LEN(s) - 1;
while (p < e) { str_reverse(p, e);
c = *p;
*p++ = *e;
*e-- = c;
}
} }
return str; return str;
}
} }
/* ---------------------------------- */ /* ---------------------------------- */
......
...@@ -479,6 +479,7 @@ assert('String#reverse(UTF-8)', '15.2.10.5.29') do ...@@ -479,6 +479,7 @@ assert('String#reverse(UTF-8)', '15.2.10.5.29') do
assert_equal 'こんにちは世界!', a assert_equal 'こんにちは世界!', a
assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse
assert_equal 'あ', 'あ'.reverse
end if UTF8STRING end if UTF8STRING
assert('String#reverse!', '15.2.10.5.30') do assert('String#reverse!', '15.2.10.5.30') do
...@@ -495,6 +496,10 @@ assert('String#reverse!(UTF-8)', '15.2.10.5.30') do ...@@ -495,6 +496,10 @@ assert('String#reverse!(UTF-8)', '15.2.10.5.30') do
assert_equal '!界世はちにんこ', a assert_equal '!界世はちにんこ', a
assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse! assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse!
b = 'あ'
b.reverse!
assert_equal 'あ', b
end if UTF8STRING end if UTF8STRING
assert('String#rindex', '15.2.10.5.31') do assert('String#rindex', '15.2.10.5.31') do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment