class TSparser::AribStringDecoder::Decoder
Class which is express decoding process. Receive all coding definition object when instance is maked.
Public Class Methods
new(caller, operator, set_map, proc_map, length_map, group_map, region_map, control_code_map)
click to toggle source
# File lib/arib_string_decoder.rb, line 175 def initialize(caller, operator, set_map, proc_map, length_map, group_map, region_map, control_code_map) @caller = caller @operator = operator @set_map = set_map @proc_map = proc_map @length_map = length_map @decoded = Decoded.new @outputer = CodeOutputer.new(proc_map, @decoded) @control_code_processor = ControlCodeProcessor.new(control_code_map, @decoded) @current_group_map = group_map.dup @current_region_map = region_map.dup @current_single_region_map = Hash.new end
Public Instance Methods
decode(binary)
click to toggle source
# File lib/arib_string_decoder.rb, line 189 def decode(binary) begin parse_one(binary) while binary.readable? rescue => error return @decoded if @decoded.to_s rescue nil parse_error(error, binary) end return @decoded end
output_code(byte, binary, target)
click to toggle source
# File lib/arib_string_decoder.rb, line 225 def output_code(byte, binary, target) code_name = query_code(target) if @length_map[code_name] == 1 byte &= 0x7F if target == :GR @outputer.output(code_name, byte) elsif @length_map[code_name] == 2 byte2 = binary.read_byte_as_binary(1) if target == :GR byte &= 0x7F byte2 &= 0x7F end @outputer.output(code_name, byte, byte2) else raise "Unsupported code length #{@length_map[code_name]} (from #{code_name})." end end
parse_control_code(byte, binary)
click to toggle source
# File lib/arib_string_decoder.rb, line 242 def parse_control_code(byte, binary) control_code = [byte] loop do caller_candidates = @caller.candidates(control_code) operator_candidates = @operator.candidates(control_code, @set_map) if caller_candidates == 0 && operator_candidates == 0 raise "Unacceptable control code (#{control_code})." end if caller_candidates == 1 && operator_candidates == 0 set_target(*@caller.pull(control_code)) break end if caller_candidates == 0 && operator_candidates == 1 set_code_set(*@operator.pull(control_code, @set_map)) break end unless binary.readable? raise "Binary is finished before accepting some operation code (now: #{control_code})." end control_code << binary.read_byte_as_binary(1) end end
parse_error(error, binary)
click to toggle source
# File lib/arib_string_decoder.rb, line 199 def parse_error(error, binary) STDERR.puts "Error occurred on the way to decode following bytes." STDERR.puts " \"#{binary.dump}\"" STDERR.puts "Now process pointer is pointing at #{binary.bit_pointer / 8}-th byte." begin STDERR.puts "Trying to print now decoded string..." STDERR.puts "Decoded: \"#{@decoded}\"" rescue STDERR.puts "Sorry, failed." end raise error end
parse_one(binary)
click to toggle source
# File lib/arib_string_decoder.rb, line 212 def parse_one(binary) byte = binary.read_byte_as_binary(1) if byte >= 0x21 && byte <= 0x7E output_code(byte, binary, :GL) elsif byte >= 0xA1 && byte <= 0xFE output_code(byte, binary, :GR) elsif @control_code_processor.match?(byte) @control_code_processor.process(byte, binary) else parse_control_code(byte, binary) end end
query_code(region)
click to toggle source
# File lib/arib_string_decoder.rb, line 280 def query_code(region) group_name = @current_single_region_map[region] || @current_region_map[region] unless group_name raise "No group is set to region \"#{region}\"." end code_name = @current_group_map[group_name] unless code_name raise "No code is set to group \"#{group_name}\"." end @current_single_region_map = Hash.new return code_name end
set_code_set(code_name, group_name)
click to toggle source
# File lib/arib_string_decoder.rb, line 276 def set_code_set(code_name, group_name) @current_group_map[group_name] = code_name end
set_target(group_name, target_region, call_type)
click to toggle source
# File lib/arib_string_decoder.rb, line 265 def set_target(group_name, target_region, call_type) case call_type when :locking @current_region_map[target_region] = group_name when :single @current_single_region_map[target_region] = group_name else raise "Unsupported call type \"#{call_type}\"." end end