binary_parser 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,96 +3,97 @@ module BinaryParser
3
3
 
4
4
  DataDefinition = Struct.new(:bit_position, :bit_length, :conditions, :klass)
5
5
  LoopDefinition = Struct.new(:bit_position, :bit_length, :conditions, :klass)
6
+ WhileDefinition = Struct.new(:bit_position, :bit_length, :conditions, :klass, :loop_condition)
6
7
 
7
- attr_reader :parent_structure, :bit_at, :names
8
+ KEYWORDS =
9
+ [
10
+ :data, :SPEND, :TIMES, :WHILE, :IF, :E, :cond, :match, :var, :len, :nextbits, :position,
11
+ :rest, :[]
12
+ ]
8
13
 
9
- def initialize(method_names=[], parent_structure=nil, &init_proc)
10
- @method_names = method_names
14
+ attr_reader :parent_structure, :bit_at, :names
15
+
16
+ def initialize(forbidden_method_names=[], parent_structure=nil, &init_proc)
17
+ @forbidden_method_names = forbidden_method_names
11
18
  @parent_structure = parent_structure
12
19
  @bit_at = BitPosition.new
13
- @data_def, @var = {}, {}
20
+ @data_def = {}
14
21
  @conditions, @names = [], []
15
- instance_eval(&init_proc) if init_proc
22
+ Proxy.new(self, KEYWORDS).instance_eval(&init_proc) if init_proc
16
23
  end
17
24
 
18
25
  def data(name, klass, bit_length)
19
- check_new_def_name(name)
26
+ __check_new_def_name(name)
20
27
  unless klass.ancestors.include?(TemplateBase)
21
28
  raise DefinitionError, "Class #{klass} should be TemplateBase."
22
29
  end
23
- bit_at, bit_length = process_bit_length(bit_length, name)
24
- @data_def[name] = DataDefinition.new(bit_at, bit_length, @conditions.dup, klass)
25
- @names << name
30
+ bit_at, bit_length = __process_bit_length(bit_length, name)
31
+ define(name, DataDefinition.new(bit_at, bit_length, @conditions.dup, klass))
26
32
  end
27
33
 
28
34
  def SPEND(bit_length, name, &block)
29
- check_new_def_name(name)
30
- bit_at, bit_length = process_bit_length(bit_length, name)
35
+ __check_new_def_name(name)
36
+ bit_at, bit_length = __process_bit_length(bit_length, name)
31
37
  klass = NamelessTemplateMaker.new(self, block)
32
- @data_def[name] = LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass)
33
- @names << name
38
+ define(name, LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass))
34
39
  end
35
40
 
36
41
  def TIMES(times, name, &block)
37
- check_new_def_name(name)
42
+ __check_new_def_name(name)
38
43
  klass = NamelessTemplateMaker.new(self, block)
39
44
  structure = klass.structure
40
45
  if structure.bit_at.names.empty?
41
- bit_at, bit_length = process_bit_length(times * structure.bit_at.imm, name)
42
- @data_def[name] = LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass)
46
+ bit_at, bit_length = __process_bit_length(times * structure.bit_at.imm, name)
47
+ define(name, LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass))
43
48
  else
44
- bit_length = Expression.new([0])
45
- structure.bit_at.names.each do |bit_at_depending_name|
46
- depending_length_exp = structure[bit_at_depending_name].bit_length
47
- depending_length_exp.variables.each do |var_name|
48
- if structure[var_name]
49
- raise DefinitionError, "In '#{name}', same level variable #{var_name} is referenced." +
49
+ bit_length = Expression.immediate(0)
50
+ structure.bit_at.names.each do |depending_token|
51
+ depending_length_exp = structure[depending_token.symbol].bit_length
52
+ depending_length_exp.variable_tokens.each do |token|
53
+ if structure[token.symbol]
54
+ raise DefinitionError, "In '#{name}', same level variable #{token.symbol} is referenced." +
50
55
  "*** TIMES's inner structure's bit-length must be always same." +
