[pypy-svn] r62023 - in pypy/trunk/pypy: module/_winreg module/_winreg/test rlib

afa at codespeak.net afa at codespeak.net
Thu Feb 19 18:28:56 CET 2009


Author: afa
Date: Thu Feb 19 18:28:54 2009
New Revision: 62023

Modified:
   pypy/trunk/pypy/module/_winreg/__init__.py
   pypy/trunk/pypy/module/_winreg/interp_winreg.py
   pypy/trunk/pypy/module/_winreg/test/test_winreg.py
   pypy/trunk/pypy/rlib/rwinreg.py
Log:
winreg: add OpenKey and EnumValue


Modified: pypy/trunk/pypy/module/_winreg/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/_winreg/__init__.py	(original)
+++ pypy/trunk/pypy/module/_winreg/__init__.py	Thu Feb 19 18:28:54 2009
@@ -11,6 +11,9 @@
         'SetValueEx': 'interp_winreg.SetValueEx',
         'QueryValue': 'interp_winreg.QueryValue',
         'CreateKey': 'interp_winreg.CreateKey',
+        'OpenKey'     : 'interp_winreg.OpenKey',
+        'OpenKeyEx'   : 'interp_winreg.OpenKey',
+        'EnumValue'   : 'interp_winreg.EnumValue',
         'CloseKey': 'interp_winreg.CloseKey',
         'QueryInfoKey': 'interp_winreg.QueryInfoKey',
     }

Modified: pypy/trunk/pypy/module/_winreg/interp_winreg.py
==============================================================================
--- pypy/trunk/pypy/module/_winreg/interp_winreg.py	(original)
+++ pypy/trunk/pypy/module/_winreg/interp_winreg.py	Thu Feb 19 18:28:54 2009
@@ -182,6 +182,36 @@
     errstring = space.wrap("Could not convert the data to the specified type")
     raise OperationError(space.w_ValueError, errstring)
 
+def convert_from_regdata(space, buf, buflen, typ):
+    if typ == rwinreg.REG_DWORD:
+        if not buflen:
+            return 0
+        return rffi.cast(rwin32.LPDWORD, buf)[0]
+
+    elif typ == rwinreg.REG_SZ or typ == rwinreg.REG_EXPAND_SZ:
+        if not buflen:
+            return u""
+        return rffi.charp2strn(rffi.cast(rffi.CCHARP, buf), buflen)
+
+    elif typ == rwinreg.REG_MULTI_SZ:
+        if not buflen:
+            return []
+        i = 0
+        l = []
+        while i < buflen and buf[i]:
+            s = []
+            while i < buflen and buf[i] != '\0':
+                s.append(buf[i])
+                i += 1
+            if len(s) == 0:
+                break
+            l.append(''.join(s))
+            i += 1
+        return l
+
+    else: # REG_BINARY and all other types
+        return rffi.charpsize2str(buf, buflen)
+
 def SetValueEx(space, w_hkey, value_name, w_reserved, typ, w_value):
     hkey = hkey_w(w_hkey, space)
     buf, buflen = convert_to_regdata(space, w_value, typ)
@@ -189,6 +219,8 @@
         ret = rwinreg.RegSetValueEx(hkey, value_name, 0, typ, buf, buflen)
     finally:
         lltype.free(buf, flavor='raw')
+    if ret != 0:
+        raiseWindowsError(space, ret, 'RegSetValueEx')
 SetValueEx.unwrap_spec = [ObjSpace, W_Root, str, W_Root, int, W_Root]
 
 def CreateKey(space, w_hkey, subkey):
@@ -203,6 +235,70 @@
         lltype.free(rethkey, flavor='raw')
 CreateKey.unwrap_spec = [ObjSpace, W_Root, str]
 
+def OpenKey(space, w_hkey, subkey, res=0, sam=rwinreg.KEY_READ):
+    hkey = hkey_w(w_hkey, space)
+    rethkey = lltype.malloc(rwinreg.PHKEY.TO, 1, flavor='raw')
+    try:
+        ret = rwinreg.RegOpenKeyEx(hkey, subkey, res, sam, rethkey)
+        if ret != 0:
+            raiseWindowsError(space, ret, 'RegOpenKeyEx')
+        return space.wrap(W_HKEY(rethkey[0]))
+    finally:
+        lltype.free(rethkey, flavor='raw')
+OpenKey.unwrap_spec = [ObjSpace, W_Root, str, int, rffi.r_uint]
+
+def EnumValue(space, w_hkey, index):
+    hkey = hkey_w(w_hkey, space)
+    null_dword = lltype.nullptr(rwin32.LPDWORD.TO)
+
+    retValueSize = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')
+    try:
+        retDataSize = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')
+        try:
+            ret = rwinreg.RegQueryInfoKey(
+                hkey, None, null_dword, null_dword,
+                null_dword, null_dword, null_dword,
+                null_dword, retValueSize, retDataSize,
+                null_dword, lltype.nullptr(rwin32.PFILETIME.TO))
+            if ret != 0:
+                raiseWindowsError(space, ret, 'RegQueryInfoKey')
+            # include null terminators
+            retValueSize[0] += 1
+            retDataSize[0] += 1
+
+            valuebuf = lltype.malloc(rffi.CCHARP.TO, retValueSize[0],
+                                     flavor='raw')
+            try:
+                databuf = lltype.malloc(rffi.CCHARP.TO, retDataSize[0],
+                                        flavor='raw')
+                try:
+                    retType = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')
+                    try:
+                        ret = rwinreg.RegEnumValue(
+                            hkey, index, valuebuf, retValueSize,
+                            null_dword, retType, databuf, retDataSize)
+                        if ret != 0:
+                            raiseWindowsError(space, ret, 'RegEnumValue')
+
+                        return space.wrap((
+                            rffi.charp2str(valuebuf),
+                            convert_from_regdata(space, databuf,
+                                                 retDataSize[0], retType[0]),
+                            retType[0]
+                            ))
+                    finally:
+                        lltype.free(retType, flavor='raw')
+                finally:
+                    lltype.free(databuf, flavor='raw')
+            finally:
+                lltype.free(valuebuf, flavor='raw')
+        finally:
+            lltype.free(retDataSize, flavor='raw')
+    finally:
+        lltype.free(retValueSize, flavor='raw')
+
+EnumValue.unwrap_spec = [ObjSpace, W_Root, int]
+
 def QueryInfoKey(space, w_hkey):
     hkey = hkey_w(w_hkey, space)
     nSubKeys = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')

