def read_val(inbuf, ttype, spec=None, decode_response=True):
    if ttype == TType.BOOL:
        return bool(unpack_i8(inbuf.read(1)))

    elif ttype == TType.BYTE:
        return unpack_i8(inbuf.read(1))

    elif ttype == TType.I16:
        return unpack_i16(inbuf.read(2))

    elif ttype == TType.I32:
        return unpack_i32(inbuf.read(4))

    elif ttype == TType.I64:
        return unpack_i64(inbuf.read(8))

    elif ttype == TType.DOUBLE:
        return unpack_double(inbuf.read(8))

    elif ttype == TType.STRING:
        sz = unpack_i32(inbuf.read(4))
        byte_payload = inbuf.read(sz)

        # Since we cannot tell if we're getting STRING or BINARY
        # if not asked not to decode, try both
        if decode_response:
            try:
                return byte_payload.decode('utf-8')
            except __HOLE__:
                pass
        return byte_payload

    elif ttype == TType.SET or ttype == TType.LIST:
        if isinstance(spec, tuple):
            v_type, v_spec = spec[0], spec[1]
        else:
            v_type, v_spec = spec, None

        result = []
        r_type, sz = read_list_begin(inbuf)
        # the v_type is useless here since we already get it from spec
        if r_type != v_type:
            for _ in range(sz):
                skip(inbuf, r_type)
            return []

        for i in range(sz):
            result.append(read_val(inbuf, v_type, v_spec, decode_response))
        return result

    elif ttype == TType.MAP:
        if isinstance(spec[0], int):
            k_type = spec[0]
            k_spec = None
        else:
            k_type, k_spec = spec[0]

        if isinstance(spec[1], int):
            v_type = spec[1]
            v_spec = None
        else:
            v_type, v_spec = spec[1]

        result = {}
        sk_type, sv_type, sz = read_map_begin(inbuf)
        if sk_type != k_type or sv_type != v_type:
            for _ in range(sz):
                skip(inbuf, sk_type)
                skip(inbuf, sv_type)
            return {}

        for i in range(sz):
            k_val = read_val(inbuf, k_type, k_spec, decode_response)
            v_val = read_val(inbuf, v_type, v_spec, decode_response)
            result[k_val] = v_val

        return result

    elif ttype == TType.STRUCT:
        obj = spec()
        read_struct(inbuf, obj, decode_response)
        return obj
dataset/ETHPy150Open eleme/thriftpy/thriftpy/protocol/binary.py/read_val