Class: GitObjectBrowser::Models::PackIndex

Inherits:
Bindata
  • Object
show all
Defined in:
lib/git-object-browser/models/pack_index.rb

Overview

v2

signature   4bytes
version     4bytes
fanout      4bytes * 256
sha1       20bytes * fanout[255]
crc32       4bytes * fanout[255]
offset      4bytes * fanout[255]
pack  sha1 20bytes
index sha1 20bytes

Constant Summary collapse

PER_PAGE =
200

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Bindata

#binstr, #byte, #bytes, #find_char, #hex, #int, #peek, #raw, #seek, #skip, #switch_source

Constructor Details

#initialize(input) ⇒ PackIndex

Returns a new instance of PackIndex.



20
21
22
# File 'lib/git-object-browser/models/pack_index.rb', line 20

def initialize(input)
  super(input)
end

Instance Attribute Details

#entriesObject (readonly)

Returns the value of attribute entries.



16
17
18
# File 'lib/git-object-browser/models/pack_index.rb', line 16

def entries
  @entries
end

Class Method Details

.path?(relpath) ⇒ Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/git-object-browser/models/pack_index.rb', line 223

def self.path?(relpath)
  return relpath =~ %r{\Aobjects/pack/pack-[0-9a-f]{40}\.idx\z}
end

Instance Method Details

#empty?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/git-object-browser/models/pack_index.rb', line 52

def empty?
  @entries.empty?
end

#find(sha1_hex) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/git-object-browser/models/pack_index.rb', line 161

def find(sha1_hex)
  parse_fanout
  sha1 = [sha1_hex].pack("H*")
  fanout_idx = sha1.unpack("C").first

  lo = fanout_idx == 0 ? 0 : @fanout[fanout_idx - 1]
  hi = @fanout[fanout_idx]

  while lo < hi
    mid = (lo + hi) / 2
    mid_sha1 = get_sha1_raw(mid)
    if mid_sha1 == sha1
      return {
        :sha1   => sha1_hex,
        :crc32  => get_crc32_hex(mid),
        :offset => get_offset(mid)
      }
    elsif sha1 < mid_sha1
      hi = mid
    else
      lo = mid + 1
    end
  end
  nil
end

#get_crc32_hex(pos) ⇒ Object



205
206
207
208
209
210
211
212
# File 'lib/git-object-browser/models/pack_index.rb', line 205

def get_crc32_hex(pos)
  if @version == 2
    seek(4 + 4 + 4 * 256 + 20 * @fanout[255] + 4 * pos)
  else
    raise "FIXME version 1"
  end
  hex(4)
end

#get_offset(pos) ⇒ Object



214
215
216
217
218
219
220
221
# File 'lib/git-object-browser/models/pack_index.rb', line 214

def get_offset(pos)
  if @version == 2
    seek(4 + 4 + 4 * 256 + 20 * @fanout[255] + 4 * @fanout[255] + 4 * pos)
  else
    raise "FIXME version 1"
  end
  int
end

#get_sha1_hex(pos) ⇒ Object



196
197
198
199
200
201
202
203
# File 'lib/git-object-browser/models/pack_index.rb', line 196

def get_sha1_hex(pos)
  if @version == 2
    seek(4 + 4 + 4 * 256 + 20 * pos)
  else
    raise "FIXME version 1"
  end
  hex(20)
end

#get_sha1_raw(pos) ⇒ Object



187
188
189
190
191
192
193
194
# File 'lib/git-object-browser/models/pack_index.rb', line 187

def get_sha1_raw(pos)
  if @version == 2
    seek(4 + 4 + 4 * 256 + 20 * pos)
  else
    raise "FIXME version 1"
  end
  raw(20)
end

#load_object_types(input) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/git-object-browser/models/pack_index.rb', line 245

def load_object_types(input)
  obj = PackedObject.new(self, input)
  @entries.each do |entry|
    header = obj.parse_header(entry[:offset])
    if header[:type] == 'ofs_delta'
      obj.parse_ofs_delta_header(entry[:offset], header)
    elsif header[:type] == 'ref_delta'
      obj.parse_ref_delta_header(header)
    end
    entry.merge!(header)
  end
end

#page_dataObject

Extended pagenation data for Git Object Browser.



236
237
238
239
240
241
242
243
# File 'lib/git-object-browser/models/pack_index.rb', line 236

def page_data
  return {
    :per_page      => PER_PAGE,
    :entry_count   => @fanout[255],
    :page          => @page,
    :order         => @order
  }
end

#parse(order, page) ⇒ Object



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
# File 'lib/git-object-browser/models/pack_index.rb', line 24

def parse(order, page)
  parse_fanout
  @page = page
  @order = order

  if order == 'digest'
    parse_digest
  elsif order == 'sha1'
    parse_sha1_page
    set_fanouts
  else
    @order = 'offset'
    parse_offset_page
    set_fanouts
  end

  # XXX Doesn't support packfile >= 2 GiB
  # x.times do |i|
  #   puts "offset[#{ i }] = #{ hex(8) }"
  # end

  seek(4 + 4 + 4 * 256 + (20 + 4 + 4) * @fanout[255])
  @packfile_sha1 = hex(20)
  @index_sha1 = hex(20)

  self
end

#parse_fanoutObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/git-object-browser/models/pack_index.rb', line 144

def parse_fanout
  return if @fanout

  seek(0)
  signature = raw(4)
  signature_v2 = [255, 'tOc'].pack('Ca*')

  raise "FIXME" if signature != signature_v2
  @version = int
  raise "FIXME" if @version != 2

  @fanout = []
  256.times do |i|
    @fanout << int
  end
end

#to_hashObject



227
228
229
230
231
232
233
# File 'lib/git-object-browser/models/pack_index.rb', line 227

def to_hash
  return {
    :entries       => @entries,
    :packfile_sha1 => @packfile_sha1,
    :index_sha1    => @index_sha1,
  }
end