51
56
  "In other words, that bit-length must not rely on same level variables. ***"
52
57
  end
53
58
  end
54
59
  bit_length += depending_length_exp
55
60
  end
56
- bit_at, bit_length = process_bit_length(bit_length * times, name)
57
- @data_def[name] = LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass)
61
+ bit_at, bit_length = __process_bit_length(bit_length * times, name)
62
+ define(name, LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass))
58
63
  end
64
+ end
65
+
66
+ def define(name, data)
67
+ @data_def[name] = data
59
68
  @names << name
60
69
  end
61
70
 
71
+ def WHILE(condition, name, &block)
72
+ __check_new_def_name(name)
73
+ klass = NamelessTemplateMaker.new(self, block)
74
+ bit_at, bit_length = __process_bit_length(Expression.control_var(:non_fixed), name)
75
+ define(name, WhileDefinition.new(bit_at, bit_length, @conditions.dup, klass, condition))
76
+ end
77
+
62
78
  def IF(condition, &block)
63
79
  @conditions.push(condition)
64
80
  block.call
65
81
  @conditions.pop
66
82
  end
67
83
 
68
- def check_new_def_name(name)
69
- if name[0..1] == "__"
70
- raise DefinitionError, "Name that starts with '__' is system-reserved."
71
- end
72
- if @method_names.include?(name)
73
- raise DefinitionError, "Name '#{name}' is already used as method name." +
74
- "You should chanege to other name."
75
- end
76
- if @data_def[name]
77
- raise DefinitionError, "Name #{name} is already defined." +
78
- "You should change to other name."
79
- end
80
- end
81
-
82
- def name_solvable?(name, structure=self)
83
- return structure[name] ||
84
- (structure.parent_structure && name_solvable?(name, structure.parent_structure))
85
- end
86
-
87
84
  def cond(*var_names, &condition_proc)
88
85
  var_names.each do |var_name|
89
- unless name_solvable?(var_name)
86
+ unless __name_resolvable?(var_name)
90
87
  raise DefinitionError, "As condition variable, unsolvable variable #{var_name} is used."
91
88
  end
92
89
  end
93
90
  return Condition.new(*var_names, &condition_proc)
94
91
  end
95
92
 
93
+ def E(&condition_proc)
94
+ return FreeCondition.new(&condition_proc)
95
+ end
96
+
96
97
  def match(var_name, value)
97
98
  case value
98
99
  when Integer
@@ -107,35 +108,48 @@ module BinaryParser
107
108
  end
108
109
 
109
110
  def var(var_name)
110
- unless name_solvable?(var_name)
111
+ unless __name_resolvable?(var_name)
111
112
  raise DefinitionError, "Unsolvable variable #{var_name} is used."
112
113
  end
113
- return Expression.new([var_name])
114
+ return Expression.value_var(var_name)
114
115
  end
115
116
 
116
117
  def len(var_name)
117
- unless name_solvable?(var_name)
118
+ unless __name_resolvable?(var_name)
118
119
  raise DefinitionError, "Unsolvable variable #{var_name} is used."
119
120
  end
120
- symbol = ("__LEN__" + var_name.to_s).to_sym
121
- return Expression.new([symbol])
121
+ return Expression.length_var(var_name)
122
+ end
123
+
124
+ def nextbits(length)
125
+ return Expression.nextbits_var(length)
122
126
  end
123
127
 
124
128
  def position
125
- return Expression.new([:__position])
129
+ Expression.control_var(:position)
126
130
  end
127
131
 
128
132
  def rest
129
- return Expression.new([:__rest])
133
+ Expression.control_var(:rest)
130
134
  end
131
135
 
132
136
  def [](var_name)
133
137
  return @data_def[var_name]
134
138
  end
135
139
 
