Class: DMAP::Tag

Inherits:
Object show all
Defined in:
lib/dmap/tag.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code, value) ⇒ Tag

Returns a new instance of Tag.



11
12
13
14
15
16
17
# File 'lib/dmap/tag.rb', line 11

def initialize(code, value)
  @code, @value = code, value
  @tag, @type = lookup
  
  raise "Cannot have nil value in tag #{code}" if value.nil? && type != :list
  raise "Unknown tag #{code}" if tag.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object



87
88
89
90
91
# File 'lib/dmap/tag.rb', line 87

def method_missing(meth, *args)
  return super unless self.class.lookup(meth)
  return super unless value.is_a? Array
  value.find { |v| v.code == meth }.value
end

Instance Attribute Details

#codeObject

Returns the value of attribute code.



9
10
11
# File 'lib/dmap/tag.rb', line 9

def code
  @code
end

#tagObject

Returns the value of attribute tag.



9
10
11
# File 'lib/dmap/tag.rb', line 9

def tag
  @tag
end

#typeObject

Returns the value of attribute type.



9
10
11
# File 'lib/dmap/tag.rb', line 9

def type
  @type
end

#valueObject

Returns the value of attribute value.



9
10
11
# File 'lib/dmap/tag.rb', line 9

def value
  @value
end

Class Method Details

.lookup(code) ⇒ Object



4
5
6
# File 'lib/dmap/tag.rb', line 4

def lookup(code)
  TAGS[code]
end

Instance Method Details

#==(obj) ⇒ Object

Could be optimised later down the track



40
41
42
# File 'lib/dmap/tag.rb', line 40

def ==(obj)
  self.to_dmap == obj.to_dmap
end

#inspect(level = 0) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/dmap/tag.rb', line 63

def inspect(level = 0)
  pad = ' ' * (level * 2)
  case value
  when Array
    if value.any? { |e| e.is_a? Tag }
      (["#{pad}#{code}[#{length}]: #{tag}"] + value.map{ |v| v.inspect(level + 1) }).join("\n")
    else
      "#{pad}#{code}[#{length}]: #{value.inspect} - #{tag}"
    end
  else
    "#{pad}#{code}[#{length}]: #{value.inspect} - #{tag}"
  end
end

#lengthObject



48
49
50
51
52
53
54
55
56
57
# File 'lib/dmap/tag.rb', line 48

def length
  @length ||= case type
  when :string
    value.length
  when :list
    (value || []).inject(0) { |mem, v| mem += v.length + 8 }
  else
    STATIC_LENGTH_TYPES[type].first
  end
end

#lookupObject



59
60
61
# File 'lib/dmap/tag.rb', line 59

def lookup
  self.class.lookup(code)
end

#pack_codeObject



44
45
46
# File 'lib/dmap/tag.rb', line 44

def pack_code
  @pack_code ||= STATIC_LENGTH_TYPES[type].last rescue raise("No pack code definition for #{code}")
end

#to_dmapObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/dmap/tag.rb', line 19

def to_dmap
  data = case type
  when :string
    value
  when :list
    (value || []).inject('') { |mem, v| mem += v.to_dmap }
  when :version
    value.pack(pack_code)
  when :long
    # Some types seem to be the wrong endian
    # so there are endian hacks
    [value].pack('Q').reverse
  when :signed_integer
    [value].pack(pack_code).reverse
  else
    [value.to_i].pack(pack_code)
  end
  "#{code}#{[length].pack('N')}#{data}"
end

#to_dsl(level = 0) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'lib/dmap/tag.rb', line 77

def to_dsl(level = 0)
  pad = ' ' * (level * 2)
  case value
  when Array
    (["#{pad}#{code} do # #{tag}"] + value.map{ |v| v.to_dsl(level + 1) } + ["#{pad}end"]).join("\n")
  else
    "#{pad}#{code} #{value.inspect} # #{tag}"
  end
end