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