mercurial/pure/parsers.py
changeset 29133 255274719dc1
parent 28861 86db5cb55d46
child 31220 37596c980662
equal deleted inserted replaced
29132:12769703d4ba 29133:255274719dc1
    23 # code outside this module should always use dirstatetuple.
    23 # code outside this module should always use dirstatetuple.
    24 def dirstatetuple(*x):
    24 def dirstatetuple(*x):
    25     # x is a tuple
    25     # x is a tuple
    26     return x
    26     return x
    27 
    27 
       
    28 indexformatng = ">Qiiiiii20s12x"
       
    29 indexfirst = struct.calcsize('Q')
       
    30 sizeint = struct.calcsize('i')
       
    31 indexsize = struct.calcsize(indexformatng)
       
    32 
       
    33 def gettype(q):
       
    34     return int(q & 0xFFFF)
       
    35 
       
    36 def offset_type(offset, type):
       
    37     return long(long(offset) << 16 | type)
       
    38 
       
    39 class BaseIndexObject(object):
       
    40     def __len__(self):
       
    41         return self._lgt + len(self._extra) + 1
       
    42 
       
    43     def insert(self, i, tup):
       
    44         assert i == -1
       
    45         self._extra.append(tup)
       
    46 
       
    47     def _fix_index(self, i):
       
    48         if not isinstance(i, int):
       
    49             raise TypeError("expecting int indexes")
       
    50         if i < 0:
       
    51             i = len(self) + i
       
    52         if i < 0 or i >= len(self):
       
    53             raise IndexError
       
    54         return i
       
    55 
       
    56     def __getitem__(self, i):
       
    57         i = self._fix_index(i)
       
    58         if i == len(self) - 1:
       
    59             return (0, 0, 0, -1, -1, -1, -1, nullid)
       
    60         if i >= self._lgt:
       
    61             return self._extra[i - self._lgt]
       
    62         index = self._calculate_index(i)
       
    63         r = struct.unpack(indexformatng, self._data[index:index + indexsize])
       
    64         if i == 0:
       
    65             e = list(r)
       
    66             type = gettype(e[0])
       
    67             e[0] = offset_type(0, type)
       
    68             return tuple(e)
       
    69         return r
       
    70 
       
    71 class IndexObject(BaseIndexObject):
       
    72     def __init__(self, data):
       
    73         assert len(data) % indexsize == 0
       
    74         self._data = data
       
    75         self._lgt = len(data) // indexsize
       
    76         self._extra = []
       
    77 
       
    78     def _calculate_index(self, i):
       
    79         return i * indexsize
       
    80 
       
    81     def __delitem__(self, i):
       
    82         if not isinstance(i, slice) or not i.stop == -1 or not i.step is None:
       
    83             raise ValueError("deleting slices only supports a:-1 with step 1")
       
    84         i = self._fix_index(i.start)
       
    85         if i < self._lgt:
       
    86             self._data = self._data[:i * indexsize]
       
    87             self._lgt = i
       
    88             self._extra = []
       
    89         else:
       
    90             self._extra = self._extra[:i - self._lgt]
       
    91 
       
    92 class InlinedIndexObject(BaseIndexObject):
       
    93     def __init__(self, data, inline=0):
       
    94         self._data = data
       
    95         self._lgt = self._inline_scan(None)
       
    96         self._inline_scan(self._lgt)
       
    97         self._extra = []
       
    98 
       
    99     def _inline_scan(self, lgt):
       
   100         off = 0
       
   101         if lgt is not None:
       
   102             self._offsets = [0] * lgt
       
   103         count = 0
       
   104         while off <= len(self._data) - indexsize:
       
   105             s, = struct.unpack('>i',
       
   106                 self._data[off + indexfirst:off + sizeint + indexfirst])
       
   107             if lgt is not None:
       
   108                 self._offsets[count] = off
       
   109             count += 1
       
   110             off += indexsize + s
       
   111         if off != len(self._data):
       
   112             raise ValueError("corrupted data")
       
   113         return count
       
   114 
       
   115     def __delitem__(self, i):
       
   116         if not isinstance(i, slice) or not i.stop == -1 or not i.step is None:
       
   117             raise ValueError("deleting slices only supports a:-1 with step 1")
       
   118         i = self._fix_index(i.start)
       
   119         if i < self._lgt:
       
   120             self._offsets = self._offsets[:i]
       
   121             self._lgt = i
       
   122             self._extra = []
       
   123         else:
       
   124             self._extra = self._extra[:i - self._lgt]
       
   125 
       
   126     def _calculate_index(self, i):
       
   127         return self._offsets[i]
       
   128 
    28 def parse_index2(data, inline):
   129 def parse_index2(data, inline):
    29     def gettype(q):
   130     if not inline:
    30         return int(q & 0xFFFF)
   131         return IndexObject(data), None
    31 
   132     return InlinedIndexObject(data, inline), (0, data)
    32     def offset_type(offset, type):
       
    33         return long(long(offset) << 16 | type)
       
    34 
       
    35     indexformatng = ">Qiiiiii20s12x"
       
    36 
       
    37     s = struct.calcsize(indexformatng)
       
    38     index = []
       
    39     cache = None
       
    40     off = 0
       
    41 
       
    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             append(e)
       
    49             if e[1] < 0:
       
    50                 break
       
    51             off += e[1] + s
       
    52     else:
       
    53         while off <= l:
       
    54             e = _unpack(indexformatng, data[off:off + s])
       
    55             append(e)
       
    56             off += s
       
    57 
       
    58     if off != len(data):
       
    59         raise ValueError('corrupt index file')
       
    60 
       
    61     if index:
       
    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, cache
       
    71 
   133 
    72 def parse_dirstate(dmap, copymap, st):
   134 def parse_dirstate(dmap, copymap, st):
    73     parents = [st[:20], st[20: 40]]
   135     parents = [st[:20], st[20: 40]]
    74     # dereference fields so they will be local in loop
   136     # dereference fields so they will be local in loop
    75     format = ">cllll"
   137     format = ">cllll"