def _decode_surrogatepass(data, codec):
"""Like data.decode(codec, 'surrogatepass') but makes utf-16-le/be work
on Python < 3.4 + Windows
https://bugs.python.org/issue27971
Raises UnicodeDecodeError, LookupError
"""
try:
return data.decode(codec, _surrogatepass)
except UnicodeDecodeError:
if not _codec_can_decode_with_surrogatepass(codec):
if _normalize_codec(codec) == "utf-16-be":
data = _swap_bytes(data)
codec = "utf-16-le"
if _normalize_codec(codec) == "utf-16-le":
buffer_ = ctypes.create_string_buffer(data + b"\x00\x00")
value = ctypes.wstring_at(buffer_, len(data) // 2)
if value.encode("utf-16-le", _surrogatepass) != data:
raise
return value
else:
raise
else:
raise
python类wstring_at()的实例源码
def get_env(shell=None, for_subprocess=False):
"""
Return environment variables for the current user
:param shell:
The shell to get the env from - unused on Windows
:param for_subprocess:
If True, and the code is being run in Sublime Text 2, the result will
be byte strings instead of unicode strings
:return:
A 2-element tuple:
- [0] unicode string shell path
- [1] env dict with keys and values as unicode strings
"""
shell = os.environ['ComSpec']
if not isinstance(shell, str_cls) and for_subprocess is False:
shell = shell.decode(_sys_encoding)
if sys.version_info < (3,) and for_subprocess is False:
str_pointer = kernel32.GetEnvironmentStringsW()
string = ctypes.wstring_at(str_pointer)
values = {}
while string != '':
if string[0].isalpha():
name, value = string.split(u'=', 1)
values[name.upper()] = value
# Include the trailing null byte, and measure each
# char as 2 bytes since Windows uses UTF-16 for
# wide chars
str_pointer += (len(string) + 1) * 2
string = ctypes.wstring_at(str_pointer)
else:
values = dict(os.environ)
return (shell, values)
def FillDeviceAttributes(device, descriptor):
"""Fill out the attributes of the device.
Fills the devices HidAttributes and product string
into the descriptor.
Args:
device: A handle to the open device
descriptor: The DeviceDescriptor to populate with the
attributes.
Returns:
None
Raises:
WindowsError when unable to obtain attributes or product
string.
"""
attributes = HidAttributes()
result = hid.HidD_GetAttributes(device, ctypes.byref(attributes))
if not result:
raise ctypes.WinError()
buf = ctypes.create_string_buffer(1024)
result = hid.HidD_GetProductString(device, buf, 1024)
if not result:
raise ctypes.WinError()
descriptor.vendor_id = attributes.VendorID
descriptor.product_id = attributes.ProductID
descriptor.product_string = ctypes.wstring_at(buf)
def EnumKey(key, index):
"""This calls the Windows RegEnumKeyEx function in a Unicode safe way."""
buf = ctypes.create_unicode_buffer(257)
length = ctypes.wintypes.DWORD(257)
rc = RegEnumKeyEx(key.handle, index, ctypes.cast(buf, ctypes.c_wchar_p),
ctypes.byref(length), LPDWORD(), ctypes.c_wchar_p(),
LPDWORD(), ctypes.POINTER(FileTime)())
if rc != 0:
raise ctypes.WinError(2)
return ctypes.wstring_at(buf, length.value).rstrip(u"\x00")
def Reg2Py(data, size, data_type):
if data_type == _winreg.REG_DWORD:
if size == 0:
return 0
return ctypes.cast(data, ctypes.POINTER(ctypes.c_int)).contents.value
elif data_type == _winreg.REG_SZ or data_type == _winreg.REG_EXPAND_SZ:
return ctypes.wstring_at(data, size // 2).rstrip(u"\x00")
elif data_type == _winreg.REG_MULTI_SZ:
return ctypes.wstring_at(data, size // 2).rstrip(u"\x00").split(u"\x00")
else:
if size == 0:
return None
return ctypes.string_at(data, size)
def _safe_wstring_at(self, buff, offset):
idx = 0
length = 0
while offset + idx + 1 < len(buff):
if buff[offset+idx] == b'\x00' and buff[offset+idx+1] == b'\x00':
return ct.wstring_at(ct.addressof(buff) + offset, length)
idx += 2
length += 1
return None # terminating null char not found