Exemple #1
0
 def parse_value(bfr):
     ''' Unserialise a serialised Dirent.
 '''
     type_ = BSUInt.parse_value(bfr)
     flags = DirentFlags(BSUInt.parse_value(bfr))
     if flags & DirentFlags.HASNAME:
         flags ^= DirentFlags.HASNAME
         name = BSString.parse_value(bfr)
     else:
         name = ""
     if flags & DirentFlags.HASMETA:
         flags ^= DirentFlags.HASMETA
         metatext = BSString.parse_value(bfr)
     else:
         metatext = None
     uu = None
     if flags & DirentFlags.HASUUID:
         flags ^= DirentFlags.HASUUID
         uu = UUID(bytes=bfr.take(16))
     if flags & DirentFlags.NOBLOCK:
         flags ^= DirentFlags.NOBLOCK
         block = None
     else:
         block = BlockRecord.parse_value(bfr)
     if flags & DirentFlags.HASPREVDIRENT:
         flags ^= DirentFlags.HASPREVDIRENT
         prev_dirent_blockref = BlockRecord.parse_value(bfr)
     else:
         prev_dirent_blockref = None
     if flags & DirentFlags.EXTENDED:
         flags ^= DirentFlags.EXTENDED
         extended_data = BSData.parse_value(bfr)
     else:
         extended_data = None
     if flags:
         warning("%s.parse_value: unexpected extra flags: 0x%02x",
                 cls.__name__, flags)
     E = _Dirent.from_components(type_,
                                 name,
                                 meta=metatext,
                                 uuid=uu,
                                 block=block)
     E._prev_dirent_blockref = prev_dirent_blockref
     E.ingest_extended_data(extended_data)
     return E
Exemple #2
0
 def parse(cls, bfr):
     ''' Parse a `CompressibleDataRecord` from a buffer.
 '''
     flags = BSUInt.parse_value(bfr)
     data = BSData.parse_value(bfr)
     is_compressed = (flags & cls.FLAG_COMPRESSED) != 0
     if is_compressed:
         flags &= ~cls.FLAG_COMPRESSED
     if flags:
         raise ValueError("unsupported flags: 0x%02x" % (flags, ))
     return cls(_data=data, is_compressed=is_compressed)
Exemple #3
0
 def parse(cls, bfr):
     ''' Parse a packet from a buffer.
 '''
     raw_payload = BSData.parse_value(bfr)
     payload_bfr = CornuCopyBuffer([raw_payload])
     self = cls()
     # pylint: disable=attribute-defined-outside-init
     self.tag = BSUInt.parse_value(payload_bfr)
     flags = BSUInt.parse_value(payload_bfr)
     has_channel = (flags & 0x01) != 0
     self.is_request = (flags & 0x02) != 0
     flags >>= 2
     self.flags = flags
     if has_channel:
         self.channel = BSUInt.parse_value(payload_bfr)
     else:
         self.channel = 0
     if self.is_request:
         self.rq_type = BSUInt.parse_value(payload_bfr)
     self.payload = b''.join(payload_bfr)
     return self
Exemple #4
0
 def parse(cls, bfr, *, parse_flags):
     ''' Parse a HashCodesRequest from a buffer and construct.
 '''
     after = (parse_flags & 0x01) != 0
     has_start_hashcode = (parse_flags & 0x02) != 0
     extra_flags = parse_flags & ~0x03
     if extra_flags:
         raise ValueError("extra flags: 0x%02x" % (extra_flags, ))
     hashname = BSString.parse_value(bfr)
     hashclass = HashCode.by_index(hashname)
     if has_start_hashcode:
         start_hashcode = HashCodeField.parse_value(bfr)
         if type(start_hashcode) is not hashclass:  # pylint: disable=unidiomatic-typecheck
             raise ValueError(
                 "request hashclass %s does not match start_hashcode class %s"
                 % (hashclass, type(start_hashcode)))
     else:
         start_hashcode = None
     length = BSUInt.parse_value(bfr)
     return cls(after=after,
                hashclass=hashclass,
                start_hashcode=start_hashcode,
                length=length)
Exemple #5
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
Exemple #6
0
 def parse_value(bfr):
     ''' Decode a serialised hash from the CornuCopyBuffer `bfr`.
 '''
     hashenum = BSUInt.parse_value(bfr)
     hashcls = HASHCLASS_BY_ENUM[hashenum]
     return hashcls.from_hashbytes(bfr.take(hashcls.HASHLEN))