140
+ def symbol_call(symbol, *args, &block)
141
+ if args.length == 0
142
+ return var(symbol)
143
+ elsif args.length == 2
144
+ return data(symbol, *args)
145
+ else
146
+ raise DefinitionError, "Unknown use of keyword '#{var_name}' with args(#{args})."
147
+ end
148
+ end
149
+
136
150
  private
137
151
 
138
- def process_bit_length(bit_length, name)
152
+ def __process_bit_length(bit_length, name)
139
153
  bit_at = @bit_at
140
154
  case bit_length
141
155
  when Integer
@@ -144,10 +158,10 @@ module BinaryParser
144
158
  else
145
159
  @bit_at = @bit_at.add_name(name)
146
160
  end
147
- return bit_at, Expression.new([bit_length])
161
+ return bit_at, Expression.immediate(bit_length)
148
162
  when Expression
149
- bit_length.variables.reject{|s| s[0..1] == "__"}.each do |symbol|
150
- unless name_solvable?(symbol)
163
+ bit_length.variable_tokens.each do |token|
164
+ if (token.value_var? || token.length_var?) && !__name_resolvable?(token.symbol)
151
165
  raise DefinitionError, "In #{name}, unsolvable variable #{symbol} is used."
152
166
  end
153
167
  end
@@ -157,5 +171,24 @@ module BinaryParser
157
171
  raise DefinitionError, "Unknown type of bit_length (#{bit_length.class})."
158
172
  end
159
173
  end
174
+
175
+ def __check_new_def_name(name)
176
+ if name[0..1] == "__"
177
+ raise DefinitionError, "Name that starts with '__' is system-reserved."
178
+ end
179
+ if @forbidden_method_names.include?(name)
180
+ raise DefinitionError, "Name '#{name}' is already used as method name." +
181
+ "You should chanege to other name."
182
+ end
183
+ if @data_def[name]
184
+ raise DefinitionError, "Name #{name} is already defined." +
185
+ "You should change to other name."
186
+ end
187
+ end
188
+
189
+ def __name_resolvable?(name, structure=self)
190
+ return structure[name] ||
191
+ (structure.parent_structure && __name_resolvable?(name, structure.parent_structure))
192
+ end
160
193
  end
161
194
  end
data/lib/template_base.rb CHANGED
@@ -10,18 +10,7 @@ module BinaryParser
10
10
  end
11
11
 
12
12
  def self.def_var_method(name)
13
- define_method(name){|&block|
14
- if block
15
- case block.arity
16
- when 0
17
- @scope.load_var(name).instance_eval(&block)
18
- when 1
19
- block.call(@scope.load_var(name))
20
- end
21
- else
22
- @scope.load_var(name)
23
- end
24
- }
13
+ define_method(name){|&block| load(name, &block) }
25
14
  end
26
15
 
27
16
  def self.Def(parent_structure=nil, &definition_proc)
@@ -36,6 +25,19 @@ module BinaryParser
36
25
  @scope = Scope.new(self.class.structure, convert_into_abstract_binary(binary), parent_scope)
37
26
  end
38
27
 
28
+ def load(name, &block)
29
+ if block
30
+ case block.arity
31
+ when 0
32
+ @scope.load_var(name).instance_eval(&block)
33
+ when 1
34
+ block.call(@scope.load_var(name))
35
+ end
36
+ else
37
+ @scope.load_var(name)
38
+ end
39
+ end
40
+
39
41
  def convert_into_abstract_binary(object)
40
42
  return object if object.is_a?(AbstractBinary)
41
43
  if object.is_a?(String) && object.encoding == Encoding::BINARY
