[#32910] NKF,Kconv — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
[#32913] openの"b"とencoding — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
[#32922] SEGV by regexp match in while loop — Tanaka Akira <akr@...>
Debian GNU/Linux (sarge) の gcc-3.4 を使ってビルドした ruby
[#32935] queue and timeout — Tanaka Akira <akr@...>
timeout で Queue#pop に時間制限をつけた時、タイムアウト時に
まつもと ゆきひろです
[#32940] ripper cannot build on win32 — yukimi_sake <yukimi_sake@...>
雪見酒です。
[#32945] Shift_JIS variants and UTF-16 support — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
中村さん、こんにちは。
まつもと ゆきひろです
成瀬です。
まつもと ゆきひろです
こんにちは、なかむら(う)です。
成瀬です。
こんにちは、なかむら(う)です。
成瀬です。
こんにちは、なかむら(う)です。
まつもと ゆきひろです
[#32946] replica と alias の違い(encoding) — KIMURA Koichi <kimura.koichi@...>
木村です。
[#32987] error with open-uri (instance_eval?) — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
[#32988] Re: [ruby-cvs:22194] Ruby:r14957 (trunk): * encoding.c (rb_enc_init): UTF-{16,32}{BE,LE} are not builtin. — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
[#32992] ASCII is alias of US-ASCII; replica of dummy encoding is not a dummy — "NARUSE, Yui" <naruse@...>
成瀬です。
まつもと ゆきひろです
At 18:13 08/01/09, Yukihiro Matsumoto wrote:
成瀬です。
まつもと ゆきひろです
成瀬です。
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
[#32996] binmode and ASCII-8BIT — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
[#33069] Re: [ruby-cvs:22244] Ruby:r15007 (trunk): * enc/make_encdb.rb: added. search enc/*.c and make encoding database. — Yukihiro Matsumoto <matz@...>
まつもと ゆきひろです
まつもと ゆきひろです
[#33076] Encoding.compatible? and dummy encodings — sheepman <sheepman@...>
こんにちは sheepman です。
成瀬です。
まつもと ゆきひろです
[#33078] NEW REPLICA ENCODINGS AND ENCODING ALIASES — "NARUSE, Yui" <naruse@...>
成瀬です。
[#33101] String#valid_encoding? shoud be strict? — Masayoshi Takahashi <maki@...>
高橋征義です。1.9のエンコーディングとString#valid_encoding?について。
[#33139] Bignum#* might invoke GC parallelly? — "Yusuke ENDOH" <mame@...>
遠藤と申します。
[#33156] default script encoding and -K option — sheepman <sheepman@...>
こんばんは sheepman です。
こんにちは、なかむら(う)です。
まつもと ゆきひろです
[#33164] default encoding for Marshal.load — "Shugo Maeda" <shugo@...>
前田です。
まつもと ゆきひろです
[#33185] コンパイルの問題 (r15218) — Martin Duerst <duerst@...>
r15128 当たりで (実はもう少し前から) コンパイルできなくなりました。
[#33218] Re: Ruby1.9String バイト列へのインデックス アクセス — "Hisanori Kiryu" <hkiryu@...>
> ちなみに、byte のではなく bytes の方が妥当だと思います。
[#33224] printf "%0x" — Tanaka Akira <akr@...>
printf の %0x に負の整数を与えると、値によって .. がついたり
[#33226] [PATCH] warnings of enc/trans/utf_16_32.c — Nobuyoshi Nakada <nobu@...>
なかだです。
[#33239] Re: [ruby-cvs:22386] Ruby:r15149 (trunk): * string.c (rb_str_each_char): move forward. — Tanaka Akira <akr@...>
In article <200801210259.m0L2x3CW017171@ci.ruby-lang.org>,
なかだです。
In article <20080121065650.55F60E0662@mail.bc9.jp>,
なかだです。
まつもと ゆきひろです
[#33247] requests to transcode — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
[#33303] Time#strftimeのエンコーディング — rubikitch@...
るびきちです。
まつもと ゆきひろです
なかだです。
西山和広です。
[#33368] summary of script encoding — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
まつもと ゆきひろです
こんにちは、なかむら(う)です。
まつもと ゆきひろです
永井@知能.九工大です.
[#33387] HashからStructを作る — rubikitch@...
るびきちです。
まつもと ゆきひろです
From: Yukihiro Matsumoto <matz@ruby-lang.org>
まつもと ゆきひろです
From: Yukihiro Matsumoto <matz@ruby-lang.org>
まつもと ゆきひろです
From: Yukihiro Matsumoto <matz@ruby-lang.org>
まつもと ゆきひろです
[#33399] regexp match /.../n against to UTF-8 string — Tanaka Akira <akr@...>
以下のように、つけてもいない正規表現の n オプションに関して
[#33400] /#{}/e.encoding — Tanaka Akira <akr@...>
以下のように /#{}/e の encoding が US-ASCII になります。
[#33403] wrapped String#gsub — "Park Ji-In" <tisphie@...>
こんにちは、朴 芝印です。
[#33417] コンパイルの問題 — Martin Duerst <duerst@...>
現在 (r15264 で) コンパイル使用とすると、エラーになります:
At 16:28 08/01/27, you wrote:
[#33433] Win32OLE: set encoding to OLE string — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
成瀬です。
助田です。
こんにちは、なかむら(う)です。
こんにちは、なかむら(う)です。
[#33452] enc/euc_kr.c (euckr_mbc_enc_len) euc_kr.c is also used by CP942 — "NARUSE, Yui" <naruse@...>
成瀬です。
まつもと ゆきひろです
成瀬です。
[#33461] Failed to make ruby-1.8.6-p111 on MacOSX 10.5(Leopard) — MORITA Hideyuki <h-morita@...>
=1B$B?9ED$H?=3D$7$^$9!#=1B(B
なかだです。
森田です。
なかだです。
森田です。
天野竜太郎と申します。
森田です。
天野です。
森田です。
天野です。
森田です。
天野です。
森田です。
天野です。
[#33488] 現在の script encoding の値を得る方法は? — Hidetoshi NAGAI <nagai@...>
永井@知能.九工大です.
まつもと ゆきひろです
永井@知能.九工大です.
成瀬です。
永井@知能.九工大です.
成瀬です。
永井@知能.九工大です.
成瀬です。
In article <47A00E86.4010701@airemix.com>,
成瀬です。
In article <47A03C9D.2090008@airemix.com>,
In article <87hcgvu1ng.fsf@fsij.org>,
[#33521] nkf の CP932 — Martin Duerst <duerst@...>
成瀬さん、皆さん、こんにちは。
[#33548] block parameter of String#gsub — "NARUSE, Yui" <naruse@...>
成瀬です。
まつもと ゆきひろです
[ruby-dev:33443] Re: Ruby1.9 String バイト列へのインデックス アクセス
なかだです。
At Sun, 20 Jan 2008 03:58:32 +0900,
Yukihiro Matsumoto wrote in [ruby-dev:33196]:
> |s = "abcde"
> |s.byte(3) # => 100
> |s.byte(3, 101)
> |s # => "abcee"
>
> 難点は「s.byte(3,101)」がいまいち「代入感」がないところでしょ
> うか。文法を拡張して「s.byte(3)=101」を許すようにするかな。
これはだいぶ前から考えているんですが、かなり難しいというか面倒そ
うです。
> |あるいはBytesクラスを用意してString#byteで作成できるといいかもしれません。
>
> この場合はBytesクラスはメモリ領域をStringと共有するのでしょ
> うか。それはそれで面白いと思いますが。
>
> |s = "abcde"
> |s.byte # "abcde"のバイト列オブジェクト
> |s.byte[3] # => 100
> |s.byte[3] = 101 # 破壊的更新
> |s # => "abcee"
> |
> |インデックスにはRangeも指定できるといいです。
>
> その場合は右辺に文字列(またはBytes)を指定するわけ?
>
> そういえば、自分で言い出しといてなんだけど複数形な名前のクラ
> スってのはいかがなものか。
String::ByteIndexerとか。
Index: string.c
===================================================================
--- string.c (revision 15284)
+++ string.c (working copy)
@@ -2405,27 +2405,33 @@ rb_str_aref_m(int argc, VALUE *argv, VAL
static void
-rb_str_splice_0(VALUE str, long beg, long len, VALUE val)
+rb_str_splice_ptr(VALUE str, long beg, long len, const char *vptr, long vlen)
{
rb_str_modify(str);
- if (len < RSTRING_LEN(val)) {
+ if (len < vlen) {
/* expand string */
- RESIZE_CAPA(str, RSTRING_LEN(str) + RSTRING_LEN(val) - len + 1);
+ RESIZE_CAPA(str, RSTRING_LEN(str) + vlen - len + 1);
}
- if (RSTRING_LEN(val) != len) {
- memmove(RSTRING_PTR(str) + beg + RSTRING_LEN(val),
+ if (vlen != len) {
+ memmove(RSTRING_PTR(str) + beg + vlen,
RSTRING_PTR(str) + beg + len,
RSTRING_LEN(str) - (beg + len));
}
- if (RSTRING_LEN(val) < beg && len < 0) {
+ if (vlen < beg && len < 0) {
MEMZERO(RSTRING_PTR(str) + RSTRING_LEN(str), char, -len);
}
- if (RSTRING_LEN(val) > 0) {
- memmove(RSTRING_PTR(str)+beg, RSTRING_PTR(val), RSTRING_LEN(val));
+ if (vlen > 0) {
+ memmove(RSTRING_PTR(str)+beg, vptr, vlen);
}
- STR_SET_LEN(str, RSTRING_LEN(str) + RSTRING_LEN(val) - len);
+ STR_SET_LEN(str, RSTRING_LEN(str) + vlen - len);
if (RSTRING_PTR(str)) {
RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0';
}
+}
+
+static void
+rb_str_splice_0(VALUE str, long beg, long len, VALUE val)
+{
+ rb_str_splice_ptr(str, beg, len, RSTRING_PTR(val), RSTRING_LEN(val));
OBJ_INFECT(str, val);
}
@@ -4666,16 +4672,195 @@ rb_str_each_line(int argc, VALUE *argv,
+static VALUE rb_str_each_byte(VALUE str);
+
+static VALUE rb_cByteIndexer;
+
+struct byte_indexer {
+ VALUE str;
+ long offset, length;
+};
+
+static void
+bidx_mark(void *ptr)
+{
+ struct byte_indexer *bp = ptr;
+ rb_gc_mark(bp->str);
+}
+
+static struct byte_indexer *
+bidx_ptr(VALUE self)
+{
+ struct byte_indexer *ptr;
+
+ Data_Get_Struct(self, struct byte_indexer, ptr);
+ if (RDATA(self)->dmark != bidx_mark) {
+ rb_raise(rb_eArgError, "ByteIndexer expected");
+ }
+ return ptr;
+}
+
+static VALUE
+rb_byte_indexer(VALUE str, long offset, long length)
+{
+ struct byte_indexer *ptr;
+ VALUE indexer = Data_Make_Struct(rb_cByteIndexer, struct byte_indexer,
+ bidx_mark, -1, ptr);
+
+ ptr->str = str;
+ ptr->offset = offset;
+ ptr->length = length;
+ return indexer;
+}
+
+static VALUE
+bidx_aref(int argc, VALUE *argv, VALUE self)
+{
+ struct byte_indexer *ptr = bidx_ptr(self);
+ VALUE str = ptr->str;
+ long beg, len, offset = ptr->offset, length = ptr->length;
+
+ if (length < 0) {
+ length += RSTRING_LEN(str) + 1;
+ }
+ if (offset + length > RSTRING_LEN(str)) {
+ length = RSTRING_LEN(str) - offset;
+ }
+ if (argc == 2) {
+ beg = NUM2LONG(argv[0]) + offset;
+ len = NUM2LONG(argv[1]);
+ range:
+ if (len < 0) return Qnil;
+ if (!length) {
+ len = 0;
+ }
+ if (beg < 0) {
+ if (len > -beg) len = -beg;
+ beg += length;
+ if (beg < 0) return Qnil;
+ }
+ else if (beg > length) {
+ return Qnil;
+ }
+ return rb_byte_indexer(str, beg, len);
+ }
+ else if (argc != 1) {
+ rb_raise(rb_eArgError, "wrong number arguments (%d for 1)", argc);
+ }
+ if (!FIXNUM_P(argv[0])) {
+ switch (rb_range_beg_len(argv[0], &beg, &len, length, 0)) {
+ case Qfalse:
+ break;
+ case Qnil:
+ return Qnil;
+ default:
+ goto range;
+ }
+ }
+ beg = FIX2INT(argv[0]);
+ if (beg >= length) return Qnil;
+ return INT2FIX(RSTRING_PTR(str)[beg + offset]);
+}
+
+static VALUE
+byte_array(VALUE ary)
+{
+ long i;
+ VALUE str = rb_str_tmp_new(RARRAY_LEN(ary));
+
+ for (i = 0; i < RARRAY_LEN(ary); ++i) {
+ VALUE n = RARRAY_PTR(ary)[i];
+ RSTRING_PTR(str)[i] = NUM2CHR(n);
+ }
+ return str;
+}
+
+static VALUE
+bidx_aset(int argc, VALUE *argv, VALUE self)
+{
+ struct byte_indexer *ptr = bidx_ptr(self);
+ VALUE str = ptr->str, val, ary;
+ long beg, len, slen;
+
+ rb_str_modify(str);
+ slen = RSTRING_LEN(str);
+ switch (argc) {
+ case 3:
+ beg = NUM2LONG(argv[0]);
+ len = NUM2LONG(argv[1]);
+ if (len < 0) rb_raise(rb_eIndexError, "negative length %ld", len);
+ if (beg < 0 ? (beg += slen) < 0 : beg > slen) {
+ rb_raise(rb_eIndexError, "index %ld out of string", beg);
+ }
+ val = argv[2];
+ break;
+ case 2:
+ if (!rb_range_beg_len(argv[0], &beg, &len, slen, 0)) {
+ beg = NUM2LONG(argv[0]);
+ len = 1;
+ }
+ val = argv[1];
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
+ }
+ if (!NIL_P(ary = rb_check_array_type(val))) {
+ rb_str_splice_0(str, beg, len, byte_array(ary));
+ }
+ else {
+ char byte = NUM2CHR(val);
+ rb_str_splice_ptr(str, beg, len, &byte, 1);
+ }
+ return argv[argc - 1];
+}
+
+static VALUE
+bidx_each(VALUE self)
+{
+ struct byte_indexer *ptr = bidx_ptr(self);
+ VALUE str = ptr->str;
+ long i, l;
+
+ if (!rb_block_given_p()) return self;
+ for (l = (i=ptr->offset) + ptr->length; i<l && i<RSTRING_LEN(str); i++) {
+ rb_yield(INT2FIX(RSTRING_PTR(str)[i] & 0xff));
+ }
+ return str;
+}
+
+static void
+Init_ByteIndexer(void)
+{
+ rb_cByteIndexer = rb_define_class_under(rb_cString, "ByteIndexer", rb_cData);
+ rb_include_module(rb_cByteIndexer, rb_mEnumerable);
+ rb_undef_alloc_func(rb_cByteIndexer);
+ rb_define_method(rb_cByteIndexer, "[]", bidx_aref, -1);
+ rb_define_method(rb_cByteIndexer, "[]=", bidx_aset, -1);
+ rb_define_method(rb_cByteIndexer, "each", bidx_each, 0);
+}
+
+
/*
* Document-method: bytes
* call-seq:
- * str.bytes => anEnumerator
+ * str.bytes => anIndexer
* str.bytes {|fixnum| block } => str
- *
+ *
* Returns an enumerator that gives each byte in the string. If a block is
* given, it iterates over each byte in the string.
- *
+ *
* "hello".bytes.to_a #=> [104, 101, 108, 108, 111]
+ *
+ * str = "hello"
+ * str.bytes[0] ^= 0x20
+ * str #=> "Hello"
*/
+static VALUE
+rb_str_bytes(VALUE str)
+{
+ if (!rb_block_given_p()) return rb_byte_indexer(str, 0, -1);
+ return rb_str_each_byte(str);
+}
+
/*
* Document-method: each_byte
@@ -6077,5 +6262,5 @@ Init_String(void)
rb_define_method(rb_cString, "split", rb_str_split_m, -1);
rb_define_method(rb_cString, "lines", rb_str_each_line, -1);
- rb_define_method(rb_cString, "bytes", rb_str_each_byte, 0);
+ rb_define_method(rb_cString, "bytes", rb_str_bytes, 0);
rb_define_method(rb_cString, "chars", rb_str_each_char, 0);
rb_define_method(rb_cString, "reverse", rb_str_reverse, 0);
@@ -6183,3 +6368,5 @@ Init_String(void)
rb_define_method(rb_cSymbol, "encoding", sym_encoding, 0);
+
+ Init_ByteIndexer();
}
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