Example #1
0
def xattrs_from_bytes(bs, offset=0):
    ''' Decode an XAttrs from some bytes, return the xattrs dictionary.
  '''
    bfr = CornuCopyBuffer.from_bytes(bs)
    if offset > 0:
        bfr.skip(offset)
    xattrs = {}
    while not bfr.at_eof():
        name = BSString.parse_value(bfr)
        data = BSData.parse_value(bfr)
        if name in xattrs:
            warning("repeated name, ignored: %r", name)
        else:
            xattrs[name] = data
    return xattrs
Example #2
0
 def last(self):
     ''' The last Archive entry `(when,E)` or `(None,None)`.
 '''
     with Pfx("%s.last", self):
         try:
             flags, payload = self.S.do(
                 ArchiveLastRequest(self.archive_name))
         except StoreError as e:
             warning("%s, returning (None, None)", e)
             return ArchiveEntry(None, None)
         found = flags & 0x01
         if not found:
             return ArchiveEntry(None, None)
         bfr = CornuCopyBuffer.from_bytes(payload)
         entry = ArchiveEntry.from_buffer(bfr)
         return entry
Example #3
0
def selftest():
    ''' Run some self tests.
  '''
    # pylint: disable=import-outside-toplevel
    from cs.buffer import CornuCopyBuffer
    for n in (0, 1, 2, 3, 16, 17, 127, 128, 129, 32767, 32768, 32769, 65535,
              65536, 65537):
        bs = transcribe_length_encoded_value(n)
        bfr = CornuCopyBuffer.from_bytes(bs)
        n2 = get_length_encoded_value(bfr)
        assert n == n2, "n:%s != n2:%s" % (n, n2)
        assert bfr.offset == len(
            bs), "bfr.offset:%s != len(bs):%s" % (bfr.offset, len(bs))
        assert bfr.at_eof, "bfr not at EOF"
        ds, offset = DataSize.from_bytes(bs)
        assert ds.value == n
        assert offset == len(bs)
        bs2 = bytes(ds)
        assert bs == bs2
        ds2 = DataSize(n)
        bs3 = bytes(ds2)
        assert bs == bs3
Example #4
0
    def parse_value(bfr):
        ''' Decode a Block reference from a buffer.

        Format is a `BSData` holding this encoded data:

            BS(flags)
              0x01 indirect blockref
              0x02 typed: type follows, otherwise BT_HASHCODE
              0x04 type flags: per type flags follow type
            BS(span)
            [BS(type)]
            [BS(type_flags)]
            union {
              type BT_HASHCODE: hash
              type BT_RLE: octet-value (repeat span times to get data)
              type BT_LITERAL: raw-data (span bytes)
              type BT_SUBBLOCK: suboffset, super block
            }

        Even though this is all decodable without the leading length
        we use a leading length so that future encodings do not
        prevent parsing any following data.
    '''
        raw_encoding = BSData.parse_value(bfr)
        blockref_bfr = CornuCopyBuffer.from_bytes(raw_encoding)
        flags = BSUInt.parse_value(blockref_bfr)
        is_indirect = bool(flags & F_BLOCK_INDIRECT)
        is_typed = bool(flags & F_BLOCK_TYPED)
        has_type_flags = bool(flags & F_BLOCK_TYPE_FLAGS)
        unknown_flags = flags & ~(F_BLOCK_INDIRECT | F_BLOCK_TYPED
                                  | F_BLOCK_TYPE_FLAGS)
        if unknown_flags:
            raise ValueError(
                "unexpected flags value (0x%02x) with unsupported flags=0x%02x"
                % (flags, unknown_flags))
        span = BSUInt.parse_value(blockref_bfr)
        if is_indirect:
            # With indirect blocks, the span is of the implied data, not
            # the referenced block's data. Therefore we build the referenced
            # block with a span of None and store the span in the indirect
            # block.
            ispan = span
            span = None
        # block type, default BT_HASHCODE
        if is_typed:
            block_type = BlockType(BSUInt.parse_value(blockref_bfr))
        else:
            block_type = BlockType.BT_HASHCODE
        if has_type_flags:
            type_flags = BSUInt.parse_value(blockref_bfr)
            if type_flags:
                warning("nonzero type_flags: 0x%02x", type_flags)
        else:
            type_flags = 0x00
        # instantiate type specific block ref
        if block_type == BlockType.BT_HASHCODE:
            hashcode = HashCode.from_buffer(blockref_bfr)
            B = HashCodeBlock(hashcode=hashcode, span=span)
        elif block_type == BlockType.BT_RLE:
            octet = blockref_bfr.take(1)
            B = RLEBlock(span, octet)
        elif block_type == BlockType.BT_LITERAL:
            data = blockref_bfr.take(span)
            B = LiteralBlock(data)
        elif block_type == BlockType.BT_SUBBLOCK:
            suboffset = BSUInt.parse_value(blockref_bfr)
            superB = BlockRecord.parse_value(blockref_bfr)
            # wrap inner Block in subspan
            B = SubBlock(superB, suboffset, span)
        else:
            raise ValueError("unsupported Block type 0x%02x" % (block_type, ))
        if is_indirect:
            B = IndirectBlock(B, span=ispan)
        if not blockref_bfr.at_eof():
            warning("unparsed data (%d bytes) follow Block %s",
                    len(raw_encoding) - blockref_bfr.offset, B)
        assert isinstance(B, _Block)
        return B