Skip to content
instance method

IO::Buffer#copy

(::IO::Buffer source, ?::Integer offset, ?::Integer length, ?::Integer source_offset) -> ::Integer
copy(source, [offset, [length, [source_offset]]]) → size

Efficiently copy from a source IO::Buffer into the buffer, at offset using memmove. For copying String instances, see set_string.

Example
buffer = IO::Buffer.new(32)
# =>
# #<IO::Buffer 0x0000555f5ca22520+32 INTERNAL>
# 0x00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
# 0x00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  *

buffer.copy(IO::Buffer.for("test"), 8)
# => 4 -- size of buffer copied
buffer
# =>
# #<IO::Buffer 0x0000555f5cf8fe40+32 INTERNAL>
# 0x00000000  00 00 00 00 00 00 00 00 74 65 73 74 00 00 00 00 ........test....
# 0x00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ *

copy can be used to put buffer into strings associated with buffer:

Example
string = "data:    "
# => "data:    "
buffer = IO::Buffer.for(string) do |buffer|
  buffer.copy(IO::Buffer.for("test"), 5)
end
# => 4
string
# => "data:test"

Attempt to copy into a read-only buffer will fail:

Example
File.write('test.txt', 'test')
buffer = IO::Buffer.map(File.open('test.txt'), nil, 0, IO::Buffer::READONLY)
buffer.copy(IO::Buffer.for("test"), 8)
# in `copy': Buffer is not writable! (IO::Buffer::AccessError)

See ::map for details of creation of mutable file mappings, this will work:

Example
buffer = IO::Buffer.map(File.open('test.txt', 'r+'))
buffer.copy(IO::Buffer.for("boom"), 0)
# => 4
File.read('test.txt')
# => "boom"

Attempt to copy the buffer which will need place outside of buffer’s bounds will fail:

Example
buffer = IO::Buffer.new(2)
buffer.copy(IO::Buffer.for('test'), 0)
# in `copy': Specified offset+length is bigger than the buffer size! (ArgumentError)

It is safe to copy between memory regions that overlaps each other. In such case, the data is copied as if the data was first copied from the source buffer to a temporary buffer, and then copied from the temporary buffer to the destination buffer.

Example
buffer = IO::Buffer.new(10)
buffer.set_string("0123456789")
buffer.copy(buffer, 3, 7)
# => 7
buffer
# =>
# #<IO::Buffer 0x000056494f8ce440+10 INTERNAL>
# 0x00000000  30 31 32 30 31 32 33 34 35 36                   0120123456

Ruby version changes

  1. 3.4
See also #clear #each #and! #each_byte also in 4.1 · 3.4 · 3.3 · 3.2 · 3.1