[Stackless-checkins] r52352 - stackless/sandbox/libraries/slpmonkeypatch/resources/iocp.py

richard.tew python-checkins at python.org
Sun Oct 15 23:00:51 CEST 2006


Author: richard.tew
Date: Sun Oct 15 23:00:51 2006
New Revision: 52352

Modified:
   stackless/sandbox/libraries/slpmonkeypatch/resources/iocp.py
Log:
Some general fixes and also a correction of how the file reading works.  Fleshed out the file writing as well (still incomplete and untested though).

Modified: stackless/sandbox/libraries/slpmonkeypatch/resources/iocp.py
==============================================================================
--- stackless/sandbox/libraries/slpmonkeypatch/resources/iocp.py	(original)
+++ stackless/sandbox/libraries/slpmonkeypatch/resources/iocp.py	Sun Oct 15 23:00:51 2006
@@ -127,16 +127,10 @@
         completionKey = c_ulong()
         ovp = POINTER(OVERLAPPED)()
 
-        #import ctypes
-        #import ctypes.wintypes
-        #numBytes = ctypes.wintypes.DWORD()
-        #completionKey = ctypes.c_ulong()
-        #ovp = ctypes.wintypes.POINTER(OVERLAPPED)()
-
         while True:
             ret = GetQueuedCompletionStatus(self.handle, byref(numBytes), byref(completionKey), byref(ovp), 0)
             if ovp:
-                self.ForgetOverlappedReference(ovp.contents)
+                self.UnregisterChannelObject(ovp.contents)
             elif ret == 0:
                 break
 
@@ -194,15 +188,6 @@
 
 OPEN_ALWAYS             = 4
 
-# Local definitions:
-
-def GetBufferPtr(b):
-    bPtr = c_void_p()
-    ret = pythonapi.PyArg_ParseTuple(py_object((b,)), c_char_p("w"), byref(bPtr))
-    if ret == 0:
-        raise WinError()
-    return bPtr
-
 iocpMgr = IOCPManager()
 
 # TODO: This raises windows errors.  I probably need to go over each of them
@@ -215,6 +200,8 @@
         if not self.closed:
             self.close()
 
+        self.binary = 'b' in mode
+
         self.handle_open(filename, mode, buffering)
 
         self.name = filename
@@ -238,9 +225,6 @@
 
             self.handle_close()
 
-            del self.name
-            del self.mode
-            del self.offset
             del self.closed
 
     @uthread.with_instance_locking
@@ -281,10 +265,6 @@
 
 
 class FileObject(BaseFileObject):
-    def __init__(self, filename, mode=None, buffering=None):
-        if not self.closed:
-            self.close()
-
     def handle_open(self, filename, mode, buffering):
         flags = FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_OVERLAPPED
         access = GENERIC_READ
@@ -311,14 +291,25 @@
         del self.iocpLinked
 
     def handle_read(self, bytesToRead):
-        if bytesToRead is None:
-            bytesToRead = int(os.path.getsize(self.name))
+        # 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:
             raise WinError()
 
-        readBufferPtr = GetBufferPtr(readBuffer)
+        # 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:
+            raise WinError()
+
         bytesRead = DWORD()
         ov = OVERLAPPED()
         ov.Offset = self.offset
@@ -329,36 +320,55 @@
         if ret == 0:
             # Error.
             if windll.kernel32.GetLastError() != ERROR_IO_PENDING:
-                raise WinError()
+                # This should raise.
+                pythonapi.PyErr_SetFromErrno(py_object(IOError))
 
             # 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 str(readBuffer)
+        return readBuffer[:bytesToRead]
 
     def handle_write(self, s):
-        # TODO: NEEDS TO BE COMPLETED AND CORRECTED.
-        # BOOL = (HANDLE, c_void_p, DWORD, POINTER(DWORD), POINTER(OVERLAPPED))
-        bytesToWrite = len(data)
+        # 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:
+            raise WinError()
+
         bytesWritten = DWORD()
         ov = OVERLAPPED()
         ov.Offset = self.offset
         ov.channel = stackless.channel()
 
         self.ensure_iocp_association()
-        ret = WriteFile(self.handle, c_char_p(data), bytesToWrite, byref(bytesWritten), byref(ov))
+        ret = WriteFile(self.handle, writeBufferPtr, bytesToWrite, byref(bytesWritten), byref(ov))
         if ret == 0:
             # Error.
             if windll.kernel32.GetLastError() != ERROR_IO_PENDING:
-                raise WinError()
+                # This should raise.
+                pythonapi.PyErr_SetFromErrno(py_object(IOError))
 
             # 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.
+            pythonapi.PyErr_SetFromErrno(py_object(IOError))
+
     def handle_flush(self):
         pass
 

_______________________________________________
Stackless-checkins mailing list
Stackless-checkins at stackless.com
http://www.stackless.com/mailman/listinfo/stackless-checkins



More information about the Stackless-checkins mailing list