Backport #809: String#ord and String#[gs]etbyte for 1.8
http://redmine.ruby-lang.org/issues/show/809
e$B5/I<<Te(B: Shinichiro Hamaji
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
Ruby1.9 e$B$G%3!<%I$r=q$$$F$$$k;~$K!"e(B 1.8
e$B$G$bF0$/$h$&$K$7$H$/$+$J$!!De(B
e$B$H;W$&;~$K:G$b:$$k$N$,8D?ME*$K$Oe(B String#[]
e$B$N5sF0$NJQ2=$J$N$G$9$,!"e(B
1.9 e$B$Ne(B ord, getbyte, setbyte e$B$re(B backport
e$B$7$F$*$/$o$1$K$O$$$1$J$$$b$s$G$7$g$&$+!#e(B
Index: string.c
— string.c (revision 20448)
+++ string.c (working copy)
@@ -2473,6 +2473,51 @@
/*
- call-seq:
-
-
str.getbyte(index) => 0 .. 255
-
-
-
- returns the indexth byte as an integer.
- */
+static VALUE
+rb_str_getbyte(VALUE str, VALUE index)
+{ - long pos = NUM2LONG(index);
- if (pos < 0)
- pos += RSTRING_LEN(str);
- if (pos < 0 || RSTRING_LEN(str) <= pos)
- return Qnil;
- return INT2FIX((unsigned char)RSTRING_PTR(str)[pos]);
+}
+/*
-
- call-seq:
-
-
str.setbyte(index, int) => int
-
-
-
- modifies the indexth byte as int.
- */
+static VALUE
+rb_str_setbyte(VALUE str, VALUE index, VALUE value)
+{ - long pos = NUM2LONG(index);
- int byte = NUM2INT(value);
- rb_str_modify(str);
- if (pos < -RSTRING_LEN(str) || RSTRING_LEN(str) <= pos)
- rb_raise(rb_eIndexError, “index %ld out of string”, pos);
- if (pos < 0)
- pos += RSTRING_LEN(str);
- RSTRING_PTR(str)[pos] = byte;
- return value;
+}
+/*
-
- call-seq:
-
str.reverse => new_str
- Returns a new string with the characters from str in reverse
order.
@@ -4556,6 +4601,24 @@
/*
- call-seq:
-
-
str.ord => integer
-
-
-
- Return the
Integer
ordinal of a one-character string.
- Return the
-
-
-
"a".ord #=> 97
-
- */
+VALUE
+rb_str_ord(VALUE s)
+{
- if (RSTRING_LEN(s) <= 0)
- rb_raise(rb_eArgError, “empty string”);
- return INT2FIX(*RSTRING_PTR(s) & 0xff);
+}
+/*
-
- call-seq:
-
str.sum(n=16) => integer
- Returns a basic n-bit checksum of the characters in
str,
@@ -4959,6 +5022,8 @@
rb_define_method(rb_cString, “index”, rb_str_index_m, -1);
rb_define_method(rb_cString, “rindex”, rb_str_rindex_m, -1);
rb_define_method(rb_cString, “replace”, rb_str_replace, 1);
-
rb_define_method(rb_cString, “getbyte”, rb_str_getbyte, 1);
-
rb_define_method(rb_cString, “setbyte”, rb_str_setbyte, 2);
rb_define_method(rb_cString, “to_i”, rb_str_to_i, -1);
rb_define_method(rb_cString, “to_f”, rb_str_to_f, 0);
@@ -4987,6 +5052,7 @@
rb_define_method(rb_cString, “crypt”, rb_str_crypt, 1);
rb_define_method(rb_cString, “intern”, rb_str_intern, 0);
rb_define_method(rb_cString, “to_sym”, rb_str_intern, 0); -
rb_define_method(rb_cString, “ord”, rb_str_ord, 0);
rb_define_method(rb_cString, “include?”, rb_str_include, 1);
rb_define_method(rb_cString, “start_with?”, rb_str_start_with, -1);
Index: test/ruby/test_string.rb
===================================================================
— test/ruby/test_string.rb (revision 20448)
+++ test/ruby/test_string.rb (working copy)
@@ -77,4 +77,28 @@
assert_equal(“aaaaaaaaaaaa”, “zzzzzzzzzzz”.succ!)
assert_equal(“aaaaaaaaaaaaaaaaaaaaaaaa”,
“zzzzzzzzzzzzzzzzzzzzzzz”.succ!)
end -
def test_getbyte
-
assert_equal(0x82, “\xE3\x81\x82\xE3\x81\x84”.getbyte(2))
-
assert_equal(0x82, “\xE3\x81\x82\xE3\x81\x84”.getbyte(-4))
-
assert_nil("\xE3\x81\x82\xE3\x81\x84".getbyte(100))
-
end
-
def test_setbyte
-
s = “\xE3\x81\x82\xE3\x81\x84”
-
s.setbyte(2, 0x84)
-
assert_equal("\xE3\x81\x84\xE3\x81\x84", s)
-
s = “\xE3\x81\x82\xE3\x81\x84”
-
assert_raise(IndexError) { s.setbyte(100, 0) }
-
s = “\xE3\x81\x82\xE3\x81\x84”
-
s.setbyte(-4, 0x84)
-
assert_equal("\xE3\x81\x84\xE3\x81\x84", s)
-
end
-
def test_ord
-
assert_equal(0xe3, “\xE3\x81\x82\xE3\x81\x84”.ord)
-
assert_raise(ArgumentError) { “”.ord }
-
end
end