#!/usr/bin/env ruby exit(1) if ARGV[0].nil? class ModuleFile end class ModuleFragment attr_accessor :id, :module def initialize(id, module_file) @module = module_file @id = id end def is_last? @module.frag_count == id end def data @data ||= @module.data[offset_begin..offset_end] @data end def offset_begin @module.fragment_size * id end def offset_end off = @module.fragment_size * (id + 1) - 1 is_last? ? off + @module.last_frag_add : off end def module_id @module.id end def checksum i = 0 data.inject { |l, r| (l + r) % 256 } % checksum_modulo end def checksum_modulo module_id + 4 end def modulo checksum_modulo - (checksum % checksum_modulo) end def to_s(io) io << [module_id, id, modulo].pack("CCC") io << data.pack("C*") # TODO: add meta-data io.flush end def path "#{@module.path}.#{id}.frag" end end class ModuleFile attr_accessor :path, :frag_count, :id def initialize(path, frag_count, id) @path = path @frag_count = frag_count @id = id end def data @data ||= File.read(@path).bytes @data end def fragments @frag_count.times.map do |i| ModuleFragment.new(i, self) end end def fragment_size data.size / @frag_count end def last_frag_add fragment_size / @frag_count end end ARGV.each do |arg| m = ModuleFile.new(arg, 4, File.basename(arg).to_i) frags = m.fragments #p "path", frags.map(&:path) #p "checksum", frags.map(&:checksum) #p "modulo", frags.map(&:modulo) #p "checksum modulo", frags.map(&:checksum_modulo) #p "offset_begin", frags.map(&:offset_begin) #p "offset_end", frags.map(&:offset_end) #p frags.each do |frag| frag.to_s File.open(frag.path, "w") end #frags.each do |frag| # p File.open(frag.path, "r").read(6).unpack "CCC" #end end