コード例 #1
0
    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]
コード例 #2
0
    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()