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 String or a Ronin::Support::Binary::ByteSlice.

  • (IndexError)

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

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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:

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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:

[View source]

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