class BinaryParser::StructureDefinition
Constants
- DataDefinition
- KEYWORDS
- LoopDefinition
- WhileDefinition
Attributes
bit_at[R]
names[R]
parent_structure[R]
Public Class Methods
new(forbidden_method_names=[], parent_structure=nil, &init_proc)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 16 def initialize(forbidden_method_names=[], parent_structure=nil, &init_proc) @forbidden_method_names = forbidden_method_names @parent_structure = parent_structure @bit_at = BitPosition.new @data_def = {} @conditions, @names = [], [] Proxy.new(self, KEYWORDS).instance_eval(&init_proc) if init_proc end
Public Instance Methods
E(&condition_proc)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 93 def E(&condition_proc) return FreeCondition.new(&condition_proc) end
IF(condition, &block)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 78 def IF(condition, &block) @conditions.push(condition) block.call @conditions.pop end
SPEND(bit_length, name, klass=nil, &block)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 34 def SPEND(bit_length, name, klass=nil, &block) __check_new_def_name(name) bit_at, bit_length = __process_bit_length(bit_length, name) klass ||= NamelessTemplateMaker.new(self, block) define(name, LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass)) end
TIMES(times, name, klass=nil, &block)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 41 def TIMES(times, name, klass=nil, &block) __check_new_def_name(name) klass ||= NamelessTemplateMaker.new(self, block) structure = klass.structure if structure.bit_at.names.empty? bit_at, bit_length = __process_bit_length(times * structure.bit_at.imm, name) define(name, LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass)) else bit_length = Expression.immediate(0) structure.bit_at.names.each do |depending_token| depending_length_exp = structure[depending_token.symbol].bit_length depending_length_exp.variable_tokens.each do |token| if structure[token.symbol] raise DefinitionError, "In '#{name}', same level variable #{token.symbol} is referenced." + "*** TIMES's inner structure's bit-length must be always same." + "In other words, that bit-length must not rely on same level variables. ***" end end bit_length += depending_length_exp end bit_at, bit_length = __process_bit_length(bit_length * times, name) define(name, LoopDefinition.new(bit_at, bit_length, @conditions.dup, klass)) end end
WHILE(condition, name, &block)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 71 def WHILE(condition, name, &block) __check_new_def_name(name) klass = NamelessTemplateMaker.new(self, block) bit_at, bit_length = __process_bit_length(Expression.control_var(:non_fixed), name) define(name, WhileDefinition.new(bit_at, bit_length, @conditions.dup, klass, condition)) end
[](var_name)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 136 def [](var_name) return @data_def[var_name] end
cond(*var_names, &condition_proc)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 84 def cond(*var_names, &condition_proc) var_names.each do |var_name| unless __name_resolvable?(var_name) raise DefinitionError, "As condition variable, unsolvable variable #{var_name} is used." end end return Condition.new(*var_names, &condition_proc) end
data(name, klass, bit_length)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 25 def data(name, klass, bit_length) __check_new_def_name(name) unless klass.ancestors.include?(TemplateBase) raise DefinitionError, "Class #{klass} should be TemplateBase." end bit_at, bit_length = __process_bit_length(bit_length, name) define(name, DataDefinition.new(bit_at, bit_length, @conditions.dup, klass)) end
define(name, data)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 66 def define(name, data) @data_def[name] = data @names << name end
len(var_name)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 117 def len(var_name) unless __name_resolvable?(var_name) raise DefinitionError, "Unsolvable variable #{var_name} is used." end return Expression.length_var(var_name) end
match(var_name, value)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 97 def match(var_name, value) case value when Integer return cond(var_name){|v| v.to_i == value} when String return cond(var_name){|v| v.to_s == value} when Symbol return cond(var_name, value){|v1, v2| v1.to_i == v2.to_i} else raise DefinitionError, "Unknown type of matching value(#{value}) '#{value.class}'." end end
nextbits(length)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 124 def nextbits(length) return Expression.nextbits_var(length) end
position()
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 128 def position Expression.control_var(:position) end
rest()
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 132 def rest Expression.control_var(:rest) end
symbol_call(symbol, *args, &block)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 140 def symbol_call(symbol, *args, &block) if args.length == 0 return var(symbol) elsif args.length == 2 return data(symbol, *args) else raise DefinitionError, "Unknown use of keyword '#{var_name}' with args(#{args})." end end
var(var_name)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 110 def var(var_name) unless __name_resolvable?(var_name) raise DefinitionError, "Unsolvable variable #{var_name} is used." end return Expression.value_var(var_name) end
Private Instance Methods
__check_new_def_name(name)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 175 def __check_new_def_name(name) if name[0..1] == "__" raise DefinitionError, "Name that starts with '__' is system-reserved." end if @forbidden_method_names.include?(name) raise DefinitionError, "Name '#{name}' is already used as method name." + "You should chanege to other name." end if @data_def[name] raise DefinitionError, "Name #{name} is already defined." + "You should change to other name." end end
__name_resolvable?(name, structure=self)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 189 def __name_resolvable?(name, structure=self) return structure[name] || (structure.parent_structure && __name_resolvable?(name, structure.parent_structure)) end
__process_bit_length(bit_length, name)
click to toggle source
# File lib/binary_parser/structure_definition.rb, line 152 def __process_bit_length(bit_length, name) bit_at = @bit_at case bit_length when Integer if @conditions.empty? @bit_at = @bit_at.add_imm(bit_length) else @bit_at = @bit_at.add_name(name) end return bit_at, Expression.immediate(bit_length) when Expression bit_length.variable_tokens.each do |token| if (token.value_var? || token.length_var?) && !__name_resolvable?(token.symbol) raise DefinitionError, "In #{name}, unsolvable variable #{symbol} is used." end end @bit_at = @bit_at.add_name(name) return bit_at, bit_length else raise DefinitionError, "Unknown type of bit_length (#{bit_length.class})." end end