From 90dea6d415bfc5734bc87c2797b26cca311246bc Mon Sep 17 00:00:00 2001 From: scott Chacon Date: Tue, 20 Nov 2007 13:24:44 -0800 Subject: have the pure ruby bindings working to some degree --- lib/git/raw/internal/loose.rb | 138 ++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 67 deletions(-) (limited to 'lib/git/raw/internal/loose.rb') diff --git a/lib/git/raw/internal/loose.rb b/lib/git/raw/internal/loose.rb index 0e4020c..d8ec6fb 100644 --- a/lib/git/raw/internal/loose.rb +++ b/lib/git/raw/internal/loose.rb @@ -3,85 +3,89 @@ require 'digest/sha1' require 'git/raw/internal/object' -module Git module Raw module Internal - class LooseObjectError < StandardError - end +module Git + module Raw + module Internal + class LooseObjectError < StandardError + end - class LooseStorage - def initialize(directory) - @directory = directory - end + class LooseStorage + def initialize(directory) + @directory = directory + end - def [](sha1) - sha1 = sha1.unpack("H*")[0] + def [](sha1) + sha1 = sha1.unpack("H*")[0] - path = @directory+'/'+sha1[0...2]+'/'+sha1[2..40] - begin - get_raw_object(File.read(path)) - rescue Errno::ENOENT - nil - end - end + path = @directory+'/'+sha1[0...2]+'/'+sha1[2..40] + begin + get_raw_object(File.read(path)) + rescue Errno::ENOENT + nil + end + end - def get_raw_object(buf) - if buf.length < 2 - raise LooseObjectError, "object file too small" - end + def get_raw_object(buf) + if buf.length < 2 + raise LooseObjectError, "object file too small" + end - if legacy_loose_object?(buf) - content = Zlib::Inflate.inflate(buf) - header, content = content.split(/\0/, 2) - if !header || !content - raise LooseObjectError, "invalid object header" - end - type, size = header.split(/ /, 2) - if !%w(blob tree commit tag).include?(type) || size !~ /^\d+$/ - raise LooseObjectError, "invalid object header" + if legacy_loose_object?(buf) + content = Zlib::Inflate.inflate(buf) + header, content = content.split(/\0/, 2) + if !header || !content + raise LooseObjectError, "invalid object header" + end + type, size = header.split(/ /, 2) + if !%w(blob tree commit tag).include?(type) || size !~ /^\d+$/ + raise LooseObjectError, "invalid object header" + end + type = type.to_sym + size = size.to_i + else + type, size, used = unpack_object_header_gently(buf) + content = Zlib::Inflate.inflate(buf[used..-1]) + end + raise LooseObjectError, "size mismatch" if content.length != size + return RawObject.new(type, content) end - type = type.to_sym - size = size.to_i - else - type, size, used = unpack_object_header_gently(buf) - content = Zlib::Inflate.inflate(buf[used..-1]) - end - raise LooseObjectError, "size mismatch" if content.length != size - return RawObject.new(type, content) - end - # private - def unpack_object_header_gently(buf) - used = 0 - c = buf[used] - used += 1 + # private + def unpack_object_header_gently(buf) + used = 0 + c = buf[used] + used += 1 + + type = (c >> 4) & 7; + size = c & 15; + shift = 4; + while c & 0x80 != 0 + if buf.length <= used + raise LooseObjectError, "object file too short" + end + c = buf[used] + used += 1 - type = (c >> 4) & 7; - size = c & 15; - shift = 4; - while c & 0x80 != 0 - if buf.length <= used - raise LooseObjectError, "object file too short" + size += (c & 0x7f) << shift + shift += 7 + end + type = OBJ_TYPES[type] + if ![:blob, :tree, :commit, :tag].include?(type) + raise LooseObjectError, "invalid loose object type" + end + return [type, size, used] end - c = buf[used] - used += 1 + private :unpack_object_header_gently - size += (c & 0x7f) << shift - shift += 7 - end - type = OBJ_TYPES[type] - if ![:blob, :tree, :commit, :tag].include?(type) - raise LooseObjectError, "invalid loose object type" + def legacy_loose_object?(buf) + word = (buf[0] << 8) + buf[1] + buf[0] == 0x78 && word % 31 == 0 + end + private :legacy_loose_object? end - return [type, size, used] - end - private :unpack_object_header_gently - - def legacy_loose_object?(buf) - word = (buf[0] << 8) + buf[1] - buf[0] == 0x78 && word % 31 == 0 - end - private :legacy_loose_object? + end end -end end +end if $0 == __FILE__ require 'find' -- cgit