Modified: pypy/trunk/pypy/module/_winreg/test/test_winreg.py
==============================================================================
--- pypy/trunk/pypy/module/_winreg/test/test_winreg.py	(original)
+++ pypy/trunk/pypy/module/_winreg/test/test_winreg.py	Thu Feb 19 18:28:54 2009
@@ -25,6 +25,16 @@
         cls.w_root_key = space.wrap(cls.root_key)
         cls.w_test_key_name = space.wrap(cls.test_key_name)
 
+        test_data = [
+            ("Int Value", 45, _winreg.REG_DWORD),
+            ("Str Value", "A string Value", _winreg.REG_SZ),
+            ("Unicode Value", u"A unicode Value", _winreg.REG_SZ),
+            ("Str Expand", "The path is %path%", _winreg.REG_EXPAND_SZ),
+            ("Multi Str", ["Several", "string", u"values"], _winreg.REG_MULTI_SZ),
+            ("Raw data", "binary"+chr(0)+"data", _winreg.REG_BINARY),
+            ]
+        cls.w_test_data = space.wrap(test_data)
+
     def teardown_class(cls):
         import _winreg
         try:
@@ -71,18 +81,21 @@
 
     def test_SetValueEx(self):
         from _winreg import CreateKey, SetValueEx
-        from _winreg import REG_DWORD, REG_SZ, REG_EXPAND_SZ
-        from _winreg import REG_MULTI_SZ, REG_BINARY
         key = CreateKey(self.root_key, self.test_key_name)
-        SetValueEx(key, "Int Value", 0,
-                   REG_DWORD, 45)
-        SetValueEx(key, "Str Value", 0,
-                   REG_SZ, "A string Value")
-        SetValueEx(key, "Unicode Value", 0,
-                   REG_SZ, u"A unicode Value")
-        SetValueEx(key, "Str Expand", 0,
-                   REG_EXPAND_SZ, "The path is %path%")
-        SetValueEx(key, "Multi Str", 0,
-                   REG_MULTI_SZ, ["Several", "string", u"values"])
-        SetValueEx(key, "Raw data", 0,
-                   REG_BINARY, "binary"+chr(0)+"data")
+        sub_key = CreateKey(key, "sub_key")
+        for name, value, type in self.test_data:
+            SetValueEx(sub_key, name, 0, type, value)
+
+    def test_readValues(self):
+        from _winreg import OpenKey, EnumValue
+        key = OpenKey(self.root_key, self.test_key_name)
+        sub_key = OpenKey(key, "sub_key")
+        index = 0
+        while 1:
+            try:
+                data = EnumValue(sub_key, index)
+            except EnvironmentError, e:
+                break
+            assert data in self.test_data
+            index = index + 1
+        assert index == len(self.test_data)

Modified: pypy/trunk/pypy/rlib/rwinreg.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwinreg.py	(original)
+++ pypy/trunk/pypy/rlib/rwinreg.py	Thu Feb 19 18:28:54 2009
@@ -42,6 +42,7 @@
 
 HKEY = rwin32.HANDLE
 PHKEY = rffi.CArrayPtr(HKEY)
+REGSAM = rwin32.DWORD
 
 RegSetValue = external(
     'RegSetValueA',
@@ -61,7 +62,19 @@
 
 RegCreateKey = external(
     'RegCreateKeyA',
-    [rffi.LONG, rffi.CCHARP, PHKEY],
+    [HKEY, rffi.CCHARP, PHKEY],
+    rffi.LONG)
+
+RegOpenKeyEx = external(
+    'RegOpenKeyExA',
+    [HKEY, rffi.CCHARP, rwin32.DWORD, REGSAM, PHKEY],
+    rffi.LONG)
+
+RegEnumValue = external(
+    'RegEnumValueA',
+    [HKEY, rwin32.DWORD, rffi.CCHARP,
+     rwin32.LPDWORD, rwin32.LPDWORD, rwin32.LPDWORD,
+     rffi.CCHARP, rwin32.LPDWORD],
     rffi.LONG)
 
 RegQueryInfoKey = external(



More information about the Pypy-commit mailing list