Read bytes from an IPC connection until we have a full frame.
(self, size: int = MAX_READ)
| 88 | return self.read_bytes(size).decode("utf-8") |
| 89 | |
| 90 | def read_bytes(self, size: int = MAX_READ) -> bytes: |
| 91 | """Read bytes from an IPC connection until we have a full frame.""" |
| 92 | if sys.platform == "win32": |
| 93 | while True: |
| 94 | # Check if we already have a message in the buffer before |
| 95 | # receiving any more data from the socket. |
| 96 | bdata = self.frame_from_buffer() |
| 97 | if bdata is not None: |
| 98 | break |
| 99 | |
| 100 | # Receive more data into the buffer. |
| 101 | ov, err = _winapi.ReadFile(self.connection, size, overlapped=True) |
| 102 | try: |
| 103 | if err == _winapi.ERROR_IO_PENDING: |
| 104 | timeout = int(self.timeout * 1000) if self.timeout else _winapi.INFINITE |
| 105 | res = _winapi.WaitForSingleObject(ov.event, timeout) |
| 106 | if res != _winapi.WAIT_OBJECT_0: |
| 107 | raise IPCException(f"Bad result from I/O wait: {res}") |
| 108 | except BaseException: |
| 109 | ov.cancel() |
| 110 | raise |
| 111 | _, err = ov.GetOverlappedResult(True) |
| 112 | more = ov.getbuffer() |
| 113 | if more: |
| 114 | self.buffer.extend(more) |
| 115 | bdata = self.frame_from_buffer() |
| 116 | if bdata is not None: |
| 117 | break |
| 118 | if err == 0: |
| 119 | # we are done! |
| 120 | break |
| 121 | elif err == _winapi.ERROR_MORE_DATA: |
| 122 | # read again |
| 123 | continue |
| 124 | elif err == _winapi.ERROR_OPERATION_ABORTED: |
| 125 | raise IPCException("ReadFile operation aborted.") |
| 126 | else: |
| 127 | while True: |
| 128 | # Check if we already have a message in the buffer before |
| 129 | # receiving any more data from the socket. |
| 130 | bdata = self.frame_from_buffer() |
| 131 | if bdata is not None: |
| 132 | break |
| 133 | |
| 134 | # Receive more data into the buffer. |
| 135 | more = self.connection.recv(size) |
| 136 | if not more: |
| 137 | # Connection closed |
| 138 | break |
| 139 | self.buffer.extend(more) |
| 140 | |
| 141 | if not bdata: |
| 142 | # Socket was empty, and we didn't get any frame. |
| 143 | # This should only happen if the socket was closed. |
| 144 | return b"" |
| 145 | return bdata |
| 146 | |
| 147 | def write(self, data: str) -> None: |
no test coverage detected