async def read_response(self, initial_connect=False): try: raw_size = await self.reader.readexactly(size_struct.size) except asyncio.IncompleteReadError: raise ConnectionAbortedError size = size_struct.unpack(raw_size)[0] # connect and close op replies don't contain a reply header if initial_connect or self.pending_specials[protocol.CLOSE_XID]: raw_payload = await self._read(size) response = protocol.ConnectResponse.deserialize(raw_payload) return (None, None, response) raw_header = await self._read(reply_header_struct.size) xid, zxid, error_code = reply_header_struct.unpack_from(raw_header) if error_code: self.opcode_xref.pop(xid) return (xid, zxid, exc.get_response_error(error_code)) size -= reply_header_struct.size raw_payload = await self._read(size) if xid == protocol.WATCH_XID: response = protocol.WatchEvent.deserialize(raw_payload) else: opcode = self.opcode_xref.pop(xid) response = protocol.response_xref[opcode].deserialize(raw_payload) return (xid, zxid, response)
def deserialize(cls, raw_bytes): instance = cls() header, offset = MultiHeader.parse(raw_bytes, 0) while not header.done: if header.type == -1: error_code = error_struct.unpack_from(raw_bytes, offset)[0] offset += error_struct.size instance.responses.append(exc.get_response_error(error_code)) header, offset = MultiHeader.parse(raw_bytes, offset) continue response_class = response_xref[header.type] response, offset = response_class.parse(raw_bytes, offset) instance.responses.append(response) header, offset = MultiHeader.parse(raw_bytes, offset) return instance