data/lib/while_list.rb ADDED
@@ -0,0 +1,31 @@
1
+ module BinaryParser
2
+ class WhileList < LoopList
3
+
4
+ attr_reader :bit_length
5
+
6
+ def initialize(definition, abstract_binary, parent_scope, name)
7
+ parsed_length = 0
8
+ list, rest_binary = [], abstract_binary
9
+ while continue?(definition, rest_binary, parent_scope, name)
10
+ template = definition.klass.new(rest_binary, parent_scope)
11
+ if template.structure_bit_length == 0
12
+ raise ParsingError, "0 bit-length repetition happens. This means infinite loop."
13
+ end
14
+ parsed_length += template.structure_bit_length
15
+ rest_binary = rest_binary.sub(:bit_index => template.structure_bit_length)
16
+ list << template
17
+ end
18
+ @list, @bit_length = list, parsed_length
19
+ end
20
+
21
+ def continue?(definition, rest_binary, parent_scope, name)
22
+ definition.loop_condition.eval do |token|
23
+ if token.nextbits_var?
24
+ TemplateBase.new(rest_binary.sub(:bit_length => token.length)).to_i
25
+ else
26
+ parent_scope.token_eval(token, name)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ $LIBRARY_ROOT_PATH = File.dirname(File.dirname(File.expand_path(File.dirname(__FILE__))))
3
+
4
+ module BinaryParser
5
+ module UnitTest
6
+ require 'test/unit'
7
+
8
+ # load testing target
9
+ require $LIBRARY_ROOT_PATH + '/lib/binary_parser.rb'
10
+
11
+ class BinaryTemplateTest < Test::Unit::TestCase
12
+
13
+ class TestingTemplate < TemplateBase
14
+ def_structure do
15
+ data :b1, Binary, 16
16
+ data :b2, Binary, 16
17
+ data :b3, Binary, 16
18
+ end
19
+ end
20
+
21
+ def test_data_method_block_call
22
+ t = gen(0x41, 0x42, 0x41, 0x42, 0, 0)
23
+
24
+ assert_equal(true, t.b1 == "AB")
25
+ assert_equal(false, t.b1 == "BA")
26
+
27
+ assert_equal(true, "AB" == t.b1)
28
+ assert_equal(false,"BA" == t.b1)
29
+
30
+ assert_equal(true, t.b1 == t.b2)
31
+ assert_equal(false, t.b1 == t.b3)
32
+ end
33
+
34
+ # helper for generating binary
35
+ def gen(*chars)
36
+ return TestingTemplate.new(chars.pack("C*"))
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,87 @@
1
+ # -*- coding: utf-8 -*-
2
+ $LIBRARY_ROOT_PATH = File.dirname(File.dirname(File.expand_path(File.dirname(__FILE__))))
3
+
4
+ module BinaryParser
5
+ module UnitTest
6
+ require 'test/unit'
7
+
8
+ # load testing target
9
+ require $LIBRARY_ROOT_PATH + '/lib/binary_parser.rb'
10
+
11
+ class UIntTemplateTest < Test::Unit::TestCase
12
+
13
+ class TestingTemplate < TemplateBase
14
+ def_structure do
15
+ data :n1, UInt, 8
16
+ data :n2, UInt, 8
17
+ data :n3, UInt, 8
18
+ end
19
+ end
20
+
21
+ def test_bit_access
22
+ t = gen(1, 2, 4)
23
+
24
+ assert_equal(1, t.n1[0])
25
+ assert_equal(0, t.n1[1])
26
+ assert_equal(0, t.n1[2])
27
+
28
+ assert_equal(0, t.n2[0])
29
+ assert_equal(1, t.n2[1])
30
+ assert_equal(0, t.n2[2])
31
+
32
+ assert_equal(0, t.n3[0])
33
+ assert_equal(0, t.n3[1])
34
+ assert_equal(1, t.n3[2])
35
+ end
36
+
37
+ def test_to_s
38
+ t = gen(10, 16, 0)
39
+
40
+ assert_equal("10", t.n1.to_s)
41
+ assert_equal("a", t.n1.to_s(16))
42
+ assert_equal("10", t.n2.to_s(16))
43
+ end
44
+
45
+ def test_operation
46
+ t = gen(2, 3, 3)
47
+
48
+ assert_equal(BuiltInTemplate::UInt, t.n1.class)
49
+
50
+ assert_equal(3, t.n1 + 1)
51
+ assert_equal(4, t.n1 * 2)
52
+ assert_equal(1, t.n1 - 1)
53
+ assert_equal(1, t.n1 / 2)
54
+ assert_equal(false, t.n1 == 1)
55
+ assert_equal(true, t.n1 == 2)
56
+ assert_equal(true, t.n1 != 1)
57
+ assert_equal(false, t.n1 != 2)
58
+ assert_equal(false, t.n1 < 1)
59
+ assert_equal(true, t.n1 > 1)
60
+
61
+ assert_equal(3, 1 + t.n1)
62
+ assert_equal(4, 2 * t.n1)
63
+ assert_equal(1, 3 - t.n1)
64
+ assert_equal(1, 2 / t.n1)
65
+ assert_equal(false, 1 == t.n1)
66
+ assert_equal(true, 2 == t.n1)
67
+ assert_equal(true, 1 != t.n1)
68
+ assert_equal(false, 2 != t.n1)
69
+ assert_equal(true, 1 < t.n1)
70
+ assert_equal(false, 1 > t.n1)
71
+
72
+ assert_equal(5, t.n1 + t.n2)
73
+ assert_equal(6, t.n1 * t.n2)
74
+ assert_equal(-1, t.n1 - t.n2)
75
+ assert_equal(0, t.n1 / t.n2)
76
+
77
+ assert_equal(false, t.n1 == t.n2)
78
+ assert_equal(true, t.n2 == t.n3)
79
+ end
80
+
81
+ # helper for generating binary
82
+ def gen(*chars)
83
+ return TestingTemplate.new(chars.pack("C*"))
84
+ end
85
+ end
86
+ end
87
+ end
@@ -14,7 +14,7 @@ module BinaryParser
14
14
 
