class MingleEvents::ZipDirectory

Public Class Methods

new(name) click to toggle source
   # File lib/mingle_events/zip_directory.rb
 6 def initialize(name)
 7   FileUtils.mkdir_p(File.dirname(name))
 8   @root = name
 9   @entry_map = nil
10   @readio = nil
11 end

Public Instance Methods

close() click to toggle source
   # File lib/mingle_events/zip_directory.rb
44 def close
45   @readio.close if @readio
46   @readio = nil
47   @entry_map = nil
48 end
Also aliased as: reload
delete() click to toggle source
   # File lib/mingle_events/zip_directory.rb
39 def delete
40   close
41   FileUtils.rm_rf(@root)
42 end
exists?(path) click to toggle source
   # File lib/mingle_events/zip_directory.rb
34 def exists?(path)
35   return unless File.exist?(@root)
36   entry_map.include?(path)
37 end
file(path) { |entry_stream| ... } click to toggle source
   # File lib/mingle_events/zip_directory.rb
27 def file(path, &block)
28   measure("read file") do
29     raise FileNotExist, "File at '#{path}' in archive '#{@root}' dose not exisits" unless exists?(path)
30     entry_map[path].open { |entry_stream| yield(entry_stream) }
31   end
32 end
reload()
Alias for: close
write_file(path) { |io| ... } click to toggle source
   # File lib/mingle_events/zip_directory.rb
13 def write_file(path, &block)
14   measure('write_file') do
15     exists = File.exist?(@root) && File.lstat(@root).size > 1024
16     writeio = File.open(@root, exists ? 'r+b' : 'wb')
17     # for a existing tar, seek to -1024 from end to skip 1024 '\0' in tar format
18     writeio.seek(-1024, IO::SEEK_END) if exists
19 
20     Archive::Tar::Minitar::Output.open(writeio) do |output|
21       stat = {:mode => 0100644, :mtime => Time.now}
22       output.tar.add_file(path, stat) { |io, opts| yield(io) }
23     end
24   end
25 end

Private Instance Methods

entry_map() click to toggle source
   # File lib/mingle_events/zip_directory.rb
69 def entry_map
70   return @entry_map if @entry_map
71 
72   @entry_map = {}
73   measure("entries archive loading") do
74     @readio = File.open(@root, 'rb')
75     loop do
76       break if @readio.eof?
77 
78       header = Archive::Tar::PosixHeader.new_from_stream(@readio)
79       break if header.empty?
80 
81       entry = ReusableEntryStream.new(header, @readio)
82       size  = entry.size
83       @entry_map[entry.name] = entry
84 
85       skip = (512 - (size % 512)) % 512
86       @readio.seek(size - entry.bytes_read, IO::SEEK_CUR)
87       @readio.read(skip) # discard trailing zeros
88     end
89     @readio.rewind
90   end
91   @entry_map
92 end
measure(label=nil) { || ... } click to toggle source
   # File lib/mingle_events/zip_directory.rb
94 def measure(label=nil, &block)
95   return yield unless ENV['MINGLE_EVENTS_VERBOSE']
96   start = Time.now
97   yield.tap { puts "ZipDirectory##{label}: using #{Time.now - start}s"}
98 end