xtm-utils/xtmfile/joiner.rb

90 lines
2.1 KiB
Ruby
Raw Normal View History

require 'xtmfile/header'
module XtmFile
class Joiner
attr_reader :header, :input_filename, :output_filename
# yield this event + filename when opening a new file
EVENT_OPENFILE = :file
# yield this event + percent on joining progress
EVENT_PROGRESS = :progress
BUFFER_MAX_SIZE = 4096 * 4096
def initialize input, output=nil
@input_filename = input
@output_filename = output
File.open @input_filename, "rb" do |in_xtm|
@header = Header::read in_xtm
end
if @output_filename.nil? then
@output_filename = @header.filename_str
end
end
def start &blk
in_xtm = File.open @input_filename, "rb"
in_xtm.seek @header.num_bytes, IO::SEEK_SET
yield EVENT_OPENFILE, @input_filename if block_given?
out_xtm = File.open @output_filename, "wb"
cur_xtm = @input_filename
is_first = true
cur_size = @header.filesize
print "\x1b[s"
while cur_size > 0 do
unless is_first then
cur_xtm = _nextfile cur_xtm
yield EVENT_OPENFILE, cur_xtm if block_given?
in_xtm = File.open cur_xtm, "rb"
end
while cur_size > 0 and (not in_xtm.eof?) do
pcent = (( @header.filesize - cur_size) * 100 / @header.filesize)
yield EVENT_PROGRESS, pcent if block_given?
read_size = if cur_size > BUFFER_MAX_SIZE then BUFFER_MAX_SIZE
else cur_size
end
buffer = in_xtm.read read_size
cur_size = cur_size - buffer.length
out_xtm.write buffer.slice(0, buffer.length)
end
is_first = false
in_xtm.close
end
out_xtm.close
# remaining files
end
def _nextfile curfile
result = nil
cur_idx = 0
cur_len = 0
case curfile
when /\.([0-9]+)\.xtm$/ then
cur_idx = $1.to_i
cur_len = $1.length
next_idx = cur_idx + 1
result = curfile.gsub(/\.([0-9]+)\.xtm$/, ".%0#{cur_len}d.xtm" % next_idx)
when /\.xtm\.([0-9]+)$/ then
cur_idx = $1.to_i
cur_len = $1.length
next_idx = cur_idx + 1
result = curfile.gsub(/\.xtm\.([0-9]+)$/, ".xtm.%0#{cur_len}d" % next_idx)
else
raise "Unable to detect a naming patterng for file sequence!"
end
return result
end
end
end