15
15
  def test_bit_position
16
16
  bp = BitPosition.new
17
- pos = bp.add_imm(4).add_name(:hoge).add_imm(3).add_name(:fuga).eval{|name| VAL[name]}
17
+ pos = bp.add_imm(4).add_name(:hoge).add_imm(3).add_name(:fuga).eval{|token| VAL[token.symbol]}
18
18
  assert_equal(1017, pos)
19
19
  end
20
20
  end
@@ -15,8 +15,8 @@ module BinaryParser
15
15
  def test_condition
16
16
  cond1 = Condition.new(:hoge, :fuga){|v1, v2| v1 * 100 == v2}
17
17
  cond2 = Condition.new(:hoge, :fuga){|v1, v2| v1 * 10 == v2}
18
- assert_equal(true, cond1.eval{|name| VAL[name]})
19
- assert_equal(false, cond2.eval{|name| VAL[name]})
18
+ assert_equal(true, cond1.eval{|token| VAL[token.symbol]})
19
+ assert_equal(false, cond2.eval{|token| VAL[token.symbol]})
20
20
  end
21
21
  end
22
22
  end
@@ -9,13 +9,37 @@ module BinaryParser
9
9
  require $LIBRARY_ROOT_PATH + '/lib/binary_parser.rb'
10
10
 
11
11
  class ExpressionTest < Test::Unit::TestCase
12
- VAL = {:hoge => 10, :fuga => 1000}
12
+ VAL = {:a => 1, :b => 2, :c => 3, :d => 4}
13
+ LEN = {:a => 5, :b => 6, :c => 7, :d => 8}
14
+ CON = {:a => -1, :b => -2, :c => -3, :d => -4}
13
15
 
14
16
  def test_expression
