def handle_read(self, bytesToRead): # If no amount to read is given, read the whole file. # If we are asked to read a larger amount than the actual file # size, only read what is left of the actual file size. maxBytesToRead = int(os.path.getsize(self.name)) - self.offset if bytesToRead is None or maxBytesToRead < bytesToRead: bytesToRead = maxBytesToRead readBuffer = pythonapi.PyBuffer_New(bytesToRead) if readBuffer == 0: # This sould be a Python error. raise WinError() # Without access to the C structure associated with the buffer, we # have no other way of determining what address the allocated memory # we can use to read into starts at. readBufferPtr = c_void_p() ret = pythonapi.PyArg_ParseTuple(py_object((readBuffer, )), c_char_p("w"), byref(readBufferPtr)) if ret == 0: # This sould be a Python error. raise WinError() bytesRead = DWORD() ov = OVERLAPPED() ov.Offset = self.offset ov.channel = stackless.channel() self.ensure_iocp_association() ret = ReadFile(self.handle, readBufferPtr, bytesToRead, byref(bytesRead), byref(ov)) if ret == 0: # Error. if windll.kernel32.GetLastError() != ERROR_IO_PENDING: # This should raise. pythonapi.PyErr_SetExcFromWindowsErrWithFilename( py_object(IOError), 0, c_char_p(self.filename)) # Windows is processing our IO request and will get back to us. iocpMgr.RegisterChannelObject(self, ov.channel) ov.channel.receive() # Set the new file offset. self.offset += bytesToRead # We either got an immediate result, or our channel had notification # send that our buffer had been filled successfully. return readBuffer[:bytesToRead]
def handle_write(self, s): # UNTESTED AS OF YET. # Without access to the C structure associated with the buffer, we # have no other way of determining what the address of the given data # which we can use to write from is. writeBufferPtr = c_char_p() bytesToWrite = c_int() fmt = self.binary and "s#" or "t#" ret = pythonapi.PyArg_ParseTuple(py_object((s, )), c_char_p(fmt), byref(bPtr), byref(bLen)) if ret == 0: # This sould be a Python error. raise WinError() bytesWritten = DWORD() ov = OVERLAPPED() ov.Offset = self.offset ov.channel = stackless.channel() self.ensure_iocp_association() ret = WriteFile(self.handle, writeBufferPtr, bytesToWrite, byref(bytesWritten), byref(ov)) if ret == 0: # Error. if windll.kernel32.GetLastError() != ERROR_IO_PENDING: # This should raise. pythonapi.PyErr_SetExcFromWindowsErrWithFilename( py_object(IOError), 0, c_char_p(self.filename)) # Windows is processing our IO request and will get back to us. iocpMgr.RegisterChannelObject(self, ov.channel) ov.channel.receive() if bytesToWrite != bytesWritten.value: # This should raise. Same check as done in the actual file # object code. raise WinError()