Class: BinaryParser::Scope

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(structure_definition, abstract_binary, parent_scope = nil) ⇒ Scope

Returns a new instance of Scope.



6
7
8
9
10
11
# File 'lib/scope.rb', line 6

def initialize(structure_definition, abstract_binary, parent_scope=nil)
  @definition = structure_definition
  @abstract_binary = abstract_binary
  @parent_scope = parent_scope
  @data, @ebs, @ebl = {}, {}, {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



13
14
15
16
# File 'lib/scope.rb', line 13

def method_missing(name, *args)
  return load_var(name) if @definition[name]
  super
end

Instance Attribute Details

#abstract_binaryObject (readonly)

Returns the value of attribute abstract_binary.



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

def abstract_binary
  @abstract_binary
end

Instance Method Details

#bit_length_control_variable_resolution(name, var_name) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/scope.rb', line 82

def bit_length_control_variable_resolution(name, var_name)
  if var_name == :__rest
    length = @abstract_binary.bit_length - eval_bit_position(name)
    raise ParsingError, "Binary is too short. (So, 'rest' is failed.)" if length < 0
    return length
  elsif var_name == :__position
    return eval_bit_position(name)
  elsif var_name[0..6] == "__LEN__"
    return eval_bit_length(var_name[7..(var_name.length - 1)].to_sym)
  else
    raise ProgramAssertionError, "Unknown Control-Variable '#{var_name}'."
  end
end

#check_name_defined(name) ⇒ Object

Raises:



22
23
24
# File 'lib/scope.rb', line 22

def check_name_defined(name)
  raise UndefinedError, "Undefined data-name '#{name}'." unless @definition[name]
end

#eval_bit_length(name) ⇒ Object

  • memorized method (little obfuscated? : need refactoring?)



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/scope.rb', line 62

def eval_bit_length(name)
  check_name_defined(name)
  return @ebl[name] if @ebl[name]
  return @ebl[name] = 0 unless @definition[name].conditions.all? do |cond|
    cond.eval{|name| load_var(name)}
  end
  return @ebl[name] ||= @definition[name].bit_length.eval do |var_name|
    if var_name[0..1] == "__"
      bit_length_control_variable_resolution(name, var_name)
    else
      val = load_var(var_name)
      unless val
        raise ParsingError, "Variable '#{var_name}' assigned  to Nil is referenced" +
          "at the time of resolving bit_length of '#{var_name}'."
      end
      val.to_i
    end
  end
end

#eval_bit_position(name) ⇒ Object

  • memorized method (little obfuscated? : need refactoring?)



54
55
56
57
58
59
# File 'lib/scope.rb', line 54

def eval_bit_position(name)
  check_name_defined(name)
  return @ebs[name] ||= @definition[name].bit_position.eval do |name|
    eval_bit_length(name)
  end
end

#eval_entire_bit_lengthObject



96
97
98
99
100
# File 'lib/scope.rb', line 96

def eval_entire_bit_length
  return @definition.bit_at.eval do |name|
    eval_bit_length(name)
  end
end

#load_binary(name) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/scope.rb', line 41

def load_binary(name)
  check_name_defined(name)
  start  = eval_bit_position(name)
  length = eval_bit_length(name)
  begin
    return @abstract_binary.sub(:bit_index => start, :bit_length => length)
  rescue BadBinaryManipulationError => error
    raise ParsingError, "Cannot load binary of '#{name}'.\n" +
      "*** #{error.backtrace.first} ***\n#{error.message}\n"
  end
end

#load_var(name) ⇒ Object

  • Unsatisfactory memorized method (little obfuscated? : need refactoring?)



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/scope.rb', line 27

def load_var(name)
  return @parent_scope.load_var(name) if !@definition[name] && @parent_scope
  check_name_defined(name)
  case @definition[name]
  when StructureDefinition::DataDefinition
    return @data[name] ||= eval_bit_length(name) == 0 ? nil :
      @definition[name].klass.new(load_binary(name))
  when StructureDefinition::LoopDefinition
    return @data[name] ||= LoopList.new(@definition[name], load_binary(name), self)
  else
    raise ProgramAssertionError, "Unknown definition-class '#{@definition[name].class}'."
  end
end

#namesObject



18
19
20
# File 'lib/scope.rb', line 18

def names
  @definition.names.dup
end