lib/ronin/formatting/extensions/binary/integer.rb in ronin-support-0.4.1 vs lib/ronin/formatting/extensions/binary/integer.rb in ronin-support-0.5.0.rc1
- old
+ new
@@ -15,35 +15,37 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
#
+require 'ronin/binary/template'
+
class Integer
#
# Extracts a sequence of bytes which represent the Integer.
#
- # @param [Integer] address_length
+ # @param [Integer] length
# The number of bytes to decode from the Integer.
#
# @param [Symbol, String] endian
# The endianness to use while decoding the bytes of the Integer.
# May be one of:
#
- # * `:big` / `"big"`
- # * `:little` / `"little"`
- # * `:net` / `"net"`
+ # * `big`
+ # * `little`
+ # * `net`
#
# @return [Array]
# The bytes decoded from the Integer.
#
# @raise [ArgumentError]
# The given `endian` was not one of:
#
- # * `:little` / `"little"`
- # * `:net` / `"net"`
- # * `:big` / `"big"`
+ # * `little`
+ # * `net`
+ # * `big`
#
# @example
# 0xff41.bytes(2)
# # => [65, 255]
#
@@ -51,30 +53,30 @@
# 0xff41.bytes(4, :big)
# # => [0, 0, 255, 65]
#
# @api public
#
- def bytes(address_length,endian=:little)
+ def bytes(length,endian=:little)
endian = endian.to_sym
buffer = []
case endian
when :little, :net
mask = 0xff
shift = 0
- address_length.times do |i|
+ length.times do |i|
buffer << ((self & mask) >> shift)
mask <<= 8
shift += 8
end
when :big
- shift = ((address_length - 1) * 8)
+ shift = ((length - 1) * 8)
mask = (0xff << shift)
- address_length.times do |i|
+ length.times do |i|
buffer << ((self & mask) >> shift)
mask >>= 8
shift -= 8
end
@@ -84,66 +86,77 @@
return buffer
end
#
- # Packs the Integer into a String, for a specific architecture and
- # address-length.
+ # Packs the Integer into a String.
#
- # @param [Ronin::Arch, #endian, #address_length, String] arch
- # The architecture to pack the Integer for.
+ # @param [String, Symbol, arch] arguments
+ # The `Array#pack` code, {Ronin::Binary::Template} type or Architecture
+ # object with `#endian` and `#address_length` methods.
#
- # @param [Integer] address_length
- # The number of bytes to pack.
- #
# @return [String]
# The packed Integer.
#
# @raise [ArgumentError]
- # The given `arch` does not respond to the `endian` or
- # `address_length` methods.
+ # The arguments were not a String, Symbol or Architecture object.
#
- # @example using archs other than `Ronin::Arch`.
+ # @example using a `Array#pack` template:
+ # 0x41.pack('V')
+ # # => "A\0\0\0"
+ #
+ # @example using {Ronin::Binary::Template} types:
+ # 0x41.pack(:uint32_le)
+ #
+ # @example using archs other than `Ronin::Arch` (**deprecated**):
# arch = OpenStruct.new(:endian => :little, :address_length => 4)
- #
+ #
# 0x41.pack(arch)
# # => "A\0\0\0"
#
- # @example using a `Ronin::Arch` arch.
+ # @example using a `Ronin::Arch` arch (**deprecated**):
# 0x41.pack(Arch.i686)
# # => "A\0\0\0"
#
- # @example specifying a custom address-length.
+ # @example specifying a custom address-length (**deprecated**):
# 0x41.pack(Arch.ppc,2)
# # => "\0A"
#
- # @example using a `Array#pack` template String for the arch.
- # 0x41.pack('L')
- # # => "A\0\0\0"
+ # @see http://rubydoc.info/stdlib/core/Array:pack
#
- # @see http://ruby-doc.org/core/classes/Array.html#M002222
- #
# @api public
#
- def pack(arch,address_length=nil)
- if arch.kind_of?(String)
- return [self].pack(arch)
- end
+ def pack(*arguments)
+ argument = arguments.first
- unless arch.respond_to?(:address_length)
- raise(ArgumentError,"first argument to Ineger#pack must respond to address_length")
- end
+ case argument
+ when String
+ [self].pack(argument)
+ when Symbol
+ unless Ronin::Binary::Template::INT_TYPES.include?(argument)
+ raise(ArgumentError,"unsupported integer type: #{argument}")
+ end
- unless arch.respond_to?(:endian)
- raise(ArgumentError,"first argument to Ineger#pack must respond to endian")
- end
+ [self].pack(Ronin::Binary::Template::TYPES[argument])
+ else
+ # TODO: deprecate this calling convention
+ arch, address_length = arguments
- address_length ||= arch.address_length
+ unless arch.respond_to?(:address_length)
+ raise(ArgumentError,"first argument to Ineger#pack must respond to address_length")
+ end
- integer_bytes = bytes(address_length,arch.endian)
- integer_bytes.map! { |b| b.chr }
+ unless arch.respond_to?(:endian)
+ raise(ArgumentError,"first argument to Ineger#pack must respond to endian")
+ end
- return integer_bytes.join
+ address_length ||= arch.address_length
+
+ integer_bytes = bytes(address_length,arch.endian)
+ integer_bytes.map! { |b| b.chr }
+
+ return integer_bytes.join
+ end
end
#
# @return [String]
# The hex escaped version of the Integer.