Class: Ronin::Binary::Template

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

Overview

Provides a translation layer between C-types and Ruby Array#pack codes.

Types

  • :uint8 (C) - unsigned 8-bit integer.
  • :uint16 (S) - unsigned 16-bit integer.
  • :uint32 (L) - unsigned 32-bit integer.
  • :uint64 (Q) - unsigned 64-bit integer.
  • :int8 (c) - signed 8-bit integer.
  • :int16 (s) - signed 16-bit integer.
  • :int32 (l) - signed 32-bit integer.
  • :int64 (q) - signed 64-bit integer.
  • :uint16_le (v) - unsigned 16-bit integer, little endian.
  • :uint32_le (V) - unsigned 32-bit integer, little endian.
  • :uint16_be (n) - unsigned 16-bit integer, big endian.
  • :uint32_be (N) - unsigned 32-bit integer, big endian.
  • :uchar (Z) - unsigned character.
  • :ushort (S!) - unsigned short integer, native endian.
  • :uint (I!) - unsigned integer, native endian.
  • :ulong (L!) - unsigned long integer, native endian.
  • :ulong_long (Q) - unsigned quad integer, native endian.
  • :char (Z) - signed character.
  • :short (s!) - signed short integer, native endian.
  • :int (i!) - signed integer, native endian.
  • :long (l!) - signed long integer, native endian.
  • :long_long (q) - signed quad integer, native endian.
  • :utf8 (U) - UTF8 character.
  • :float (F) - single-precision float, native format.
  • :double (D) - double-precision float, native format.
  • :float_le (e) - single-precision float, little endian.
  • :double_le (E) - double-precision float, little endian.
  • :float_be (g) - single-precision float, big endian.
  • :double_be (G) - double-precision float, big endian.
  • :ubyte (C) - unsigned byte.
  • :byte (c) - signed byte.
  • :string (Z*) - binary String, \0 terminated.

Ruby 1.9 specific C-types

  • :uint16_le (S<) - unsigned 16-bit integer, little endian.
  • :uint32_le (L<) - unsigned 32-bit integer, little endian.
  • :uint64_le (Q<) - unsigned 64-bit integer, little endian.
  • :int16_le (s<) - signed 16-bit integer, little endian.
  • :int32_le (l<) - signed 32-bit integer, little endian.
  • :int64_le (q<) - signed 64-bit integer, little endian.
  • :uint16_be (S>) - unsigned 16-bit integer, big endian.
  • :uint32_be (L>) - unsigned 32-bit integer, big endian.
  • :uint64_be (Q>) - unsigned 64-bit integer, big endian.
  • :int16_be (s>) - signed 16-bit integer, big endian.
  • :int32_be (l>) - signed 32-bit integer, big endian.
  • :int64_be (q>) - signed 64-bit integer, big endian.
  • :ushort_le (S<) - unsigned short integer, little endian.
  • :uint_le (I<) - unsigned integer, little endian.
  • :ulong_le (L<) - unsigned long integer, little endian.
  • :ulong_long_le (Q<) - unsigned quad integer, little endian.
  • :short_le (s<) - signed short integer, little endian.
  • :int_le (i<) - signed integer, little endian.
  • :long_le (l<) - signed long integer, little endian.
  • :long_long_le (q<) - signed quad integer, little endian.
  • :ushort_be (S>) - unsigned short integer, little endian.
  • :uint_be (I>) - unsigned integer, little endian.
  • :ulong_be (L>) - unsigned long integer, little endian.
  • :ulong_long_be (Q>) - unsigned quad integer, little endian.
  • :short_be (s>) - signed short integer, little endian.
  • :int_be (i>) - signed integer, little endian.
  • :long_be (l>) - signed long integer, little endian.
  • :long_long_be (q>) - signed quad integer, little endian.

See Also:

Since:

Constant Summary

TYPES =

Supported C-types and corresponding Array#pack codes.

Since:

  • 0.5.0

{
  :uint8  => 'C',
  :uint16 => 'S',
  :uint32 => 'L',
  :uint64 => 'Q',

  :int8   => 'c',
  :int16  => 's',
  :int32  => 'l',
  :int64  => 'q',

  :uint16_le => 'v',
  :uint32_le => 'V',
  :uint16_be => 'n',
  :uint32_be => 'N',

  :uchar      => 'Z',
  :ushort     => 'S!',
  :uint       => 'I!',
  :ulong      => 'L!',
  :ulong_long => 'Q',

  :char      => 'Z',
  :short     => 's!',
  :int       => 'i!',
  :long      => 'l!',
  :long_long => 'q',

  :utf8 => 'U',

  :float     => 'F',
  :double    => 'D',

  :float_le  => 'e',
  :double_le => 'E',

  :float_be  => 'g',
  :double_be => 'G',

  :ubyte  => 'C',
  :byte   => 'c',
  :string => 'Z*'
}
INT_TYPES =

Integer C-types

Since:

  • 0.5.0

Set[
  :uint8,
  :uint16,
  :uint32,
  :uint64,

  :int8,
  :int16,
  :int32,
  :int64,

  :ubyte,
  :ushort,
  :uint,
  :ulong,
  :ulong_long,

  :byte,
  :short,
  :int,
  :long,
  :long_long,

  :uint16_le,
  :uint32_le,
  :uint64_le,

  :int16_le,
  :int32_le,
  :int64_le,

  :ushort_le,
  :uint_le,
  :ulong_le,
  :ulong_long_le,

  :short_le,
  :int_le,
  :long_le,
  :long_long_le,

  :uint16_be,
  :uint32_be,
  :uint64_be,

  :int16_be,
  :int32_be,
  :int64_be,

  :ushort_be,
  :uint_be,
  :ulong_be,
  :ulong_long_be,

  :short_be,
  :int_be,
  :long_be,
  :long_long_be
]
FLOAT_TYPES =

