Class: PackedStruct::Package

Inherits:
Object
  • Object
show all
Defined in:
lib/packed_struct/package.rb

Overview

Manages the struct overall, and keeps track of the directives. Directives are packed in the order that they are joined, such that the first one defined is the first one on the string.

Instance Method Summary collapse

Constructor Details

#initializePackage

Initialize the package.



17
18
19
# File 'lib/packed_struct/package.rb', line 17

def initialize
  @directives = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *arguments, &block) ⇒ Directive

Creates a new directive with the given method and arguments.

Returns:



140
141
142
143
144
145
146
147
148
# File 'lib/packed_struct/package.rb', line 140

def method_missing(method, *arguments, &block)
  if @directives.map(&:name).include?(method) && arguments.length == 0
    @directives.select { |x| x.name == method }.first
  else
    directive = Directive.new(method, *arguments)
    @directives << directive
    directive
  end
end

Instance Method Details

#directivesArray<Directive>

The list of directives that the package has.

Returns:



11
12
13
14
# File 'lib/packed_struct/package.rb', line 11

def directives
  @directives = @directives.select { |x| x.parent.nil? }
  @directives
end

#fast_unpack(string) ⇒ Hash<Symbol, Object>

This unpacks the entire string at once. It assumes that none of the directives will need the values of other directives. If you’re not sure what this means, don’t use it.

Parameters:

  • string (String)

    the packed string.

Returns:

  • (Hash<Symbol, Object>)

    the unpacked data.



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/packed_struct/package.rb', line 117

def fast_unpack(string)
  out = string.unpack(to_s)
  parts = {}

  directives.each_with_index do |directive, i|
    parts[directive.name] = out[i]
  end

  parts.delete(:null) {}
  parts
end

#inspectString

Inspects the package.

Returns:

  • (String)


133
134
135
# File 'lib/packed_struct/package.rb', line 133

def inspect
  "#<#{self.class.name}:#{"0x%014x" % directives.map(&:object_id).inject(&:+)}>"
end

#pack(data) ⇒ String

Packs the given data into a string. The keys of the data correspond to the names of the directives.

Parameters:

  • the (Hash<Symbol, Object>)

    data.

Returns:

  • (String)

    the packed data.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/packed_struct/package.rb', line 36

def pack(data)
  values = []
  data.each do |k, v|
    values.push([k, v])
  end

  mapped_directives = @directives.map(&:name)

  values = values.select { |x| mapped_directives.include?(x[0]) }

  values.sort! do |a, b|
    o = mapped_directives.index(a[0]) <=> mapped_directives.index(b[0])
  end

  pack_with_array(values.map(&:last))
end

#pack_with_array(*array) ⇒ String

Packs the directives into a string. Uses an array. The parameters can either be an array, or a set of values.

Returns:

  • (String)


57
58
59
60
61
62
63
64
# File 'lib/packed_struct/package.rb', line 57

def pack_with_array(*array)
  array.flatten!

  directives.each_with_index { |e, i| e.value = array[i] }
  out = array.pack(self.to_s)
  directives.each { |x| x.value = nil }
  out
end

#to_sString Also known as: to_str

Turn the package into a string. Uses the directives (calls Directive#to_s on them), and joins the result.

Returns:

  • (String)

    the string ready for #pack.



25
26
27
# File 'lib/packed_struct/package.rb', line 25

def to_s
  directives.map(&:to_s).join(' ')
end

#unpack(string) ⇒ Hash<Symbol, Object>

Unpacks the given string with the directives. Returns a hash containing the values, with the keys being the names of the directives.

Parameters:

  • string (String)

    the packed string.

Returns:

  • (Hash<Symbol, Object>)

    the unpacked data.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/packed_struct/package.rb', line 72

def unpack(string)
  total = ""
  parts = {}
  directives.each_with_index do |directive, i|
    total << directive.to_s
    value = string.unpack(total)[i]
    directive.value = value
    parts[directive.name] = value
  end


  directives.each { |x| x.value = nil }

  parts.delete(:null) {}
  parts
end

#unpack_from_socket(sock) ⇒ Hash<Symbol, Object>

Unpacks from a socket.

Parameters:

  • sock (#read)

    the socket to unpack from.

Returns:

  • (Hash<Symbol, Object>)

    the unpacked data.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/packed_struct/package.rb', line 92

def unpack_from_socket(sock)
  read  = ""
  total = ""
  parts = {}

  directives.each_with_index do |directive, i|
    total << directive.to_s
    read << sock.read(directive.bytesize)
    value = read.unpack(total)[i]
    directive.value = value
    parts[directive.name] = value
  end

  directives.each { |x| x.value = nil }

  parts.delete(:null) {}
  parts
end