Add extended struct to ctypes generation + extended IID now in winstructs.py and used everywhere

This commit is contained in:
Clement Rouault
2017-08-29 11:39:43 +02:00
parent 1fe5b912be
commit d44a3b032e
4 changed files with 133 additions and 121 deletions
@@ -0,0 +1,58 @@
INITIAL_GUID = _GUID
class _GUID(INITIAL_GUID):
def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None):
data_tuple = (Data1, Data2, Data3, Data4)
self.name = name
self.strid = strid
if all(data is None for data in data_tuple):
return super(_GUID, self).__init__()
if any(data is None for data in data_tuple):
raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None")
super(_GUID, self).__init__(Data1, Data2, Data3, Data4)
def __repr__(self):
notpresent = object()
# Handle IID created without '__init__' (like ctypes-ptr deref)
if getattr(self, "strid", notpresent) is notpresent:
self.strid = self.to_string()
if self.strid is None:
return super(_GUID, self).__repr__()
if getattr(self, "name", notpresent) is notpresent:
self.name = None
if self.name is None:
return '<IID "{0}">'.format(self.strid.upper())
return '<IID "{0}({1})">'.format(self.strid.upper(), self.name)
def to_string(self):
data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6))
data4_str = data4_format.format(*self.Data4)
return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str
def update_strid(self):
new_strid = self.to_string()
self.strid = new_strid
@classmethod
def from_string(cls, iid):
part_iid = iid.split("-")
datas = [int(x, 16) for x in part_iid[:3]]
datas.append(int(part_iid[3][:2], 16))
datas.append(int(part_iid[3][2:], 16))
for i in range(6):
datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16))
return cls.from_raw(*datas, strid=iid)
@classmethod
def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs):
return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs)
def __eq__(self, other):
if not isinstance(other, (_GUID, INITIAL_GUID)):
return NotImplemented
return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:])
LPGUID = POINTER(_GUID)
REFGUID = POINTER(_GUID)
REFCLSID = POINTER(_GUID)
REFIID = POINTER(_GUID)
+12 -61
View File
@@ -258,6 +258,8 @@ class InitialDefGenerator(CtypesGenerator):
with open(target_file, "w") as f:
f.writelines(all_lines)
EXTENDED_STRUCT = ["_GUID"] # TODO: check auto the dir
class StructGenerator(CtypesGenerator):
PARSER = struct_parser.WinStructParser
IMPORT_HEADER = dedent ("""
@@ -329,7 +331,16 @@ class StructGenerator(CtypesGenerator):
HEADER += self.TYPES_HEADER
structs, enums = self.data
ctypes_lines = [self.common_header, HEADER] + [d.generate_ctypes() for l in (enums, structs) for d in l]
ctypes_lines = [self.common_header, HEADER]
for definition in [d for l in (enums, structs) for d in l]:
ctypes_lines.append(definition.generate_ctypes())
if definition.name in EXTENDED_STRUCT:
print("Including extended definition for <{0}>".format(definition.name))
extended_struct_filename = from_here(os.path.join("extended_structs", "{0}.py".format(definition.name)))
with open(extended_struct_filename) as f:
ctypes_lines.append(f.read())
ctypes_lines.append(definition.generate_typedef_ctypes() + "\n")
ctypes_code = "\n".join(ctypes_lines)
with open(self.outfilename, "w") as f:
f.write(ctypes_code)
@@ -501,68 +512,8 @@ class InitialCOMGenerator(CtypesGenerator):
""")
HEADER = dedent("""
_GUID = IID
class IID(IID):
def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None):
data_tuple = (Data1, Data2, Data3, Data4)
self.name = name
self.strid = strid
if all(data is None for data in data_tuple):
return super(IID, self).__init__()
if any(data is None for data in data_tuple):
raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None")
super(IID, self).__init__(Data1, Data2, Data3, Data4)
def __repr__(self):
notpresent = object()
# Handle IID created without '__init__' (like ctypes-ptr deref)
if getattr(self, "strid", notpresent) is notpresent:
self.strid = self.to_string()
if self.strid is None:
return super(IID, self).__repr__()
if getattr(self, "name", notpresent) is notpresent:
self.name = None
if self.name is None:
return '<IID "{0}">'.format(self.strid.upper())
return '<IID "{0}({1})">'.format(self.strid.upper(), self.name)
def to_string(self):
data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6))
data4_str = data4_format.format(*self.Data4)
return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str
def update_strid(self):
new_strid = self.to_string()
self.strid = new_strid
@classmethod
def from_string(cls, iid):
part_iid = iid.split("-")
datas = [int(x, 16) for x in part_iid[:3]]
datas.append(int(part_iid[3][:2], 16))
datas.append(int(part_iid[3][2:], 16))
for i in range(6):
datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16))
return cls.from_raw(*datas, strid=iid)
@classmethod
def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs):
return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs)
def __eq__(self, other):
if not isinstance(other, (IID, _GUID)):
return NotImplemented
return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:])
generate_IID = IID.from_raw
GUID = IID
LPGUID = POINTER(GUID)
REFGUID = POINTER(GUID)
REFCLSID = POINTER(GUID)
REFIID = POINTER(GUID)
class COMInterface(ctypes.c_void_p):
_functions_ = {
}
-60
View File
@@ -8,68 +8,8 @@ from windef import *
_GUID = IID
class IID(IID):
def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None):
data_tuple = (Data1, Data2, Data3, Data4)
self.name = name
self.strid = strid
if all(data is None for data in data_tuple):
return super(IID, self).__init__()
if any(data is None for data in data_tuple):
raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None")
super(IID, self).__init__(Data1, Data2, Data3, Data4)
def __repr__(self):
notpresent = object()
# Handle IID created without '__init__' (like ctypes-ptr deref)
if getattr(self, "strid", notpresent) is notpresent:
self.strid = self.to_string()
if self.strid is None:
return super(IID, self).__repr__()
if getattr(self, "name", notpresent) is notpresent:
self.name = None
if self.name is None:
return '<IID "{0}">'.format(self.strid.upper())
return '<IID "{0}({1})">'.format(self.strid.upper(), self.name)
def to_string(self):
data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6))
data4_str = data4_format.format(*self.Data4)
return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str
def update_strid(self):
new_strid = self.to_string()
self.strid = new_strid
@classmethod
def from_string(cls, iid):
part_iid = iid.split("-")
datas = [int(x, 16) for x in part_iid[:3]]
datas.append(int(part_iid[3][:2], 16))
datas.append(int(part_iid[3][2:], 16))
for i in range(6):
datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16))
return cls.from_raw(*datas, strid=iid)
@classmethod
def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs):
return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs)
def __eq__(self, other):
if not isinstance(other, (IID, _GUID)):
return NotImplemented
return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:])
generate_IID = IID.from_raw
GUID = IID
LPGUID = POINTER(GUID)
REFGUID = POINTER(GUID)
REFCLSID = POINTER(GUID)
REFIID = POINTER(GUID)
class COMInterface(ctypes.c_void_p):
_functions_ = {
}
+63
View File
@@ -2464,6 +2464,69 @@ REFCLSID = POINTER(_GUID)
GUID = _GUID
REFIID = POINTER(_GUID)
INITIAL_GUID = _GUID
class _GUID(INITIAL_GUID):
def __init__(self, Data1=None, Data2=None, Data3=None, Data4=None, name=None, strid=None):
data_tuple = (Data1, Data2, Data3, Data4)
self.name = name
self.strid = strid
if all(data is None for data in data_tuple):
return super(_GUID, self).__init__()
if any(data is None for data in data_tuple):
raise ValueError("All or none of (Data1, Data2, Data3, Data4) should be None")
super(_GUID, self).__init__(Data1, Data2, Data3, Data4)
def __repr__(self):
notpresent = object()
# Handle IID created without '__init__' (like ctypes-ptr deref)
if getattr(self, "strid", notpresent) is notpresent:
self.strid = self.to_string()
if self.strid is None:
return super(_GUID, self).__repr__()
if getattr(self, "name", notpresent) is notpresent:
self.name = None
if self.name is None:
return '<IID "{0}">'.format(self.strid.upper())
return '<IID "{0}({1})">'.format(self.strid.upper(), self.name)
def to_string(self):
data4_format = "{0:02X}{1:02X}-" + "".join("{{{i}:02X}}".format(i=i + 2) for i in range(6))
data4_str = data4_format.format(*self.Data4)
return "{0:08X}-{1:04X}-{2:04X}-".format(self.Data1, self.Data2, self.Data3) + data4_str
def update_strid(self):
new_strid = self.to_string()
self.strid = new_strid
@classmethod
def from_string(cls, iid):
part_iid = iid.split("-")
datas = [int(x, 16) for x in part_iid[:3]]
datas.append(int(part_iid[3][:2], 16))
datas.append(int(part_iid[3][2:], 16))
for i in range(6):
datas.append(int(part_iid[4][i * 2:(i + 1) * 2], 16))
return cls.from_raw(*datas, strid=iid)
@classmethod
def from_raw(cls, Data1, Data2, Data3, Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48, **kwargs):
return cls(Data1, Data2, Data3, (BYTE*8)(Data41, Data42, Data43, Data44, Data45, Data46, Data47, Data48), **kwargs)
def __eq__(self, other):
if not isinstance(other, (_GUID, INITIAL_GUID)):
return NotImplemented
return (self.Data1, self.Data2, self.Data3, self.Data4[:]) == (other.Data1, other.Data2, other.Data3, other.Data4[:])
LPGUID = POINTER(_GUID)
REFGUID = POINTER(_GUID)
REFCLSID = POINTER(_GUID)
REFIID = POINTER(_GUID)
IID = _GUID
REFCLSID = POINTER(_GUID)
GUID = _GUID
REFIID = POINTER(_GUID)
class _TMP_signscale(Structure):
_fields_ = [
("scale", BYTE),