Skip to content

Commit 94eb0df

Browse files
Watson1978claude
andcommitted
IO::Buffer: 数値の読み書きの 7 メソッドを追加
get_value / get_values / set_value / set_values / values / each / each_byte を 追加した。実機で確認した版差は #%since / #%until で出し分けている。 - get_value と set_value は 3.1 からあるが、他の 5 つは 3.2 から (#%since 3.2)。 - 128bit の型 (:u128 :U128 :s128 :S128) は 4.0 から (#%since 4.0)。 3.2〜3.4 では ArgumentError になる。 - set_value の返り値は 3.1 では指定した offset、3.2 以降は書き込んだ値の次の 位置。ruby/ruby#6434 (3.2.0) で変わったもので、rdoc の例が古いままだったため ruby/ruby#18078 で修正を出した。 - each_byte は 3.4 以前で引数が正しく扱われない。引数を1つ渡すと無視され、 2つ渡すと2番目が開始位置として使われる。4.0 で修正済みなので #%until 4.0 で 注記し、引数付きの例は #%since 4.0 に閉じ込めた。 記載した例はすべて 3.1 / 3.2 / 3.4 / 4.0 で実行して出力が一致することを確認した。 set_value の例は返り値を表示せず get_string / get_value で結果を見る形にして、 全版で同じ出力になるようにしている。 あわせて、readonly? の説明で平文にしていた IO::Buffer#set_value への参照を リンクに戻した (rurema#3305 で入れた #%# の覚え書きも削除)。 rake check_links でリンク切れが増えていないことを確認した。 3.1 : 262 -> 262 3.2 : 296 -> 296 4.0 : 297 -> 297 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent f792e03 commit 94eb0df

1 file changed

Lines changed: 219 additions & 2 deletions

File tree

manual/api/_builtin/IO__Buffer.md

Lines changed: 219 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,224 @@ IO::Buffer.new(2).set_string("TOOLONG") # ~> ArgumentError
318318

