Exemplo n.º 1
0
    def _parse(
        cls,
        desc: binwrapper.BinWrapper,
        codecs_list: typing.List[TypeDesc],
        protocol_version: tuple,
    ) -> 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 = {}
            cardinalities = {}
            for _ in range(els):
                if protocol_version >= (0, 11):
                    flag = desc.read_ui32()
                    cardinality = enums.Cardinality(desc.read_bytes(1)[0])
                else:
                    flag = desc.read_bytes(1)[0]
                    cardinality = None
                name = desc.read_len32_prefixed_bytes().decode()
                pos = desc.read_ui16()
                fields[name] = codecs_list[pos]
                flags[name] = flag
                if cardinality:
                    cardinalities[name] = cardinality
            return ShapeDesc(
                tid=tid,
                flags=flags,
                fields=fields,
                cardinalities=cardinalities,
            )

        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 >= 0x80 and t <= 0xff):
            # Ignore all type annotations.
            desc.read_len32_prefixed_bytes()
            return None

        else:
            raise NotImplementedError(
                f'no codec implementation for EdgeDB data class {t}')
Exemplo n.º 2
0
 def parse(self, buffer: binwrapper.BinWrapper) -> any:
     return buffer.read_ui32()