class Archiverb::Ar
Private Instance Methods
next_header(io)
click to toggle source
# File lib/archiverb/ar.rb, line 28 def next_header(io) return nil if io.eof? io.read(1) if io.pos % 2 == 1 header = {} header[:name] = io.read(16) || (return nil) header[:name].strip! header[:mtime] = io.read(12) || (return nil) header[:uid] = io.read(6).to_i header[:gid] = io.read(6).to_i header[:mode] = io.read(8).to_i(8) header[:size] = io.read(10).to_i header[:magic] = io.read(2) raise InvalidFormat unless header[:magic] == "`\n" if header[:name][0..2] == "#1/" # bsd format extended file name header[:name] = io.read(header[:name][3..-1].to_i) header[:size] -= header[:name].length header[:name] = header[:name][0..-4] # @todo support gnu format for extended file name end header end
preprocess(io)
click to toggle source
# File lib/archiverb/ar.rb, line 51 def preprocess(io) raise InvalidFormat unless io.read(8) == "!<arch>\n" end
read_file(header, io)
click to toggle source
# File lib/archiverb/ar.rb, line 55 def read_file(header, io) io.read(header[:size]) end
write_to(io)
click to toggle source
# File lib/archiverb/ar.rb, line 8 def write_to(io) io.write("!<arch>\n") @files.each do |_, file| normal = [:name, :mtime, :uid, :gid, :mode].inject({}){|n,k| n.tap{ n[k] = file.send(k) } } normal[:mtime] = normal[:mtime].to_i normal[:raw] = file.read if normal[:name].length > 16 normal[:name] = "#1/#{file.name.length + 3}" normal[:raw] = "#{file.name}\0\0\0" + normal[:raw] normal[:size] = file.name.length + 3 end normal[:size] = normal[:raw].length printf(io, "%-16s%-12u%-6d%-6d%-8o%-10u`\n", *[:name, :mtime, :uid, :gid, :mode, :size].map{|k| normal[k]}) io.write(normal[:raw]) io.write("\n") if io.pos % 2 == 1 end io.close self end