Author: andrewjlawrence
Branch: winconsoleio
Changeset: r97496:d88f85fb9795
Date: 2019-09-16 16:52 +0100
http://bitbucket.org/pypy/pypy/changeset/d88f85fb9795/

Log:    Implemented write method for the Windows console io class.

diff --git a/pypy/module/_io/interp_win32consoleio.py 
b/pypy/module/_io/interp_win32consoleio.py
--- a/pypy/module/_io/interp_win32consoleio.py
+++ b/pypy/module/_io/interp_win32consoleio.py
@@ -119,8 +119,9 @@
         lltype.free(peek_count, flavor='raw')
 
 def _pyio_get_console_type(space, w_path_or_fd):
-    fd = space.int_w(w_path_or_fd)
-    if fd >= 0:
+
+    if space.isinstance_w(w_path_or_fd, space.w_int):
+        fd = space.int_w(w_path_or_fd)
         handle = rwin32.get_osfhandle(fd)
         if handle == rwin32.INVALID_HANDLE_VALUE:
             return '\0'
@@ -519,17 +520,73 @@
                              bytes[rn], bytes_size - rn, rffi.NULL, rffi.NULL)
                              
                 if not bytes_size:
+                    lltype.free(bytes, flavor='raw')
                     err = rwin32.GetLastError_saved()
                     raise WindowsError(err, "Failed to convert wide characters 
to multi byte string")
                     
                 bytes_size += rn
             
+            lltype.free(bytes, flavor='raw')
             w_bytes = space.charp2str(bytes)
             return space.newbytes(w_bytes)
             
         finally:
-            lltype.free(buf, flavor='raw')            
+            lltype.free(buf, flavor='raw')
+            lltype.free(n, flavor='raw')
 
+    def write_w(self, space, w_data):
+        buffer = space.charbuf_w(w_data)
+        n = lltype.malloc(rwin32.LPDWORD.TO, 0, flavor='raw')
+        
+        if self.handle == rwin32.INVALID_HANDLE_VALUE:
+            return err_closed(space)
+            
+        if not self.writable:
+            return err_mode("writing")
+            
+        if not len(buffer):
+            return 0
+            
+        if len(buffer) > BUFMAX:
+            buflen = BUFMAX
+        else:
+            buflen = len(buffer)
+        
+        wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer, buflen, 
rffi.NULL, 0)
+        
+        while wlen > (32766 / rffi.sizeof(rffi.CWCHARP.TO)):
+            buflen /= 2
+            wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer, 
buflen, rffi.NULL, 0)
+            
+        if not wlen:
+            lltype.free(n, flavor='raw')
+            raise WindowsError("Failed to convert bytes to wide characters")
+        
+        with lltype.scoped_alloc(rffi.CWCHARP, wlen) as wbuf:
+            wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer, 
buflen, wbuf, wlen)
+            if wlen:
+                res = rwin32.WriteConsoleW(self.handle, wbuf, wlen, n , 
rffi.NULL)
+                
+                if res and n < wlen:
+                    buflen = rwin32.WideCharToMultiByte(rwin32.CP_UTF8, 0, 
wbuf, n,
+                    rffi.NULL, 0, rffi.NULL, rffi.NULL)
+                
+                    if buflen:
+                        wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0, 
buffer,
+                        buflen, rffi.NULL, 0)
+                        assert len == wlen
+                        
+            else:
+                res = 0
+                
+            if not res:
+                err = rwin32.GetLastError_saved()
+                lltype.free(n, flavor='raw')
+                raise WindowsError(err, "Failed to convert multi byte string 
to wide characters")
+                
+            lltype.free(n, flavor='raw')
+            return space.newint(len)
+            
     def get_blksize(self,space):
         return space.newint(self.blksize)
         
@@ -545,6 +602,6 @@
     read     = interp2app(W_WinConsoleIO.read_w),
     readall  = interp2app(W_WinConsoleIO.readall_w),
     readinto = interp2app(W_WinConsoleIO.readinto_w),
-    
+    write = interp2app(W_WinConsoleIO.write_w),   
     _blksize = GetSetProperty(W_WinConsoleIO.get_blksize),
     )
diff --git a/pypy/module/_io/moduledef.py b/pypy/module/_io/moduledef.py
--- a/pypy/module/_io/moduledef.py
+++ b/pypy/module/_io/moduledef.py
@@ -23,7 +23,7 @@
         'BufferedRWPair': 'interp_bufferedio.W_BufferedRWPair',
         'BufferedRandom': 'interp_bufferedio.W_BufferedRandom',
         'TextIOWrapper': 'interp_textio.W_TextIOWrapper',
-        'WindowsConsoleIO': 'interp_win32consoleio.W_WinConsoleIO',
+        '_WindowsConsoleIO': 'interp_win32consoleio.W_WinConsoleIO',
 
         'open': 'interp_io.open',
         'IncrementalNewlineDecoder': 
'interp_textio.W_IncrementalNewlineDecoder',
diff --git a/pypy/module/_io/test/test_win32consoleio.py 
b/pypy/module/_io/test/test_win32consoleio.py
--- a/pypy/module/_io/test/test_win32consoleio.py
+++ b/pypy/module/_io/test/test_win32consoleio.py
@@ -9,4 +9,4 @@
 
     def test_constructor(self):
         import _io
-        t = _io.WindowsConsoleIO(u"CONIN$")
+        t = _io._WindowsConsoleIO(u"CONIN$")
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -583,11 +583,21 @@
     ERROR_INSUFFICIENT_BUFFER = 122
     ERROR_OPERATION_ABORTED   = 995
     CP_UTF8 = 65001 
+    
     WideCharToMultiByte = winexternal(
         'WideCharToMultiByte', [rffi.UINT, DWORD, rffi.CWCHARP, rffi.INT,
                                 LPSTR, rffi.INT, rffi.CCHARP, LPBOOL], 
rffi.INT,
         save_err=rffi.RFFI_SAVE_LASTERROR)
   
+    MultiByteToWideChar = winexternal(
+        'MultiByteToWideChar', [rffi.UINT, DWORD, rffi.CCHARP, rffi.INT,
+                                LPWSTR, rffi.INT], rffi.INT,
+        save_err=rffi.RFFI_SAVE_LASTERROR)
+  
     ReadConsoleW = winexternal(
         'ReadConsoleW', [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID], BOOL,
         save_err=rffi.RFFI_SAVE_LASTERROR)
+        
+    WriteConsoleW = winexternal(
+        'WriteConsoleW', [HANDLE, LPVOID, DWORD, LPDWORD, LPVOID], BOOL,
+        save_err=rffi.RFFI_SAVE_LASTERROR)
\ No newline at end of file
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to