class Ronin::Support::Binary::ByteSlice

Represents a slice of bytes from a larger buffer.

@api semipublic

Attributes

bytesize[R]

The length of the byte slice within {#string}.

@return [Integer]

length[R]

The length of the byte slice within {#string}.

@return [Integer]

offset[R]

The offset that the byte slice starts at within {#string}.

@return [Integer]

size[R]

The length of the byte slice within {#string}.

@return [Integer]

string[R]

The underlying string of the byte slice.

@return [String]

Public Class Methods

new(string, offset: , length: ) click to toggle source

Initializes the byte slice.

@param [String, ByteSlice] string

The string that the byte slice will point within.

@param [Integer] offset

The offset of the byte slice within the string.

@param [Integer, Float::INFINITY] length

The length of the byte slice, in bytes.

@raise [ArgumentError]

The given string was not a Stirng or a {ByteSlice}.

@raise [IndexError]

The offset or length is out of bounds of the strings length.
# File lib/ronin/support/binary/byte_slice.rb, line 65
def initialize(string, offset: , length: )
  if length == Float::INFINITY
    length = string.bytesize - offset
  end

  case string
  when ByteSlice
    if (offset < 0) || ((offset + length) > string.bytesize)
      raise(IndexError,"offset #{offset} or length #{length} is out of bounds: 0...#{string.bytesize}")
    end

    @string = string.string
    @offset = string.offset + offset
    @length = length
  when String
    if (offset < 0) || ((offset + length) > string.bytesize)
      raise(IndexError,"offset #{offset} or length #{length} is out of bounds: 0...#{string.bytesize}")
    end

    @string = string
    @offset = offset
    @length = length
  else
    raise(ArgumentError,"string was not a String or a #{ByteSlice}: #{string.inspect}")
  end
end

Public Instance Methods

[](index_or_range,length=nil) click to toggle source

Reads a character or a substring from the buffer at the given index.

@param [Integer, (Integer, Integer), Range(Integer)] index_or_range

The index or range within the buffer to read from.

@param [Integer, nil] length

Optional additional length argument.

@return [String, nil]

The character or substring at the given index or range.

@raise [ArgumentError]

An invalid index or length value was given.
# File lib/ronin/support/binary/byte_slice.rb, line 107
def [](index_or_range,length=nil)
  case index_or_range
  when Range
    range = index_or_range

    @string[@offset + range.begin,range.end - range.begin]
  when Integer
    index = index_or_range

    case length
    when Integer
      @string[@offset + index,length]
    when nil
      @string[@offset + index]
    when Float::INFINITY
      @string[@offset + index,@length - index]
    else
      raise(ArgumentError,"invalid length (#{length.inspect}) must be an Integer, nil, or Float::INFINITY")
    end
  else
    raise(ArgumentError,"invalid index (#{index_or_range.inspect}) must be an Integer or a Range")
  end
end
[]=(index_or_range,length=nil,value) click to toggle source

Writes a value to the buffer at the given index.

@param [Integer, Range(Integer)] index_or_range

The index or range within the string to write to.

@param [Integer, nil] length

Optional additional length argument.

@param [String] value

The integer, float, or character value to write to the buffer.

@return [String]

The string written into the buffer.

@raise [ArgumentError]

An invalid index or length value was given.
# File lib/ronin/support/binary/byte_slice.rb, line 149
def []=(index_or_range,length=nil,value)
  case index_or_range
  when Range
    range = index_or_range

    @string[@offset + range.begin,range.end - range.begin] = value
  when Integer
    index = index_or_range

    case length
    when Integer
      @string[@offset + index,length] = value
    when nil
      @string[@offset + index] = value
    when Float::INFINITY
      @string[@offset + index,@length - index] = value
    else
      raise(ArgumentError,"invalid length (#{length.inspect}) must be an Integer, nil, or Float::INFINITY")
    end
  else
    raise(ArgumentError,"invalid index (#{index_or_range.inspect}) must be an Integer or a Range")
  end
end
bytes() click to toggle source

The bytes within the byte slice.

@return [Array<Integer>]

The Array of bytes within the byte slice.
# File lib/ronin/support/binary/byte_slice.rb, line 271
def bytes
  each_byte.to_a
end
byteslice(offset,length=1) click to toggle source

Creates a new byte slice within the byte slice.

@param [Integer] offset

The offset of the new byte slice.

@param [Integer] length

The length of the new byte slice.

@return [ByteSlice]

The new byte slice.
# File lib/ronin/support/binary/byte_slice.rb, line 185
def byteslice(offset,length=1)
  ByteSlice.new(self, offset: offset, length: length)
end
chars() click to toggle source

The characters within the byte slice.

@return [Array<String>]

The Array of characters within the byte slice.
# File lib/ronin/support/binary/byte_slice.rb, line 302
def chars
  each_char.to_a
end
each_byte() { |getbyte| ... } click to toggle source

Enumerates over each byte in the byte slice.

@yield [byte]

If a block is given, it will be passed each byte within the byte
slice.

@yieldparam [Integer] byte

A byte value from the byte slice.

@return [Enumerator]

If no block is given, an Enumerator will be returned.
# File lib/ronin/support/binary/byte_slice.rb, line 257
def each_byte
  return enum_for(__method__) unless block_given?

  (@offset...(@offset + @length)).each do |index|
    yield @string.getbyte(index)
  end
end
each_char() { |string| ... } click to toggle source

Enumerates over each character within the byte slice.

@yield [char]

If a block is given, it will be passed each character within the
byte slice.

@yieldparam [String] char

A character value from the byte slice.

@return [Enumerator]

If no block is given, an Enumerator will be returned.
# File lib/ronin/support/binary/byte_slice.rb, line 288
def each_char
  return enum_for(__method__) unless block_given?

  (@offset...(@offset + @length)).each do |index|
    yield @string[index]
  end
end
getbyte(index) click to toggle source

Gets the byte at the given index within the byte slice.

@param [Integer] index

@return [Integer, nil]

The byte at the given index, or nil if the index is out of bounds.
# File lib/ronin/support/binary/byte_slice.rb, line 218
def getbyte(index)
  if index < @length
    @string.getbyte(@offset + index)
  end
end
index(substring,offset=0) click to toggle source

Finds the substring within the byte slice.

@param [String] substring

The substring to search for.

@param [Integer] offset

The optional offset to start searching at.

@return [Integer, nil]

The index of the substring or `nil` if the substring could not be
found.
# File lib/ronin/support/binary/byte_slice.rb, line 202
def index(substring,offset=0)
  if (index = @string.index(substring,@offset + offset))
    if index < (@offset + @length)
      index - @offset
    end
  end
end
setbyte(index,byte) click to toggle source

Sets the byte at the given index within the byte slice.

@param [Integer] index

The index to set.

@param [Integer] byte

The new byte value to set.

@raise [IndexError]

The index was out of bounds.
# File lib/ronin/support/binary/byte_slice.rb, line 236
def setbyte(index,byte)
  if index < @length
    @string.setbyte(@offset + index,byte)
  else
    raise(IndexError,"index #{index.inspect} is out of bounds")
  end
end
to_s() click to toggle source

Converts the byte slice to a String.

@return [String]

# File lib/ronin/support/binary/byte_slice.rb, line 311
def to_s
  if (@offset > 0 || @length < @string.bytesize)
    @string[@offset,@length]
  else
    @string
  end
end
Also aliased as: to_str
to_str()
Alias for: to_s