Class: Ronin::Support::Binary::ByteSlice

Inherits:
Object
  • Object
show all
Defined in:
lib/ronin/support/binary/byte_slice.rb

Overview

Represents a slice of bytes from a larger buffer.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string, offset:, length:) ⇒ ByteSlice

Initializes the byte slice.

Parameters:

  • string (String, ByteSlice)

    The string that the byte slice will point within.

  • offset (Integer)

    The offset of the byte slice within the string.

  • length (Integer, Float::INFINITY)

    The length of the byte slice, in bytes.

Raises:

  • (ArgumentError)

    The given string was not a Stirng or a Ronin::Support::Binary::ByteSlice.

  • (IndexError)

    The offset or length is out of bounds of the strings length.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 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

Instance Attribute Details

#lengthInteger (readonly) Also known as: bytesize, size

The length of the byte slice within #string.

Returns:



42
43
44
# File 'lib/ronin/support/binary/byte_slice.rb', line 42

def length
  @length
end

#offsetInteger (readonly)

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

Returns:



37
38
39
# File 'lib/ronin/support/binary/byte_slice.rb', line 37

def offset
  @offset
end

#stringString (readonly)

The underlying string of the byte slice.

Returns:



32
33
34
# File 'lib/ronin/support/binary/byte_slice.rb', line 32

def string
  @string
end

Instance Method Details

#[](index_or_range, length = nil) ⇒ String?

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

Parameters:

  • index_or_range (Integer, (Integer, Integer), Range(Integer))

    The index or range within the buffer to read from.

  • length (Integer, nil) (defaults to: nil)

    Optional additional length argument.

Returns:

  • (String, nil)

    The character or substring at the given index or range.

Raises:

  • (ArgumentError)

    An invalid index or length value was given.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# 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) ⇒ String

Writes a value to the buffer at the given index.

Parameters:

  • index_or_range (Integer, Range(Integer))

    The index or range within the string to write to.

  • length (Integer, nil) (defaults to: nil)

    Optional additional length argument.

  • value (String)

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

Returns:

  • (String)

    The string written into the buffer.

Raises:

  • (ArgumentError)

    An invalid index or length value was given.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# 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

#bytesArray<Integer>

The bytes within the byte slice.

Returns:

  • (Array<Integer>)

    The Array of bytes within the byte slice.



271
272
273
# File 'lib/ronin/support/binary/byte_slice.rb', line 271

def bytes
  each_byte.to_a
end

#byteslice(offset, length = 1) ⇒ ByteSlice

Creates a new byte slice within the byte slice.

Parameters:

  • offset (Integer)

    The offset of the new byte slice.

  • length (Integer) (defaults to: 1)

    The length of the new byte slice.

Returns:



185
186
187
# File 'lib/ronin/support/binary/byte_slice.rb', line 185

def byteslice(offset,length=1)
  ByteSlice.new(self, offset: offset, length: length)
end

#charsArray<String>

The characters within the byte slice.

Returns:

  • (Array<String>)

    The Array of characters within the byte slice.



302
303
304
# File 'lib/ronin/support/binary/byte_slice.rb', line 302

def chars
  each_char.to_a
end

#each_byte {|byte| ... } ⇒ Enumerator

Enumerates over each byte in the byte slice.

Yields:

  • (byte)

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

Yield Parameters:

  • byte (Integer)

    A byte value from the byte slice.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.



257
258
259
260
261
262
263
# 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 {|char| ... } ⇒ Enumerator

Enumerates over each character within the byte slice.

Yields:

  • (char)

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

Yield Parameters:

  • char (String)

    A character value from the byte slice.

Returns:

  • (Enumerator)

    If no block is given, an Enumerator will be returned.



288
289
290
291
292
293
294
# 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) ⇒ Integer?

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

Parameters:

Returns:

  • (Integer, nil)

    The byte at the given index, or nil if the index is out of bounds.



218
219
220
221
222
# 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) ⇒ Integer?

Finds the substring within the byte slice.

Parameters:

  • substring (String)

    The substring to search for.

  • offset (Integer) (defaults to: 0)

    The optional offset to start searching at.

Returns:

  • (Integer, nil)

    The index of the substring or nil if the substring could not be found.



202
203
204
205
206
207
208
# 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) ⇒ Object

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

Parameters:

  • index (Integer)

    The index to set.

  • byte (Integer)

    The new byte value to set.

Raises:

  • (IndexError)

    The index was out of bounds.



236
237
238
239
240
241
242
# 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_sString Also known as: to_str

Converts the byte slice to a String.

Returns:



311
312
313
314
315
316
317
# 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