require 'twiddler/config' module Twiddler class Parser def self.parse(data) version = *data.unpack("c") case version when 4 V4Parser.new(data, 1).go.parsed end end class V4Parser def initialize(raw, skipped = 0) @data = raw @refs = Hash.new{|h,k| h[k] = [:missing_ref]} bytes_hex @index = 0 consume("x" * skipped) bytes_hex @config = Config.new() end def parsed return @config end def consume(template) old_len = @data.length values = @data.unpack(template + "a*") @data = values.pop @index += old_len - @data.length return values end def bytes_hex(count = 8) "0x%04x:#{' %02x'*count}" % ([@index] + @data.unpack("c" * count)) end def go() total_size = @data.length + 1 @keyboard_chord_table, @mouse_chord_table, @multichar_table = *consume("vvv") @config.configs[:raw] = *consume("a#{@keyboard_chord_table - @index}") until @index >= @mouse_chord_table key1234, mod_or_ff, keyindex = consume("B16B8c") exit if @index > 685 if keyindex == 0 and key1234 == "0000000000000000" and mod_or_ff == "00000000" next end chord = Config::KeyChord.new chord.keydata = key1234 if(mod_or_ff == "11111111") @refs[keyindex] = chord else chord.add_keystroke(mod_or_ff, keyindex) end @config.keyboard << chord end while @index < @multichar_table key1234, data = consume("B16B8") if key1234 == "0000000000000000" and data == "00000000" next end chord_record = Config::MouseChord.new chord_record.keydata = key1234 chord_record.data = data @config.mouse << chord_record end data_idx = 0 until @data.size == 0 do data_size = *consume("v") chord_data = [] ((data_size-1)/2).times do mod, idx = *consume("B8c") next if idx == 0 #Not sure this is sufficient @refs[data_idx].add_keystroke(mod, idx) end data_idx += 1 end return self end end end end