예제 #1
0
        def block_reader(buf: binwrapper.BinWrapper) -> Iterable[bytes]:
            while True:
                try:
                    block_type = buf.read_bytes(1)
                except BufferError:
                    # No more data blocks to read
                    return

                if block_type != b'D':
                    raise RuntimeError('cannot read the data block')

                block_hash = buf.read_bytes(20)
                block_bytes = buf.read_len32_prefixed_bytes()
                if hashlib.sha1(block_bytes).digest() != block_hash:
                    raise RuntimeError(
                        'dump integrity is compromised: data block '
                        'does not match the checksum')

                yield block_bytes
예제 #2
0
    def _parse(
        cls,
        desc: binwrapper.BinWrapper,
        codecs_list: typing.List[TypeDesc]
    ) -> typing.Optional[TypeDesc]:
        t = desc.read_bytes(1)
        tid = uuidgen.from_bytes(desc.read_bytes(16))

        if t == CTYPE_SET:
            pos = desc.read_ui16()
            return SetDesc(tid=tid, subtype=codecs_list[pos])

        elif t == CTYPE_SHAPE:
            els = desc.read_ui16()
            fields = {}
            flags = {}
            for _ in range(els):
                flag = desc.read_bytes(1)[0]
                name = desc.read_len32_prefixed_bytes().decode()
                pos = desc.read_ui16()
                fields[name] = codecs_list[pos]
                flags[name] = flag
            return ShapeDesc(tid=tid, flags=flags, fields=fields)

        elif t == CTYPE_BASE_SCALAR:
            return BaseScalarDesc(tid=tid)

        elif t == CTYPE_SCALAR:
            pos = desc.read_ui16()
            return ScalarDesc(tid=tid, subtype=codecs_list[pos])

        elif t == CTYPE_TUPLE:
            els = desc.read_ui16()
            fields = []
            for _ in range(els):
                pos = desc.read_ui16()
                fields.append(codecs_list[pos])
            return TupleDesc(tid=tid, fields=fields)

        elif t == CTYPE_NAMEDTUPLE:
            els = desc.read_ui16()
            fields = {}
            for _ in range(els):
                name = desc.read_len32_prefixed_bytes().decode()
                pos = desc.read_ui16()
                fields[name] = codecs_list[pos]
            return NamedTupleDesc(tid=tid, fields=fields)

        elif t == CTYPE_ENUM:
            els = desc.read_ui16()
            names = []
            for _ in range(els):
                name = desc.read_len32_prefixed_bytes().decode()
                names.append(name)
            return EnumDesc(tid=tid, names=names)

        elif t == CTYPE_ARRAY:
            pos = desc.read_ui16()
            els = desc.read_ui16()
            if els != 1:
                raise NotImplementedError(
                    'cannot handle arrays with more than one dimension')
            dim_len = desc.read_i32()
            return ArrayDesc(
                tid=tid, dim_len=dim_len, subtype=codecs_list[pos])

        elif (t >= 0xf0 and t <= 0xff):
            # Ignore all type annotations.
            desc.read_len32_prefixed_bytes()

        else:
            raise NotImplementedError(
                f'no codec implementation for EdgeDB data class {t}')
예제 #3
0
 def parse(self, buffer: binwrapper.BinWrapper) -> any:
     return buffer.read_bytes(16)