def EnumKey(space, w_hkey, index): """string = EnumKey(key, index) - Enumerates subkeys of an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. index is an integer that identifies the index of the key to retrieve. The function retrieves the name of one subkey each time it is called. It is typically called repeatedly until an EnvironmentError exception is raised, indicating no more values are available.""" hkey = hkey_w(w_hkey, space) null_dword = lltype.nullptr(rwin32.LPDWORD.TO) # The Windows docs claim that the max key name length is 255 # characters, plus a terminating nul character. However, # empirical testing demonstrates that it is possible to # create a 256 character key that is missing the terminating # nul. RegEnumKeyEx requires a 257 character buffer to # retrieve such a key name. with lltype.scoped_alloc(rffi.CCHARP.TO, 257) as buf: with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retValueSize: retValueSize[0] = r_uint(257) # includes NULL terminator ret = rwinreg.RegEnumKeyExW(hkey, index, buf, retValueSize, null_dword, None, null_dword, lltype.nullptr(rwin32.PFILETIME.TO)) if ret != 0: raiseWindowsError(space, ret, 'RegEnumKeyEx') return space.newunicode( rffi.wcharp2unicode(rffi.cast(rffi.CWCHARP, buf)))
def string(self, cdataobj, maxlen): space = self.space if isinstance(self.ctitem, ctypeprim.W_CTypePrimitive): cdata = cdataobj._cdata if not cdata: raise operationerrfmt(space.w_RuntimeError, "cannot use string() on %s", space.str_w(cdataobj.repr())) # from pypy.module._cffi_backend import ctypearray length = maxlen if length < 0 and isinstance(self, ctypearray.W_CTypeArray): length = cdataobj.get_array_length() # # pointer to a primitive type of size 1: builds and returns a str if self.ctitem.size == rffi.sizeof(lltype.Char): if length < 0: s = rffi.charp2str(cdata) else: s = rffi.charp2strn(cdata, length) keepalive_until_here(cdataobj) return space.wrap(s) # # pointer to a wchar_t: builds and returns a unicode if self.is_unichar_ptr_or_array(): cdata = rffi.cast(rffi.CWCHARP, cdata) if length < 0: u = rffi.wcharp2unicode(cdata) else: u = rffi.wcharp2unicoden(cdata, length) keepalive_until_here(cdataobj) return space.wrap(u) # return W_CType.string(self, cdataobj, maxlen)
def string(self, cdataobj, maxlen): space = self.space if isinstance(self.ctitem, ctypeprim.W_CTypePrimitive): cdata = cdataobj._cdata if not cdata: raise oefmt(space.w_RuntimeError, "cannot use string() on %s", space.str_w(cdataobj.repr())) # from pypy.module._cffi_backend import ctypearray length = maxlen if length < 0 and isinstance(self, ctypearray.W_CTypeArray): length = cdataobj.get_array_length() # # pointer to a primitive type of size 1: builds and returns a str if self.ctitem.size == rffi.sizeof(lltype.Char): if length < 0: s = rffi.charp2str(cdata) else: s = rffi.charp2strn(cdata, length) keepalive_until_here(cdataobj) return space.wrap(s) # # pointer to a wchar_t: builds and returns a unicode if self.is_unichar_ptr_or_array(): cdata = rffi.cast(rffi.CWCHARP, cdata) if length < 0: u = rffi.wcharp2unicode(cdata) else: u = rffi.wcharp2unicoden(cdata, length) keepalive_until_here(cdataobj) return space.wrap(u) # return W_CType.string(self, cdataobj, maxlen)
def string(self, cdataobj, maxlen): space = self.space if (isinstance(self.ctitem, ctypeprim.W_CTypePrimitive) and not isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool)): with cdataobj as ptr: if not ptr: raise oefmt(space.w_RuntimeError, "cannot use string() on %R", cdataobj) # from pypy.module._cffi_backend import ctypearray length = maxlen if length < 0 and isinstance(self, ctypearray.W_CTypeArray): length = cdataobj.get_array_length() # # pointer to a primitive type of size 1: builds and returns a str if self.ctitem.size == rffi.sizeof(lltype.Char): if length < 0: s = rffi.charp2str(ptr) else: s = rffi.charp2strn(ptr, length) return space.newbytes(s) # # pointer to a wchar_t: builds and returns a unicode if self.is_unichar_ptr_or_array(): cdata = rffi.cast(rffi.CWCHARP, ptr) if length < 0: u = rffi.wcharp2unicode(cdata) else: u = rffi.wcharp2unicoden(cdata, length) return space.newunicode(u) # return W_CType.string(self, cdataobj, maxlen)
def wcharp2unicode(space, address, maxlength=-1): if address == 0: return space.w_None wcharp_addr = rffi.cast(rffi.CWCHARP, address) if maxlength == -1: s = rffi.wcharp2unicode(wcharp_addr) else: s = rffi.wcharp2unicoden(wcharp_addr, maxlength) return space.wrap(s)
def wcharp2unicode(space, address, maxlength=-1): if address == 0: return space.w_None wcharp_addr = rffi.cast(rffi.CWCHARP, address) if maxlength == -1: s = rffi.wcharp2unicode(wcharp_addr) else: s = rffi.wcharp2unicoden(wcharp_addr, maxlength) return space.newunicode(s)
def test_AS(self, space): word = space.wrap(u'spam') array = rffi.cast(rffi.CWCHARP, PyUnicode_AS_DATA(space, word)) array2 = PyUnicode_AS_UNICODE(space, word) array3 = PyUnicode_AsUnicode(space, word) for (i, char) in enumerate(space.utf8_w(word)): assert array[i] == char assert array2[i] == char assert array3[i] == char with raises_w(space, TypeError): PyUnicode_AsUnicode(space, space.newbytes('spam')) utf_8 = rffi.str2charp('utf-8') encoded = PyUnicode_AsEncodedString(space, space.wrap(u'sp�m'), utf_8, None) assert space.unwrap(encoded) == 'sp\xef\xbf\xbdm' encoded_obj = PyUnicode_AsEncodedObject(space, space.wrap(u'sp�m'), utf_8, None) assert space.eq_w(encoded, encoded_obj) one = space.newint(1) with raises_w(space, TypeError): PyUnicode_AsEncodedString( space, space.newtuple([one, one, one]), None, None) with raises_w(space, TypeError): PyUnicode_AsEncodedString(space, space.wrap(''), None, None) ascii = rffi.str2charp('ascii') replace = rffi.str2charp('replace') encoded = PyUnicode_AsEncodedString(space, space.wrap(u'sp�m'), ascii, replace) assert space.unwrap(encoded) == 'sp?m' rffi.free_charp(utf_8) rffi.free_charp(replace) rffi.free_charp(ascii) buf = rffi.unicode2wcharp(u"12345") PyUnicode_AsWideChar(space, space.wrap(u'longword'), buf, 5) assert rffi.wcharp2unicode(buf) == 'longw' PyUnicode_AsWideChar(space, space.wrap(u'a'), buf, 5) assert rffi.wcharp2unicode(buf) == 'a' rffi.free_wcharp(buf)
def test_AS(self, space, api): word = space.wrap(u'spam') array = rffi.cast(rffi.CWCHARP, api.PyUnicode_AS_DATA(word)) array2 = api.PyUnicode_AS_UNICODE(word) array3 = api.PyUnicode_AsUnicode(word) for (i, char) in enumerate(space.unwrap(word)): assert array[i] == char assert array2[i] == char assert array3[i] == char self.raises(space, api, TypeError, api.PyUnicode_AsUnicode, space.wrap('spam')) utf_8 = rffi.str2charp('utf-8') encoded = api.PyUnicode_AsEncodedString(space.wrap(u'späm'), utf_8, None) assert space.unwrap(encoded) == 'sp\xc3\xa4m' encoded_obj = api.PyUnicode_AsEncodedObject(space.wrap(u'späm'), utf_8, None) assert space.eq_w(encoded, encoded_obj) self.raises(space, api, TypeError, api.PyUnicode_AsEncodedString, space.newtuple([1, 2, 3]), None, None) self.raises(space, api, TypeError, api.PyUnicode_AsEncodedString, space.wrap(''), None, None) ascii = rffi.str2charp('ascii') replace = rffi.str2charp('replace') encoded = api.PyUnicode_AsEncodedString(space.wrap(u'späm'), ascii, replace) assert space.unwrap(encoded) == 'sp?m' rffi.free_charp(utf_8) rffi.free_charp(replace) rffi.free_charp(ascii) buf = rffi.unicode2wcharp(u"12345") api.PyUnicode_AsWideChar(space.wrap(u'longword'), buf, 5) assert rffi.wcharp2unicode(buf) == 'longw' api.PyUnicode_AsWideChar(space.wrap(u'a'), buf, 5) assert rffi.wcharp2unicode(buf) == 'a' rffi.free_wcharp(buf)
def EnumValue(space, w_hkey, index): """tuple = EnumValue(key, index) - Enumerates values of an open registry key. key is an already open key, or any one of the predefined HKEY_* constants. index is an integer that identifies the index of the value to retrieve. The function retrieves the name of one subkey each time it is called. It is typically called repeatedly, until an EnvironmentError exception is raised, indicating no more values. The result is a tuple of 3 items: value_name is a string that identifies the value. value_data is an object that holds the value data, and whose type depends on the underlying registry type. data_type is an integer that identifies the type of the value data.""" hkey = hkey_w(w_hkey, space) null_dword = lltype.nullptr(rwin32.LPDWORD.TO) with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retValueSize: with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retDataSize: ret = rwinreg.RegQueryInfoKeyW(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 bufDataSize = intmask(retDataSize[0]) bufValueSize = intmask(retValueSize[0]) with lltype.scoped_alloc(rffi.CWCHARP.TO, intmask(retValueSize[0])) as valuebuf: while True: with lltype.scoped_alloc(rffi.CCHARP.TO, bufDataSize) as databuf: with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as retType: c_valuebuf = rffi.cast(rffi.CCHARP, valuebuf) ret = rwinreg.RegEnumValueW( hkey, index, c_valuebuf, retValueSize, null_dword, retType, databuf, retDataSize) if ret == rwinreg.ERROR_MORE_DATA: # Resize and retry bufDataSize *= 2 retDataSize[0] = rffi.cast( rwin32.DWORD, bufDataSize) retValueSize[0] = rffi.cast( rwin32.DWORD, bufValueSize) continue if ret != 0: raiseWindowsError(space, ret, 'RegEnumValue') length = intmask(retDataSize[0]) return space.newtuple([ space.newunicode( rffi.wcharp2unicode(valuebuf)), convert_from_regdata(space, databuf, length, retType[0]), space.newint(intmask(retType[0])), ])