135
|
1 # parsers.py - Python implementation of parsers.c
|
|
2 #
|
|
3 # Copyright 2009 Matt Mackall <mpm@selenic.com> and others
|
|
4 #
|
|
5 # This software may be used and distributed according to the terms of the
|
|
6 # GNU General Public License version 2, incorporated herein by reference.
|
|
7
|
160
|
8 from node import bin, nullid, nullrev
|
|
9 import util
|
135
|
10 import struct, zlib
|
|
11
|
|
12 _pack = struct.pack
|
|
13 _unpack = struct.unpack
|
|
14 _compress = zlib.compress
|
|
15 _decompress = zlib.decompress
|
|
16 _sha = util.sha1
|
|
17
|
|
18 def parse_manifest(mfdict, fdict, lines):
|
|
19 for l in lines.splitlines():
|
|
20 f, n = l.split('\0')
|
|
21 if len(n) > 40:
|
|
22 fdict[f] = n[40:]
|
|
23 mfdict[f] = bin(n[:40])
|
|
24 else:
|
|
25 mfdict[f] = bin(n)
|
|
26
|
|
27 def parse_index(data, inline):
|
|
28 def gettype(q):
|
|
29 return int(q & 0xFFFF)
|
|
30
|
|
31 def offset_type(offset, type):
|
|
32 return long(long(offset) << 16 | type)
|
|
33
|
|
34 indexformatng = ">Qiiiiii20s12x"
|
|
35
|
|
36 s = struct.calcsize(indexformatng)
|
|
37 index = []
|
|
38 cache = None
|
|
39 nodemap = {nullid: nullrev}
|
|
40 n = off = 0
|
|
41 # if we're not using lazymap, always read the whole index
|
|
42 l = len(data) - s
|
|
43 append = index.append
|
|
44 if inline:
|
|
45 cache = (0, data)
|
|
46 while off <= l:
|
|
47 e = _unpack(indexformatng, data[off:off + s])
|
|
48 nodemap[e[7]] = n
|
|
49 append(e)
|
|
50 n += 1
|
|
51 if e[1] < 0:
|
|
52 break
|
|
53 off += e[1] + s
|
|
54 else:
|
|
55 while off <= l:
|
|
56 e = _unpack(indexformatng, data[off:off + s])
|
|
57 nodemap[e[7]] = n
|
|
58 append(e)
|
|
59 n += 1
|
|
60 off += s
|
|
61
|
|
62 e = list(index[0])
|
|
63 type = gettype(e[0])
|
|
64 e[0] = offset_type(0, type)
|
|
65 index[0] = tuple(e)
|
|
66
|
|
67 # add the magic null revision at -1
|
|
68 index.append((0, 0, 0, -1, -1, -1, -1, nullid))
|
|
69
|
|
70 return index, nodemap, cache
|
|
71
|
|
72 def parse_dirstate(dmap, copymap, st):
|
|
73 parents = [st[:20], st[20: 40]]
|
|
74 # deref fields so they will be local in loop
|
|
75 format = ">cllll"
|
|
76 e_size = struct.calcsize(format)
|
|
77 pos1 = 40
|
|
78 l = len(st)
|
|
79
|
|
80 # the inner loop
|
|
81 while pos1 < l:
|
|
82 pos2 = pos1 + e_size
|
|
83 e = _unpack(">cllll", st[pos1:pos2]) # a literal here is faster
|
|
84 pos1 = pos2 + e[4]
|
|
85 f = st[pos2:pos1]
|
|
86 if '\0' in f:
|
|
87 f, c = f.split('\0')
|
|
88 copymap[f] = c
|
|
89 dmap[f] = e[:4]
|
|
90 return parents
|