Class: BinaryParser::Scope

Inherits:
Object
  • Object
show all
Defined in:
lib/binary_parser/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.



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

def initialize(structure_definition, abstract_binary, parent_scope=nil)
  @definition = structure_definition
  @abstract_binary = abstract_binary
  @parent_scope = parent_scope
end

Instance Attribute Details

#abstract_binaryObject (readonly)

Returns the value of attribute abstract_binary.



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

def abstract_binary
  @abstract_binary
end

Instance Method Details

#bit_length_control_variable_resolution(name, symbol) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/binary_parser/scope.rb', line 93

def bit_length_control_variable_resolution(name, symbol)
  if symbol == :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 symbol == :position
    return eval_bit_position(name)
  elsif symbol == :non_fixed
    return load_var(name).bit_length
  else
    raise ProgramAssertionError, "Unknown Control-Variable '#{symbol}'."
  end
end

#check_name_defined(name) ⇒ Object

Raises:



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

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

#eval(target, name) ⇒ Object



71
72
73
74
75
# File 'lib/binary_parser/scope.rb', line 71

def eval(target, name)
  target.eval do |token|
    token_eval(token, name)
  end
end

#eval_bit_length(name) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/binary_parser/scope.rb', line 59

def eval_bit_length(name)
  check_name_defined(name)
  unless @definition[name].conditions.all?{|cond| eval(cond, name)}
    return 0
  end
  return eval(@definition[name].bit_length, name).to_i
end

#eval_bit_position(name) ⇒ Object



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

def eval_bit_position(name)
  check_name_defined(name)
  return eval(@definition[name].bit_position, nil)
end

#eval_entire_bit_lengthObject



67
68
69
# File 'lib/binary_parser/scope.rb', line 67

def eval_entire_bit_length
  eval(@definition.bit_at, nil)
end

#load_binary(name) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/binary_parser/scope.rb', line 37

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



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/binary_parser/scope.rb', line 21

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
    eval_bit_length(name) == 0 ? nil : @definition[name].klass.new(load_binary(name))
  when StructureDefinition::LoopDefinition
    LoopList.new(@definition[name], load_binary(name), self)
  when StructureDefinition::WhileDefinition
    sub_binary = @abstract_binary.sub(:bit_index => eval_bit_position(name))
    WhileList.new(@definition[name], sub_binary, self, name)
  else
    raise ProgramAssertionError, "Unknown definition-class '#{@definition[name].class}'."
  end
end

#namesObject



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

def names
  @definition.names.dup
end

#preview_as_integer(start_pos, length) ⇒ Object



49
50
51
52
# File 'lib/binary_parser/scope.rb', line 49

def preview_as_integer(start_pos, length)
  sub_binary = @abstract_binary.sub(:bit_index => start_pos, :bit_length => length)
  TemplateBase.new(sub_binary).to_i
end

#token_eval(token, name) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/binary_parser/scope.rb', line 77

def token_eval(token, name)
  if token.control_var?
    bit_length_control_variable_resolution(name, token.symbol)
  elsif token.nextbits_var?
    preview_as_integer(eval_bit_position(name), token.length)
  elsif token.length_var?
    eval_bit_length(token.symbol)
  elsif token.value_var?
    unless val = load_var(token.symbol)
      raise ParsingError, "Variable '#{token.symbol}' assigned  to Nil is referenced" +
        "at the time of resolving '#{name}'."
    end
    val
  end
end