Exemple #1
0
 def decode_block(self, data, size):
     if size > len(data):
         size = len(data)
     done = 0
     block = ContentBlock()
     while done < size:
         start = done
         if data[done] == 0xdd:
             cidlen, done = valuecodecs.parse_varuint(data, done+1)
             sumlen, done = valuecodecs.parse_varuint(data, done)
             cid = data[done:done+cidlen]
             cksum = data[done:done+sumlen]
             done += max(cidlen, sumlen)
             first = (
                 data[done] + data[done+1] * 0x100 +
                 data[done+2] * 0x10000 + data[done+3] * 0x1000000)
             done += 4
             last = (
                 data[done] + data[done+1] * 0x100 +
                 data[done+2] * 0x10000 + data[done+3] * 0x1000000)
             done += 4
             if last != first:
                 self._logger.warn('deprecated', 'item.last')
             item = ItemContent(cid, cksum, first)
             if done > size:
                 raise InvalidDataError(
                     'Content item overran block end at ' + str(done))
             while data[done] in (0xa0, 0xa1):
                 self._logger.warn('deprecated', 'item.update')
                 done += 1
                 checksum = None
                 if data[done-1] == 0xa1:
                     checksum = data[done:done+sumlen]
                     done += sumlen
                 first = (
                     data[done] + data[done+1] * 0x100 +
                     data[done+2] * 0x10000 + data[done+3] * 0x1000000)
                 done += 4
                 last = (
                     data[done] + data[done+1] * 0x100 +
                     data[done+2] * 0x10000 + data[done+3] * 0x1000000)
                 done += 4
             if done > size:
                 raise InvalidDataError(
                     'Content item overran block end at ' + str(done))
             block._items.append((data[start:done], item))
             block._datasize += done - start
         elif data[done] == 0:
             if data[done:size].strip(b'\x00'):
                 raise InvalidDataError('Trailing garbage')
             done = size
         else:
             raise InvalidDataError('Unknown data item: ' + str(data[done]))
     return block
Exemple #2
0
 def decode_block(self, data, size):
     if size > len(data):
         size = len(data)
     done = 0
     block = BackupBlock()
     while done < size:
         item = None
         start = done
         if data[done] in (0x90, 0x92):
             itemtype = data[done]
             done += 1
             dirid, done = valuecodecs.parse_varuint(data, done)
             parent, done = valuecodecs.parse_varuint(data, done)
             namelen, done = valuecodecs.parse_varuint(data, done)
             name = data[done:done+namelen]
             done += namelen
             item = ItemDirectory(dirid, parent, name)
             if itemtype == 0x92:
                 extra_data, done = valuecodecs.parse_varuint(data, done)
                 item.set_extra_data(extra_data)
             itemdata = data[start:done]
         elif data[done] in (0x91, 0x93, 0x94):
             itemtype = data[done]
             done += 1
             parent, done = valuecodecs.parse_varuint(data, done)
             namelen, done = valuecodecs.parse_varuint(data, done)
             name = data[done:done+namelen]
             done += namelen
             cidlen, done = valuecodecs.parse_varuint(data, done)
             cid = data[done:done+cidlen]
             done += cidlen
             filesize, done = valuecodecs.parse_varuint(data, done)
             mtime_year = data[done] + data[done+1] * 256
             mtime_second = (
                 data[done+2] + data[done+3] * 0x100 +
                 data[done+4] * 0x10000)
             if data[done+5] >= 0x80:
                 mtime_second += 0x1000000
             mtime_ns = (
                 (data[done+5] & 0x3f) + data[done+6] * 0x40 +
                 data[done+7] * 0x4000 + data[done+8] * 0x400000)
             done += 9
             if itemtype in (0x91, 0x93):
                 item = ItemFile(
                     parent, name, cid, filesize,
                     (mtime_year, mtime_second, mtime_ns))
             elif itemtype == 0x94:
                 ftype = self._filetypechars.get(data[done])
                 if ftype is None:
                     raise AssertionError(
                         'Unknown filetype: ' + str(data[done]))
                 done += 1
                 item = ItemSpecialFile(
                     ftype, parent, name, cid, filesize,
                     (mtime_year, mtime_second, mtime_ns))
             else:
                 raise AssertionError('unreachable')
             if itemtype in (0x93, 0x94):
                 extra, done = valuecodecs.parse_varuint(data, done)
                 item.set_extra_data(extra)
             itemdata = data[start:done]
         elif data[done] == 0x21:
             done += 1
             length, done = valuecodecs.parse_varuint(data, done)
             end = done + length
             kvid, done = valuecodecs.parse_varuint(data, done)
             kv = data[done:end]
             done = end
             key, value = kv.split(b':', 1)
             item = ItemKeyValue(kvid, key, value)
             itemdata = data[start:done]
         elif data[done] == 0x22:
             done += 1
             length, done = valuecodecs.parse_varuint(data, done)
             end = done + length
             xid, done = valuecodecs.parse_varuint(data, done)
             kvids = []
             while done < end:
                 kvid, done = valuecodecs.parse_varuint(data, done)
                 kvids.append(kvid)
             assert done == end
             item = ItemExtraDef(xid, tuple(kvids))
             itemdata = data[start:done]
         elif data[done] == 0:
             if data[done:size].strip(b'\x00'):
                 raise InvalidDataError('Trailing garbage')
             done = size
         else:
             raise InvalidDataError('Unknown data item')
         if item is not None:
             block._items.append((itemdata, item))
             block._datasize += len(itemdata)
     return block