def self.open_from_io(io, signer = nil, &block)
outputter = new(io)
metadata = nil
set_meta = lambda{|x| metadata = x}
raise "Want a block" unless block_given?
begin
data_sig, meta_sig = nil, nil
outputter.external_handle.add_file("data.tar.gz", 0644) do |inner|
begin
sio = signer ? StringIO.new : nil
os = Zlib::GzipWriter.new(sio || inner)
TarWriter.new(os) do |inner_tar_stream|
klass = class << inner_tar_stream; self end
klass.send(:define_method, :metadata=, &set_meta)
block.call inner_tar_stream
end
ensure
os.flush
os.finish
data_sig = nil
if signer
dgst_algo = Gem::Security::OPT[:dgst_algo]
dig = dgst_algo.digest(sio.string)
data_sig = signer.sign(dig)
inner.write(sio.string)
end
end
end
if data_sig
sig_file = 'data.tar.gz.sig'
outputter.external_handle.add_file(sig_file, 0644) do |os|
os.write(data_sig)
end
end
outputter.external_handle.add_file("metadata.gz", 0644) do |os|
begin
sio = signer ? StringIO.new : nil
gzos = Zlib::GzipWriter.new(sio || os)
gzos.write metadata
ensure
gzos.flush
gzos.finish
if signer
dgst_algo = Gem::Security::OPT[:dgst_algo]
dig = dgst_algo.digest(sio.string)
meta_sig = signer.sign(dig)
os.write(sio.string)
end
end
end
if meta_sig
sig_file = 'metadata.gz.sig'
outputter.external_handle.add_file(sig_file, 0644) do |os|
os.write(meta_sig)
end
end
ensure
outputter.close
end
nil
end