summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-string-utf8/src/string.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-01-07 15:32:48 -0800
committerYukihiro "Matz" Matsumoto <[email protected]>2014-01-07 15:32:48 -0800
commitee8875b1d583c23d521edf4234daff4a83f9ec2f (patch)
treedc02c90112f5a11a7856eccfde884a3738074932 /mrbgems/mruby-string-utf8/src/string.c
parentb147970bd2e76888a6711fbc2f7de42ca92d55a0 (diff)
parent7fc9264b0fd124559c3095dbdc515f31a0b35f55 (diff)
downloadmruby-ee8875b1d583c23d521edf4234daff4a83f9ec2f.tar.gz
mruby-ee8875b1d583c23d521edf4234daff4a83f9ec2f.zip
Merge pull request #1651 from h2so5/string-reverse-utf8
add String#reverse, String#reverse! for UTF-8
Diffstat (limited to 'mrbgems/mruby-string-utf8/src/string.c')
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c
index 5379dd3aa..c377726a2 100644
--- a/mrbgems/mruby-string-utf8/src/string.c
+++ b/mrbgems/mruby-string-utf8/src/string.c
@@ -247,6 +247,38 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str)
return mrb_str_aref(mrb, str, a1);
}
+static mrb_value
+mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
+{
+ int utf8_len = mrb_utf8_strlen(str);
+ if (utf8_len > 1) {
+ int len = RSTRING_LEN(str);
+ char *buf = (char *)mrb_malloc(mrb, len);
+ unsigned char* p = (unsigned char*)buf;
+ unsigned char* e = (unsigned char*)buf + len;
+ unsigned char* r = (unsigned char*)RSTRING_END(str);
+
+ memcpy(buf, RSTRING_PTR(str), len);
+ mrb_str_modify(mrb, mrb_str_ptr(str));
+
+ while (p<e) {
+ int clen = utf8len(p);
+ r -= clen;
+ memcpy(r, p, clen);
+ p += clen;
+ }
+ mrb_free(mrb, buf);
+ }
+
+ return str;
+}
+
+static mrb_value
+mrb_str_reverse(mrb_state *mrb, mrb_value str)
+{
+ return mrb_str_reverse_bang(mrb, mrb_str_dup(mrb, str));
+}
+
void
mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
{
@@ -255,6 +287,8 @@ mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "size", mrb_str_size, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "[]", mrb_str_aref_m, MRB_ARGS_ANY());
mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY());
+ mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE());
+ mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE());
}
void