[Backport #809] String#ord and String#[gs]etbyte for 1.8

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.
    • "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

e$B%A%1%C%He(B #809 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

e$BC4Ev<Te(B Akinori MUSHAe$B$K%;%C%He(B

e$B$"$j$,$H$&$4$6$$$^$9!#$3$l$i$be(BNEWSe$B5-:\O3$l$G$9$M!D!#e(B

String#getbyte/setbytee$B$O$3$N$^$^F~$l$h$&$H;W$$$^$9!#e(B

String#orde$B$Oe(BInteger#orde$B$N$H$-$K5$$E$/$Y$-$G$7$?!#e(B
e$B$3$A$i$Oe(Bmultibytee$BBP1~!Je(B$KCODE
awaree$B!K$G$“$k$Y$-$@$H;W$&$N$G!”$=$N$h$&$KD>$7$FF~$l$^$9!#e(B

http://redmine.ruby-lang.org/issues/show/809

e$B%A%1%C%He(B #809 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r20461.

http://redmine.ruby-lang.org/issues/show/809

e$B%A%1%C%He(B #809 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

getbyte/setbytee$B$O$[$$=$N$^$^F~$l$^$7$?!#e(B
orde$B$Oe(B$KCODEe$BBP1~$K$7$FF~$l$^$7$?!#e(B

http://redmine.ruby-lang.org/issues/show/809

e$BIMCO$G$9!#e(B

getbyte/setbytee$B$O$[$$=$N$^$^F~$l$^$7$?!#e(B
orde$B$Oe(B$KCODEe$BBP1~$K$7$FF~$l$^$7$?!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#e(B $KCODE e$B$H$+B8:_$rK:$l$5$C$F$$$^$7$?!De(B