15
- var_exp1 = Expression.new([:hoge])
16
- var_exp2 = Expression.new([:fuga])
17
- exp = (var_exp1 + 3) * 12 + var_exp2 / 10 - 4
18
- assert_equal((10 + 3) * 12 + 1000 / 10 - 4, exp.eval{|name| VAL[name]})
17
+ exp = (1 + val(:a)) * len(:b) + 2 * con(:c) - (3 % val(:d))
18
+ res = exp.eval do |token|
19
+ if token.value_var?
20
+ VAL[token.symbol]
21
+ elsif token.length_var?
22
+ LEN[token.symbol]
23
+ elsif token.control_var?
24
+ CON[token.symbol]
25
+ end
26
+ end
27
+
28
+ assert_equal((1 + 1) * 6 + 2 * -3 - (3 % 4), res)
29
+ end
30
+
31
+ # helpers
32
+
33
+ def val(symbol)
34
+ Expression.value_var(symbol)
35
+ end
36
+
37
+ def len(symbol)
38
+ Expression.length_var(symbol)
39
+ end
40
+
41
+ def con(symbol)
42
+ Expression.control_var(symbol)
19
43
  end
20
44
  end
21
45
  end
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ $LIBRARY_ROOT_PATH = File.dirname(File.dirname(File.expand_path(File.dirname(__FILE__))))
3
+
4
+ module BinaryParser
5
+ module UnitTest
6
+ require 'test/unit'
7
+
8
+ # load testing target
9
+ require $LIBRARY_ROOT_PATH + '/lib/binary_parser.rb'
10
+
11
+ class FreeConditionTest < Test::Unit::TestCase
12
+
13
+ def test_free_condition
14
+ cond1 = FreeCondition.new{ v1 * 100 == v2 }
15
+ assert_equal(true, cond1.eval{|token| {:v1 => 1, :v2 => 100}[token.symbol]})
16
+ assert_equal(false, cond1.eval{|token| {:v1 => 2, :v2 => 100}[token.symbol]})
17
+ end
18
+ end
19
+ end
20
+ end
@@ -213,6 +213,52 @@ module BinaryParser
213
213
  assert_equal("AB", i.rest_binary.to_s)
214
214
  end
215
215
 
216
+ # TEST CASE STRUCTURE 8
217
+ # * nextbits
218
+ class ST8 < TemplateBase
219
+ Def do
220
+ data :n1, UInt, nextbits(8) * 8
221
+ data :n2, UInt, 8
222
+ end
223
+ end
224
+
225
+ def test_ST8_CASE1
226
+ i = ST8.new(gen_bin(3, 0, 0, 1))
227
+ assert_equal(24, i.n1.binary_bit_length)
228
+ assert_equal(0x030000, i.n1)
229
+ assert_equal(1, i.n2)
230
+ end
231
+
232
+ # TEST CASE STRUCTURE 9
233
+ # * WHILE
234
+ class ST9 < TemplateBase
235
+ Def do
236
+ WHILE E{ nextbits(4) == 0xA }, :ls do
237
+ data :id, UInt, 8
238
+ end
239
+ data :suffix, UInt, 8
240
+ end
241
+ end
242
+
243
+ def test_ST9_CASE1
244
+ i = ST9.new(gen_bin(0xA1, 0xA2, 0xA3, 0xB4))
245
+
246
+ assert_equal(3, i.ls.length)
247
+ assert_equal(0xA1, i.ls[0].id)
248
+ assert_equal(0xA2, i.ls[1].id)
249
+ assert_equal(0xA3, i.ls[2].id)
250
+ assert_equal(0xB4, i.suffix)
251
+ assert_equal(4 * 8, i.structure_bit_length)
252
+ end
253
+
254
+ def test_ST9_CASE2
255
+ i = ST9.new(gen_bin(0xB0))
256
+
257
+ assert_equal(0, i.ls.length)
258
+ assert_equal(0xB0, i.suffix)
259
+ assert_equal(1 * 8, i.structure_bit_length)
260
+ end
261
+
216
262
  # helpers
217
263
  def gen_bin(*chars)
218
264
  return AbstractBinary.new(chars.pack("C*"))
