Je suis dans l'impossibilité de savoir quoi faire avec ce programme ; on m'a dit qu'il devait ouvrir un fichier .dat que j'ai ; mais je n'ai aucune idée de comment faire et quoi faire avec ce texte
#!/usr/bin/env ruby
require "default_versions"
require "fileutils"
require "pp"
require "esf_parser"
require "esf_semantic_parser"
require "xml_split"
require "pgm"
class Float
def pretty_single
rv = (((100_000.0 * self).round / 100_000.0) rescue self)
return rv if [self].pack("f") == [rv].pack("f")
self
end
end
class String
# Escape string for output as XML text (< > &)
def xml_escape
replacements = {"<" => "<", ">" => ">", "&" => "&" }
gsub(/([<>&])/) { replacements[$1] }
end
# Escape characters for output as XML attribute values (< > & ' ")
def xml_attr_escape
replacements = {"<" => "<", ">" => ">", "&" => "&", "\"" => """, "'" => "'"}
gsub(/([<>&\'\"])/) { replacements[$1] }
end
def to_hex_dump
unpack("H2" * size).join(" ")
end
def to_flt_dump
unpack("f*").map(&:pretty_single).join(" ")
end
def to_v2_dump
out = []
data = unpack("f*").map(&:pretty_single)
out << "#{data.shift},#{data.shift}" until data.empty?
out.join(" ")
end
def to_v3_dump
out = []
data = unpack("f*")
out << "#{data.shift},#{data.shift},#{data.shift}" until data.empty?
out.join(" ")
end
end
module EsfParserDebug
def progressbar_thread
Thread.new{
begin
puts "Done: %0.1f%%" % (100.0 * @ofs.to_f / @data.size)
5.times {
sleep 1
break if @done
}
end until @done
}
end
end
class EsfParser
include EsfBasicBinaryOps
include EsfDefaultConvert
include EsfParserDebug
include EsfGetData
include EsfSemantic
attr_accessor fs
attr_reader :data, ut_dir, :done
attr_reader :magic, :node_types
def save_binfile(base_name, semantic_name, ext, data)
path, rel_path = alloc_new_path(base_name, semantic_name, ext)
File.open(path, 'wb'){|fh| fh.write data}
rel_path
end
def alloc_new_path(base_name, semantic_name, ext)
alloc_key = [base_name, semantic_name, ext]
name = base_name
name += "-" unless name =~ /[-\/]\z/
name += "#{semantic_name}-" if semantic_name
while true
rel_path = "%s%04d%s" % [name, @path_allocator[alloc_key], ext]
path = File.join(out_dir, rel_path)
FileUtils.mkdir_p File.dirname(path)
return [path, rel_path] unless File.exist?(path)
@path_allocator[alloc_key] += 1
end
end
def open_xml(base_name, semantic_name)
return XMLPrinter.new(*alloc_new_path(base_name, semantic_name, ".xml"))
end
def initialize(in_fh, out_dir)
@data = in_fh.read
@out_dir = out_dir
@xmlout = XMLPrinter.new(File.join(out_dir, 'esf.xml'), 'esf.xml')
@ofs = 0
@path_allocator = Hash.new(1)
get_header
@esf_type_handlers = setup_esf_type_handlers
@esf_type_handlers_get = setup_esf_type_handlers_get
end
def setup_esf_type_handlers
out = Hash.new{|ht,node_type| raise "Unknown type 0x%02x at %d" % [node_type, ofs] }
(0..255).each{|i|
name = ("convert_%02x!" % i).to_sym
out[i] = name if respond_to?(name)
}
out
end
def setup_esf_type_handlers_get
out = Hash.new{|ht,node_type| raise "Unknown type 0x%02x at %d" % [node_type, ofs] }
(0..255).each{|i|
name = ("get_%02x!" % i).to_sym
out[i] = name if respond_to?(name)
}
out
end
def get_header
case magic = get_u4
when 0xABCD
@magic = [0xABCD]
when 0xABCE
a = get_u4
b = get_u4
raise "Incorrect ESF magic followup" unless a == 0
@magic = [0xABCE, a, b]
else
raise "Incorrect ESF magic: %X" % magic
end
with_temp_ofs(get_u4) {
@node_types = get_node_types
}
end
def get_node_types
(0...get_u2()).map{ get_ascii.to_sym }
end
def inspect
"EsfParser(#{@ofs})"
end
def get_node_type
@node_types[get_u2]
end
def convert_until_ofs!(ofs_end)
convert_value! while @ofs < ofs_end
end
def xml_nested(base_name)
if base_name
orig, nested = @xmlout, open_xml(base_name, lookahead_str)
begin
@xmlout = nested
yield
ensure
@xmlout = orig
nested.flush
end
@xmlout.tag!("xml_include", :path => nested.rel_path)
else
yield
end
end
def convert_rec!(node_type, version)
begin
save_ofs = @ofs
return send(ConvertSemanticRec[node_type]) if version.nil? && ConvertSemanticRec[node_type]
rescue SemanticFail
@ofs = save_ofs
end
xml_nested(XmlSplit[node_type]) do
@xmlout.tag!("rec", :type=>node_type, :version=>version) do
convert_until_ofs!(get_u4)
end
end
end
def convert_80!
node_type = get_node_type
version = get_byte
version = nil if version == DefaultVersions[node_type]
convert_rec!(node_type, version)
end
def convert_81!
node_type = get_node_type
version = get_byte
version = nil if version == DefaultVersions[node_type]
begin
save_ofs = @ofs
return send(ConvertSemanticAry[node_type]) if version.nil? && ConvertSemanticAry[node_type]
rescue SemanticFail
@ofs = save_ofs
end
ofs_end = get_u4
count = get_u4
if count == 0
@xmlout.tag!("ary", :type=>node_type, :version=>version)
else
@xmlout.tag!("ary", :type=>node_type, :version=>version) do
count.times do
convert_rec!(node_type, nil)
end
end
end
end
def convert_value!
send(@esf_type_handlers[get_byte])
end
def get_ofs_bytes
get_bytes(get_u4 - @ofs)
end
def convert!
@done = false
@xmlout.tag!("esf", :magic => @magic.join(" ")) do
@xmlout.tag!("node_types") do
node_types.each do |n|
@xmlout.tag!("node_type", :name => n)
end
end
convert_value!
end
@xmlout.flush
@done = true
end
end
class XMLPrinter
attr_reader ut_buf, ut_path, :rel_path
def initialize(out_path, rel_path)
@out_path = out_path
@rel_path = rel_path
@out_fh = File.open(out_path, 'wb')
@out_buf = ""
@stack = []
@indent = Hash.new{|ht,k| ht[k]=" "*k}
end
def flush
@out_fh.write @out_buf
@out_buf = ""
end
def tag!(name, *args)
raise ArgumentError.new("Too many arguments") if args.size > 2
attrs_s = ""
cnt = nil
if args.size == 2
attrs_s = attrs_to_s(args[0])
cnt = args[1]
elsif args.size == 1
if args[0].is_a?(Hash)
attrs_s = attrs_to_s(args[0])
else
cnt = args[0]
end
end
cnt = nil if cnt == ""
if block_given?
raise ArgumentError.new("Cannot use content argument and bolck at the same time") if cnt
out! "<#{name}#{attrs_s}>"
@stack << name
yield
@stack.pop
out! "</#{name}>"
elsif cnt.nil?
out! "<#{name}#{attrs_s}/>"
else
out! "<#{name}#{attrs_s}>#{cnt}</#{name}>"
end
end
def out!(str)
@out_buf << @indent[@stack.size] << str << "\n"
flush if @out_buf.size > 1_000_000
end
def out_ary!(tag, attrs, data)
if data.empty?
out! "<#{tag}#{attrs}/>"
else
out! "<#{tag}#{attrs}>"
data.each{|line| out! line}
out! "</#{tag}>"
end
end
private
def attrs_to_s(attrs={})
attrs.to_a.map{|k,v| v.nil? ? "" : " #{k}='#{v.to_s.xml_attr_escape}'"}.join
end
end
verbose = true
if ARGV[0] == "--quiet"
ARGV.shift
verbose = false
end
unless ARGV.size == 2
STDERR.puts <<EOF
Usage:
#{$0} input.esf output_dir
To hide progress bar:
#{$0} --quiet input.esf output_dir
EOF
exit 1
end
in_file = File.open(ARGV[0], 'rb')
out_dir = ARGV[1]
if File.exist?(out_dir)
STDERR.puts "#{out_dir} already exists"
exit 1
end
FileUtils.mkdir_p out_dir
esf = EsfParser.new(in_file, out_dir)
thr = esf.progressbar_thread if verbose
esf.convert!
- Si vous pouviez me dire qu'est ce que je suis sensé faire avec ce texte . En theorie c'est pour ouvrir et lire un fichier.
Après on m'a donné un autre texte pour en extraire le contenu.
merçi