319319
- **SEE** [m:IO::Buffer#get_string]
320320

321+
### def get_value(buffer_type, offset) -> Integer | Float
322+
323+
バッファの offset の位置から、buffer_type で指定した型の値を読み出して返します。
324+
325+
buffer_type には以下のシンボルを指定します。
326+
小文字で始まるものはリトルエンディアン、大文字で始まるものはビッグエンディアンです
327+
(1 バイトの `:U8``:S8` にバイトオーダーの区別はありません)。
328+
329+
- **整数**: `:U8` `:S8` (1 バイト)、`:u16` `:U16` `:s16` `:S16` (2 バイト)、
330+
`:u32` `:U32` `:s32` `:S32` (4 バイト)、`:u64` `:U64` `:s64` `:S64` (8 バイト)
331+
#%since 4.0
332+
`:u128` `:U128` `:s128` `:S128` (16 バイト)
333+
#%end
334+
- **浮動小数点数**: `:f32` `:F32` (4 バイト)、`:f64` `:F64` (8 バイト)
335+
336+
小文字の `u` `s` `f` で始まるものが符号なし整数・符号付き整数・浮動小数点数を表し、
337+
`u``s` の対応する大文字はビッグエンディアンを意味します。
338+
339+
- **param** `buffer_type` -- 読み出す値の型を上記のシンボルで指定します。
340+
341+
- **param** `offset` -- 読み出す位置をバッファの先頭からのバイト数で指定します。
342+
343+
- **raise** `ArgumentError` -- buffer_type が上記以外の場合や、読み出す範囲が
344+
バッファの外にはみ出す場合に発生します。
345+
346+
```ruby
347+
buf = IO::Buffer.for([1.5].pack("f"))
348+
p buf.get_value(:f32, 0) # => 1.5
349+
350+
buf = IO::Buffer.for("\x01\x02")
351+
p buf.get_value(:u16, 0) # => 513
352+
p buf.get_value(:U16, 0) # => 258
353+
```
354+
355+
#%since 3.2
356+
- **SEE** [m:IO::Buffer#set_value], [m:IO::Buffer#get_values], [m:IO::Buffer#values]
357+
#%else
358+
- **SEE** [m:IO::Buffer#set_value]
359+
#%end
360+
361+
#%since 3.2
362+
### def get_values(buffer_types, offset) -> [Integer | Float]
363+
364+
[m:IO::Buffer#get_value] と同じですが、複数の型をまとめて読み出し、
365+
値の配列を返します。
366+
367+
- **param** `buffer_types` -- 読み出す値の型のシンボルの配列を指定します。
368+
指定できるシンボルは [m:IO::Buffer#get_value] を参照してください。
369+
370+
- **param** `offset` -- 読み出しを開始する位置をバッファの先頭からのバイト数で指定します。
371+
372+
- **raise** `ArgumentError` -- 型が不正な場合や、読み出す範囲がバッファの外に
373+
はみ出す場合に発生します。
374+
375+
```ruby
376+
buf = IO::Buffer.for([1.5, 2.5].pack("ff"))
377+
p buf.get_values([:f32, :f32], 0) # => [1.5, 2.5]
378+
```
379+
380+
- **SEE** [m:IO::Buffer#get_value], [m:IO::Buffer#set_values]
381+
#%end
382+
383+
### def set_value(buffer_type, offset, value) -> Integer
384+
385+
バッファの offset の位置に、buffer_type で指定した型で value を書き込みます。
386+
387+
指定できる型は [m:IO::Buffer#get_value] を参照してください。
388+
整数の型に [c:Float] を渡した場合は、小数点以下が切り捨てられます。
389+
390+
#%since 3.2
391+
書き込んだ値の次の位置を返します。
392+
#%else
393+
offset をそのまま返します。
394+
#%end
395+
396+
- **param** `buffer_type` -- 書き込む値の型をシンボルで指定します。
397+
398+
- **param** `offset` -- 書き込む位置をバッファの先頭からのバイト数で指定します。
399+
400+
- **param** `value` -- 書き込む値を数値で指定します。
401+
402+
- **raise** `ArgumentError` -- buffer_type が不正な場合や、書き込む範囲が
403+
バッファの外にはみ出す場合に発生します。
404+
405+
- **raise** `IO::Buffer::AccessError` -- 読み取り専用のバッファに対して
406+
呼び出した場合に発生します。
407+
408+
```ruby
409+
buf = IO::Buffer.new(8)
410+
buf.set_value(:U8, 1, 111)
411+
p buf.get_string # => "\x00o\x00\x00\x00\x00\x00\x00"
412+
413+
# 整数の型に Float を渡すと小数点以下は切り捨てられる
414+
buf = IO::Buffer.new(8)
415+
buf.set_value(:U32, 0, 2.5)
416+
p buf.get_value(:U32, 0) # => 2
417+
```
418+
419+
- **SEE** [m:IO::Buffer#get_value]
420+
421+
#%since 3.2
422+
### def set_values(buffer_types, offset, values) -> Integer
423+
424+
[m:IO::Buffer#set_value] と同じですが、複数の値をまとめて書き込みます。
425+
書き込んだ値の次の位置を返します。
426+
427+
- **param** `buffer_types` -- 書き込む値の型のシンボルの配列を指定します。
428+
429+
- **param** `offset` -- 書き込みを開始する位置をバッファの先頭からのバイト数で指定します。
430+
431+
- **param** `values` -- 書き込む値の配列を指定します。
432+
433+
- **raise** `ArgumentError` -- 型が不正な場合や、書き込む範囲がバッファの外に
434+
はみ出す場合に発生します。
435+
436+
- **raise** `IO::Buffer::AccessError` -- 読み取り専用のバッファに対して
437+
呼び出した場合に発生します。
438+
439+
```ruby
440+
buf = IO::Buffer.new(8)
441+
p buf.set_values([:U8, :U16], 0, [1, 2]) # => 3
442+
p buf.get_string(0, 3) # => "\x01\x00\x02"
443+
```
444+
445+
- **SEE** [m:IO::Buffer#set_value], [m:IO::Buffer#get_values]
446+
447+
### def values(buffer_type, offset = 0, count = nil) -> [Integer | Float]
448+
449+
バッファの offset の位置から、buffer_type で指定した型の値を順に読み出し、
450+
配列にして返します。
451+
452+
指定できる型は [m:IO::Buffer#get_value] を参照してください。
453+
454+
- **param** `buffer_type` -- 読み出す値の型をシンボルで指定します。
455+
456+
- **param** `offset` -- 読み出しを開始する位置をバッファの先頭からのバイト数で指定します。
457+
458+
- **param** `count` -- 読み出す個数を指定します。省略した場合はバッファの末尾まで
459+
読み出します。
460+
461+
```ruby
462+
buf = IO::Buffer.for("Hello World")
463+
p buf.values(:U8, 2, 2) # => [108, 108]
464+
p buf.values(:U8, 9) # => [108, 100]
465+
```
466+
467+
- **SEE** [m:IO::Buffer#each], [m:IO::Buffer#get_values]
468+
469+
### def each(buffer_type, offset = 0, count = nil) {|offset, value| ... } -> self
470+
### def each(buffer_type, offset = 0, count = nil) -> Enumerator
471+
472+
バッファの offset の位置から、buffer_type で指定した型の値を順に読み出し、
473+
その位置と値をブロックに渡して繰り返します。
474+
475+
指定できる型は [m:IO::Buffer#get_value] を参照してください。
476+
ブロックを省略した場合は [c:Enumerator] を返します。
477+
478+
- **param** `buffer_type` -- 読み出す値の型をシンボルで指定します。
479+
480+
- **param** `offset` -- 読み出しを開始する位置をバッファの先頭からのバイト数で指定します。
481+
482+
- **param** `count` -- 読み出す個数を指定します。省略した場合はバッファの末尾まで
483+
読み出します。
484+
485+
```ruby
486+
IO::Buffer.for("Hello World").each(:U8, 2, 2) do |offset, value|
487+
p [offset, value]
488+
end
489+
# => [2, 108]
490+
# [3, 108]
491+
```
492+
493+
- **SEE** [m:IO::Buffer#values], [m:IO::Buffer#each_byte]
494+
495+
### def each_byte(offset = 0, count = nil) {|byte| ... } -> self
496+
### def each_byte(offset = 0, count = nil) -> Enumerator
497+
498+
バッファの offset の位置から 1 バイトずつ読み出し、ブロックに渡して繰り返します。
499+
500+
ブロックを省略した場合は [c:Enumerator] を返します。
501+
502+
- **param** `offset` -- 読み出しを開始する位置をバッファの先頭からのバイト数で指定します。
503+
504+
- **param** `count` -- 読み出すバイト数を指定します。省略した場合はバッファの末尾まで
505+
読み出します。
506+
507+
#%until 4.0
508+
Ruby 3.4 以前では引数が正しく扱われません。引数を 1 つだけ渡した場合は無視されて
509+
先頭から末尾まで読み出し、2 つ渡した場合は 2 番目の引数が読み出しの開始位置として
510+
使われます。位置や個数を指定するには Ruby 4.0 以降が必要です。
511+
#%end
512+
513+
```ruby
514+
IO::Buffer.for("Hello").each_byte do |byte|
515+
p byte
516+
end
517+
# => 72
518+
# 101
519+
# 108
520+
# 108
521+
# 111
522+
```
523+
524+
#%since 4.0
525+
526+
```ruby title="例: 位置と個数を指定する"
527+
IO::Buffer.for("Hello World").each_byte(2, 2) do |byte|
528+
p byte
529+
end
530+
# => 108
531+
# 108
532+
```
533+
534+
#%end
535+
536+
- **SEE** [m:IO::Buffer#each]
537+
#%end
538+
321539
#%since 3.2
322540
### def slice(offset = 0, length = nil) -> IO::Buffer
323541
#%else
@@ -552,8 +770,7 @@ p IO::Buffer.new(4).external? # => false
552770

553771
バッファが読み取り専用の場合に true を返します。
554772

555-
#%# set_value を収録したらリンクに戻す
556-
読み取り専用のバッファは、`IO::Buffer#set_value`[m:IO::Buffer#set_string]
773+
読み取り専用のバッファは、[m:IO::Buffer#set_value][m:IO::Buffer#set_string]
557774
[m:IO::Buffer#copy] などで変更できません。
558775

559776
[m:IO::Buffer.for] にブロックを渡さずに作ったバッファは、元の文字列が freeze

0 commit comments

Comments
 (0)