Class: IO::Buffer::Slice
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
::IO::Buffer
|
|
|
Instance Chain:
self,
::IO::Buffer,
::Comparable
|
|
| Inherits: |
IO::Buffer
|
| Defined in: | io_buffer.c |
Overview
A zero-copy, parent-relative view of an ::IO::Buffer or another Slice.
Create a view with #slice or .new:
buffer = IO::Buffer.new(6)
buffer.set_string("abcdef")
parent = buffer.slice(1, 4)
child = parent.slice(1, 2)
child.source.equal?(parent) # => true
child.get_string # => "cd"
parent.advance(1)
child.get_string # => "de"
A slice retains its immediate source and follows that source's current view. Its range is valid only while every parent is valid and the range fits within its source. Moving the backing allocation does not itself invalidate a slice. Shrinking a parent can invalidate descendants; growing it again can restore their validity.
Slice inherits Buffer's byte-access interface but does not manage storage.
Resizing a slice only changes its extent within its parent's bounds, and
advancing it consumes bytes from the front of its view. Neither operation
allocates or releases storage. Slice has no free or transfer method,
nor Storage's predicates such as mapped? or internal?.
Writes modify the source's bytes and respect its current permissions. Locking a slice protects the backing allocation; #locked? reports that shared lock state. Locked or read-only views may still be resized or advanced, but frozen views cannot change their range. Locking does not serialize access to bytes or view metadata.
Duplicating or cloning a Slice copies its view rather than its bytes.
Both Slice and Storage are subclasses of ::IO::Buffer.
Constant Summary
::IO::Buffer - Inherited
BIG_ENDIAN, DEFAULT_SIZE, EXTERNAL, HOST_ENDIAN, INTERNAL, LITTLE_ENDIAN, MAPPED, MAP_ALIGNMENT, NETWORK_ENDIAN, PAGE_SIZE, PRIVATE, READONLY, SHARED, VERSION
Class Method Summary
-
.new(source, [offset, [length]]) ⇒ Slice
constructor
Creates a parent-relative view of a
::IO::Bufferor anotherSlice.
::IO::Buffer - Inherited
| .for | Creates a zero-copy |
| .map | Create an |
| .new | Creates an |
| .size_of | Returns the size of the given buffer type(s) in bytes. |
| .string | Creates a new string of the given length and yields a zero-copy |
Instance Attribute Summary
::IO::Buffer - Inherited
Instance Method Summary
-
#dup ⇒ Slice
Copies the view, retaining the same source, offset, and size without copying the underlying bytes.
-
#resize(new_size) ⇒ self
Alias for Storage#resize.
::IO::Buffer - Inherited
| #& | Generate a new buffer the same size as the source by applying the binary AND operation to the source, using the mask, repeating as necessary. |
| #<=> | Returns a negative integer, zero, or a positive integer if the receiver is less than, equal to, or greater than |
| #^ | Generate a new buffer the same size as the source by applying the binary XOR operation to the source, using the mask, repeating as necessary. |
| #advance | Advances the beginning of a non-owning buffer view by |
| #and! | Modify the source buffer in place by applying the binary AND operation to the source, using the mask, repeating as necessary. |
| #bit_count | Returns the number of set bits (1s) in the buffer, also known as the Hamming weight or population count. |
| #clear | Fill buffer with |
| #copy | Efficiently copy from a source |
| #get_string | Read a chunk or all of the buffer into a string, in the specified |
| #get_value | Read from buffer a value of |
| #get_values | Similar to #get_value, except that it can handle multiple buffer types and returns an array of values. |
| #hexdump | Returns a human-readable string representation of the buffer. |
| #not! | Modify the source buffer in place by applying the unary NOT operation to the source. |
| #or! | Modify the source buffer in place by applying the binary OR operation to the source, using the mask, repeating as necessary. |
| #read | Perform one read operation of at most |
| #set_string | Efficiently copy from a source |
| #set_value, | |
| #set_values | Write #values of |
| #size, | |
| #slice | Produce another |
| #source | Returns the object backing this view, or |
| #to_s, | |
| #values | Returns an array of values of |
| #write | Perform one write operation of at most |
| #xor! | Modify the source buffer in place by applying the binary XOR operation to the source, using the mask, repeating as necessary. |
| #| | Generate a new buffer the same size as the source by applying the binary OR operation to the source, using the mask, repeating as necessary. |
| #~ | Generate a new buffer the same size as the source by applying the unary NOT operation to the source. |
::Comparable - Included
| #< | Returns whether |
| #<= | Returns whether |
| #== | Compares two objects based on the receiver's #<=> method, returning true if it returns 0. |
| #> | Returns whether |
| #>= | Returns whether |
| #between? | |
| #clamp |
Constructor Details
.new(source, [offset, [length]]) ⇒ Slice
Creates a parent-relative view of a ::IO::Buffer or another Slice. The source is
retained, not copied. Resizing or advancing this view never allocates storage.
# File 'io_buffer.c', line 2153
static VALUE
io_buffer_slice_initialize(int argc, VALUE *argv, VALUE self)
{
rb_check_frozen(self);
rb_check_arity(argc, 1, 3);
struct rb_io_buffer_view *slice = get_io_buffer_view(self);
if (!NIL_P(slice->source)) rb_raise(rb_eRuntimeError, "Slice is already initialized!");
VALUE source = argv[0];
size_t offset, length;
struct rb_io_buffer_view *parent = io_buffer_extract_offset_length(source, argc-1, argv+1, &offset, &length);
io_buffer_validate_range(parent, offset, length);
slice = get_io_buffer_view(self);
if (!NIL_P(slice->source)) rb_raise(rb_eRuntimeError, "Slice is already initialized!");
slice->base = (void *)(uintptr_t)offset;
slice->size = length;
RB_OBJ_WRITE(self, &slice->source, source);
return self;
}
Instance Method Details
#dup ⇒ Slice
#clone ⇒ Slice
Slice
#clone ⇒ Slice
Copies the view, retaining the same source, offset, and size without copying the underlying bytes. Advancing or resizing the copy does not change the original view; writes through either view affect shared storage.
buffer = IO::Buffer.new(6)
buffer.set_string("abcdef")
slice = buffer.slice(1, 3)
copy = slice.dup
copy.source.equal?(slice.source) # => true
copy.advance(1)
copy.get_string # => "cd"
slice.get_string # => "bcd"
copy.set_string("XY")
buffer.get_string # => "abXYef"
This differs from IO::Buffer::Storage#dup, which copies the bytes into independent
storage. The usual Object#dup and Object#clone frozen-state rules apply.
# File 'io_buffer.c', line 2197
static VALUE
io_buffer_slice_initialize_copy(VALUE self, VALUE other)
{
if (self == other) return self;
rb_check_frozen(self);
struct rb_io_buffer_view *slice = get_io_buffer_view(self);
const struct rb_io_buffer_view *original = get_io_buffer_view(other);
if (!io_buffer_slice_p(original)) rb_raise(rb_eTypeError, "Expected IO::Buffer::Slice!");
if (!NIL_P(slice->source)) rb_raise(rb_eRuntimeError, "Slice is already initialized!");
slice->base = original->base;
slice->size = original->size;
slice->flags = original->flags;
RB_OBJ_WRITE(self, &slice->source, original->source);
return self;
}
#resize(new_size) ⇒ self
Alias for Storage#resize.