# HG changeset patch # User Martin Geisler # Date 2009-01-23 23:12:18 # Node ID f410c552fa15dca94f1e15b4bc525f11ad42949c # Parent fac054f84600424cb91675b6307ad88610f965cf pure Python implementation of parsers.c diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py new file mode 100644 --- /dev/null +++ b/mercurial/pure/parsers.py @@ -0,0 +1,81 @@ +# parsers.py - Python implementation of parsers.c +# +# Copyright 2009 Matt Mackall and others +# +# This software may be used and distributed according to the terms +# of the GNU General Public License, incorporated herein by reference. + +from node import bin, hex, nullid, nullrev +import revlog, dirstate, struct, util, zlib + +_pack = struct.pack +_unpack = struct.unpack +_compress = zlib.compress +_decompress = zlib.decompress +_sha = util.sha1 + +def parse_manifest(mfdict, fdict, lines): + for l in lines.splitlines(): + f, n = l.split('\0') + if len(n) > 40: + fdict[f] = n[40:] + mfdict[f] = bin(n[:40]) + else: + mfdict[f] = bin(n) + +def parse_index(data, inline): + indexformatng = revlog.indexformatng + s = struct.calcsize(indexformatng) + index = [] + cache = None + nodemap = {nullid: nullrev} + n = off = 0 + # if we're not using lazymap, always read the whole index + l = len(data) - s + append = index.append + if inline: + cache = (0, data) + while off <= l: + e = _unpack(indexformatng, data[off:off + s]) + nodemap[e[7]] = n + append(e) + n += 1 + if e[1] < 0: + break + off += e[1] + s + else: + while off <= l: + e = _unpack(indexformatng, data[off:off + s]) + nodemap[e[7]] = n + append(e) + n += 1 + off += s + + e = list(index[0]) + type = revlog.gettype(e[0]) + e[0] = revlog.offset_type(0, type) + index[0] = tuple(e) + + # add the magic null revision at -1 + index.append((0, 0, 0, -1, -1, -1, -1, nullid)) + + return index, nodemap, cache + +def parse_dirstate(dmap, copymap, st): + parents = [st[:20], st[20: 40]] + # deref fields so they will be local in loop + e_size = struct.calcsize(dirstate._format) + pos1 = 40 + l = len(st) + + # the inner loop + while pos1 < l: + pos2 = pos1 + e_size + e = _unpack(">cllll", st[pos1:pos2]) # a literal here is faster + pos1 = pos2 + e[4] + f = st[pos2:pos1] + if '\0' in f: + f, c = f.split('\0') + copymap[f] = c + dmap[f] = e[:4] + return parents