This repository has been archived by the owner on Nov 25, 2018. It is now read-only.
/
pack_object.rb
56 lines (47 loc) · 1.59 KB
/
pack_object.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
module Cryptosphere
module Git
# Pack objects represent data within Git. They are described in Git's
# documentation under:
#
# Documentation/technical/pack-format.txt
#
class PackObject
# Sanity limit on object header size. This provides 60-bits of length,
# or 1 exabyte of data. It is considered sufficient for today's purposes
HEADER_SANITY_LIMIT = 9
# Parse the header of a packed object, returning a streamable PackObject
# or nil if more data is needed to parse the object
#
# @param [String] buffer to be processed
# @return [PackObject, nil] PackObject or nil if more data is needed
def self.parse_header(buffer)
byte = buffer[0].ord
consumed = 1
more = byte >> 7 & 0x1
type = byte >> 4 & 0x7
length = byte & 0xf
while more == 1
raise FormatError, "object header too long" if consumed >= HEADER_SANITY_LIMIT
# Need more data
return nil if consumed >= buffer.length
byte = buffer[consumed].ord
more = byte >> 7 & 0x1
length += byte & 0x7f
consumed += 1
end
new(type, length, buffer)
end
attr_reader :type, :length
# Create a new streamable pack object
#
# @param [Fixnum] type of git pack object
# @param [Fixnum] length of pack object
# @return [PackObject] a new PackObject ready to stream
def initialize(type, length, buffer = "")
@type = type
@length = length
@buffer = buffer
end
end
end
end