@@ -28,11 +28,11 @@ module BinaryParser
28
28
 
29
29
  assert_equal(C2, st[:b].klass)
30
30
  assert_equal(3, st[:b].bit_position.eval{})
31
- assert_equal(24, st[:b].bit_length.eval{|name| {:a => 3}[name]})
31
+ assert_equal(24, st[:b].bit_length.eval{|token| {:a => 3}[token.symbol]})
32
32
  assert_equal([], st[:b].conditions)
33
33
 
34
34
  assert_equal(C3, st[:c].klass)
35
- assert_equal(27, st[:c].bit_position.eval{|name| {:b => 24}[name]})
35
+ assert_equal(27, st[:c].bit_position.eval{|token| {:b => 24}[token.symbol]})
36
36
  assert_equal(4, st[:c].bit_length.eval{})
37
37
  assert_equal([], st[:c].conditions)
38
38
  end
@@ -61,8 +61,8 @@ module BinaryParser
61
61
  end
62
62
 
63
63
  assert_equal(8, st[:list].bit_position.eval{})
64
- assert_equal(12, st[:list].bit_length.eval{|name| {:outer => 3}[name]})
65
- assert_equal(20, st[:foot].bit_position.eval{|name| {:list => 12}[name]})
64
+ assert_equal(12, st[:list].bit_length.eval{|token| {:outer => 3}[token.symbol]})
65
+ assert_equal(20, st[:foot].bit_position.eval{|token| {:list => 12}[token.symbol]})
66
66
  end
67
67
 
68
68
  def test_IF
@@ -89,8 +89,8 @@ module BinaryParser
89
89
  data :fuga, C1, 1
90
90
  end
91
91
 
92
- eval_proc = Proc.new do |var_name|
93
- {:hoge => 1, :fuga => 1}[var_name]
92
+ eval_proc = Proc.new do |token|
93
+ {:hoge => 1, :fuga => 1}[token.symbol]
94
94
  end
95
95
 
96
96
  cond1 = st.match(:hoge, 1)
@@ -134,6 +134,47 @@ module BinaryParser
134
134
  end
135
135
  end
136
136
  end
137
+
138
+ def test_E
139
+ st = StructureDefinition.new do
140
+ IF E{ hoge == 1 } do
141
+ data :fuga, C1, 8
142
+ end
143
+ end
144
+
145
+ assert_equal(true, st[:fuga].conditions[0].eval{|token| {:hoge => 1}[token.symbol]})
146
+ end
147
+
148
+ def test_ABBREVIATED_NOTATION
149
+ st = StructureDefinition.new do
150
+ d2 C2, 8
151
+ end
152
+
153
+ assert_equal(8, st[:d2].bit_length.eval{})
154
+ end
155
+
156
+ def test_VARIABLE_RESOLUTION
157
+ st = StructureDefinition.new do
158
+ data :a, C1, 3
159
+ data :b, C2, a * 8
160
+ data :c, C3, 4
161
+ end
162
+
163
+ assert_equal(C1, st[:a].klass)
164
+ assert_equal(0, st[:a].bit_position.eval{})
165
+ assert_equal(3, st[:a].bit_length.eval{})
166
+ assert_equal([], st[:a].conditions)
167
+
168
+ assert_equal(C2, st[:b].klass)
169
+ assert_equal(3, st[:b].bit_position.eval{})
170
+ assert_equal(24, st[:b].bit_length.eval{|token| {:a => 3}[token.symbol]})
171
+ assert_equal([], st[:b].conditions)
172
+
173
+ assert_equal(C3, st[:c].klass)
174
+ assert_equal(27, st[:c].bit_position.eval{|token| {:b => 24}[token.symbol]})
175
+ assert_equal(4, st[:c].bit_length.eval{})
176
+ assert_equal([], st[:c].conditions)
177
+ end
137
178
  end
138
179
  end
139
180
  end