Float C-types

Since:

  • 0.5.0

Set[
  :float,    :double,
  :float_le, :double_le,
  :float_be, :double_be
]
CHAR_TYPES =

Character C-types

Since:

  • 0.5.0

Set[:uchar, :char]
STRING_TYPES =

String C-types

Since:

  • 0.5.0

CHAR_TYPES + Set[:string]
ENDIAN_TYPES =

Types which have little and big endian forms

Since:

  • 0.5.0

Set[
  :uint16, :uint32, :uint64,
  :int16, :int32, :int64,
  :ushort, :uint, :ulong, :ulong_long,
  :short, :int, :long, :long_long,
  :float, :double
]

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Template) initialize(fields, options = {})

Note:

The following C-types are not supported on Ruby 1.8:

  • :uint16_le
  • :uint32_le
  • :uint64_le
  • :int16_le
  • :int32_le
  • :int64_le
  • :uint16_be
  • :uint32_be
  • :uint64_be
  • :int16_be
  • :int32_be
  • :int64_be
  • :ushort_le
  • :uint_le
  • :ulong_le
  • :ulong_long_le
  • :short_le
  • :int_le
  • :long_le
  • :long_long_le
  • :ushort_be
  • :uint_be
  • :ulong_be
  • :ulong_long_be
  • :short_be
  • :int_be
  • :long_be
  • :long_long_be

Creates a new Binary Template.

Examples:

Template.new(:uint32, [:char, 100])

Parameters:

  • fields (Array<type, (type, length)>)

    The C-types which the packer will use.

  • options (Hash) (defaults to: {})

    Template options.

Options Hash (options):

  • :endian (:little, :big, :network)

    The endianness to apply to the C-types.

Raises:

  • (ArgumentError)

    A given type is not known.

Since:

  • 0.5.0



324
325
326
327
# File 'lib/ronin/binary/template.rb', line 324

def initialize(fields,options={})
  @fields   = fields
  @template = self.class.compile(@fields,options)
end

Instance Attribute Details

- (Object) fields (readonly)

The fields of the template

Since:

  • 0.5.0



272
273
274
# File 'lib/ronin/binary/template.rb', line 272

def fields
  @fields
end

Class Method Details

+ (Object) [](*fields)

See Also:

Since:

  • 0.5.0



332
333
334
# File 'lib/ronin/binary/template.rb', line 332

def self.[](*fields)
  new(fields)
end

+ (String) compile(types, options = {})

Compiles C-types into an Array#pack / String#unpack template.

Parameters:

  • types (Array<type, (type, length)>)

    The C-types which the packer will use.

  • options (Hash) (defaults to: {})

    Type options.

Options Hash (options):

  • :endian (:little, :big, :network)

    The endianness to apply to the C-types.

Returns:

  • (String)

    The Array#pack / String#unpack template.

Raises:

  • (ArgumentError)

    A given type is not known.

Since:

  • 0.5.0



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/ronin/binary/template.rb', line 386

def self.compile(types,options={})
  string = ''

  types.each do |(type,length)|
    type = translate(type,options)

    unless (code = TYPES[type])
      raise(ArgumentError,"#{type.inspect} not supported")
    end

    string << code << length.to_s
  end

  return string
end

+ (Symbol) translate(type, options = {})

Translates the type of the field.

Parameters:

  • type (Symbol)

    The type to translate.

  • options (Hash) (defaults to: {})

    Translation options.

Options Hash (options):

  • :endian (:little, :big, :network)

    The endianness to apply to the C-types.

Returns:

  • (Symbol)

    The translated type.

Raises:

  • (ArgumentError)

    The value of :endian is unknown.

Since:

  • 0.5.0



354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/ronin/binary/template.rb', line 354

def self.translate(type,options={})
  if (options[:endian] && ENDIAN_TYPES.include?(type))
    type = case options[:endian]
           when :little        then :#{type}_le"
           when :big, :network then :#{type}_be"
           else
             raise(ArgumentError,"unknown endianness: #{type}")
           end
  end

  return type
end

Instance Method Details

- (String) inspect

Inspects the template.

Returns:

  • (String)

    The inspected template.

Since:

  • 1.5.1



448
449
450
# File 'lib/ronin/binary/template.rb', line 448

def inspect
  "<#{self.class}: #{@fields.inspect}>"
end

- (String) pack(*data)

Packs the data.

Parameters:

  • data (Array)

    The data to pack.

Returns:

  • (String)

    The packed data.

Since:

  • 0.5.0



411
412
413
# File 'lib/ronin/binary/template.rb', line 411

def pack(*data)
  data.pack(@template)
end

- (String) to_s

Converts the template to a Array#pack template String.

Returns:

  • (String)

    The template String.

See Also:

Since:

  • 0.5.0



436
437
438
# File 'lib/ronin/binary/template.rb', line 436

def to_s
  @template
end

- (Array) unpack(string)

Unpacks the string.

Parameters:

  • string (String)

    The raw String to unpack.

Returns:

  • (Array)

    The unpacked data.

Since:

  • 0.5.0



424
425
426
# File 'lib/ronin/binary/template.rb', line 424

def unpack(string)
  string.unpack(@template)
end