Skip to content

Instantly share code, notes, and snippets.

@carllerche
Created April 11, 2010 23:50
Show Gist options
  • Save carllerche/363146 to your computer and use it in GitHub Desktop.
Save carllerche/363146 to your computer and use it in GitHub Desktop.
class Pack
def initialize(path)
@f = File.open(path, 'r')
end
end
class Index
def initialize(path)
File.open(path, 'r') do |f|
@f = f
# Check the magic number
raise unless f.read(4) == "\377tOc"
raise unless f.read(4).unpack("N") == [2]
# First read the fanout table
read_fanout
# Read in the table of SHA1 hashes
read_hashes
# Skip the CRC23 table
skip_crc23
# Read the offset for the hashes
read_offsets
# Read the file trailer
read_trailer
end
ensure
@f = nil
end
def inspect
# @fanout.inspect
str = ""
str << "OBJECTS\n"
str << "=======\n"
@hashes.each_with_index do |sha, i|
str << "#{sha} (#{@offsets[i]})\n"
end
str << "\n"
str << "TRAILER\n"
str << "=======\n"
str << " #{@pack_checksum}\n"
str << " #{@indx_checksum}\n"
str
end
def read_fanout
@fanout = (1..256).map { @f.read(4).unpack("N") }.flatten
end
def read_hashes
@hashes = (1..num_objects).map { read_sha }
end
def skip_crc23
@f.seek(crc23_len, IO::SEEK_CUR)
end
def read_offsets
@offsets = (1..num_objects).map { @f.read(4).unpack("N") }.flatten
end
def read_trailer
@pack_checksum = read_sha
@indx_checksum = read_sha
end
def read_sha
(1..5).map { @f.read(4).unpack("N").first.to_s(16) }.join
end
def crc23_len
4 * num_objects
end
def num_objects
@fanout.last
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment