From 7c6d6effaea6ec3cbac01cffc4f094744d53d8b9 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 16:30:36 +0900 Subject: Replacement to function for string reversing --- src/string.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index bfe73b359..282f8d776 100644 --- a/src/string.c +++ b/src/string.c @@ -1671,6 +1671,18 @@ mrb_ptr_to_str(mrb_state *mrb, void *p) 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 */ /* * call-seq: @@ -1714,17 +1726,12 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) { struct RString *s = mrb_str_ptr(str); char *p, *e; - char c; mrb_str_modify(mrb, s); if (RSTR_LEN(s) > 1) { p = RSTR_PTR(s); e = p + RSTR_LEN(s) - 1; - while (p < e) { - c = *p; - *p++ = *e; - *e-- = c; - } + str_reverse(p, e); } return str; } -- cgit v1.2.3 From bd2c93c2dfbb944f57b10b7b9c056caf852a5053 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 16:32:17 +0900 Subject: Change to UTF-8 string reversing with in place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverses UTF-8 strings without allocated heap for working memory. 1. String before reversing: ``` "!yburmの界世" # byte unit [33, 121, 98, 117, 114, 109, 227, 129, 174, 231, 149, 140, 228, 184, 150] ``` 2. Reverse the byte order of each character: ``` [33, 121, 98, 117, 114, 109, 174, 129, 227, 140, 149, 231, 150, 184, 228] ``` 3. Reverse the whole byte order and complete: ``` [228, 184, 150, 231, 149, 140, 227, 129, 174, 109, 114, 117, 98, 121, 33] # string "世界のmruby!" ``` --- src/string.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 282f8d776..6d01b773c 100644 --- a/src/string.c +++ b/src/string.c @@ -1693,40 +1693,28 @@ str_reverse(char *p, char *e) static mrb_value mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) { + struct RString *s = mrb_str_ptr(str); + char *p, *e; + #ifdef MRB_UTF8_STRING 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; - + mrb_str_modify(mrb, s); + p = RSTR_PTR(s); + e = p + RSTR_LEN(s); while (p 1) { p = RSTR_PTR(s); -- cgit v1.2.3 From 567075aab939dd262e816832195cb11594abade9 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 22:58:18 +0900 Subject: Fix string brakes for one UTF-8 charactor --- src/string.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 6d01b773c..a35262eb4 100644 --- a/src/string.c +++ b/src/string.c @@ -1700,8 +1700,8 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) mrb_int utf8_len = RSTRING_CHAR_LEN(str); mrb_int len = RSTR_LEN(s); - if (utf8_len == len) goto bytes; - if (utf8_len > 1) { + if (utf8_len < 2) return str; + if (utf8_len < len) { mrb_str_modify(mrb, s); p = RSTR_PTR(s); e = p + RSTR_LEN(s); @@ -1711,8 +1711,6 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) p += clen; } } - - bytes: #endif { mrb_str_modify(mrb, s); -- cgit v1.2.3 From ec03e3f54af55af8c461a19b2f7cf0a984282997 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 23:02:29 +0900 Subject: Delete the unnecessary block brace in `mrb_str_reverse_bang` --- src/string.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index a35262eb4..2cfdc337e 100644 --- a/src/string.c +++ b/src/string.c @@ -1712,15 +1712,14 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) } } #endif - { - mrb_str_modify(mrb, s); - if (RSTR_LEN(s) > 1) { - p = RSTR_PTR(s); - e = p + RSTR_LEN(s) - 1; - str_reverse(p, e); - } - return str; + + mrb_str_modify(mrb, s); + if (RSTR_LEN(s) > 1) { + p = RSTR_PTR(s); + e = p + RSTR_LEN(s) - 1; + str_reverse(p, e); } + return str; } /* ---------------------------------- */ -- cgit v1.2.3 From 11e09dc5dbd6ddaabf145bbee62741f4191eca79 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 23:09:36 +0900 Subject: Fix the unnecessary `mrb_str_modify()` call Now to be calls `mrb_str_modify()` only once when 2 or more characters. --- src/string.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/string.c') diff --git a/src/string.c b/src/string.c index 2cfdc337e..2d9d176d4 100644 --- a/src/string.c +++ b/src/string.c @@ -1710,11 +1710,13 @@ mrb_str_reverse_bang(mrb_state *mrb, mrb_value str) str_reverse(p, p + clen - 1); p += clen; } + goto bytes; } #endif - mrb_str_modify(mrb, s); if (RSTR_LEN(s) > 1) { + mrb_str_modify(mrb, s); + bytes: p = RSTR_PTR(s); e = p + RSTR_LEN(s) - 1; str_reverse(p, e); -- cgit v1.2.3