Mercurial > paraspace
comparison paraspace/dexfile.py @ 104:61cef1662035
Redirect types
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Thu, 28 Jul 2011 00:06:54 +0800 |
parents | 7fcd555d802b |
children | 7821c6e89622 |
comparison
equal
deleted
inserted
replaced
103:8a53e6f7f517 | 104:61cef1662035 |
---|---|
1029 pass | 1029 pass |
1030 | 1030 |
1031 | 1031 |
1032 class _DEX_TypeList(composite): | 1032 class _DEX_TypeList(composite): |
1033 num = uint32 | 1033 num = uint32 |
1034 typeItems = array('num', uint16) | 1034 typeItems = array('num', depend_idx('DEXFile.typeIds')(uint16)) |
1035 | 1035 |
1036 child_names = 'num typeItems'.split() | 1036 child_names = 'num typeItems'.split() |
1037 pass | 1037 pass |
1038 | 1038 |
1039 | 1039 |
1691 return linked | 1691 return linked |
1692 | 1692 |
1693 ## \brief Return name string of a linked class definition item | 1693 ## \brief Return name string of a linked class definition item |
1694 @staticmethod | 1694 @staticmethod |
1695 def get_classdef_name(classdef): | 1695 def get_classdef_name(classdef): |
1696 return classdef.classIdx.descriptorIdx.stringDataOff.data.data | 1696 return DEXFile_linked.get_typeid_name(classdef.classIdx) |
1697 | |
1698 ## \brief Return name string of a linked type ID item. | |
1699 @staticmethod | |
1700 def get_typeid_name(typeid): | |
1701 return typeid.descriptorIdx.stringDataOff.data.data | |
1702 | |
1703 ## \brief Get index of given type ID. | |
1704 def get_idx_typeid(self, typeid): | |
1705 return self.typeIds.items.index(typeid) | |
1706 | |
1707 ## \brief Find type ID item with given name. | |
1708 def find_typeid_name(self, name): | |
1709 for typeid in self.typeIds.items: | |
1710 typeid_name = DEXFile_linked.get_typeid_name(typeid) | |
1711 if typeid_name == name: | |
1712 return typeid | |
1713 pass | |
1714 pass | |
1715 | |
1716 ## \brief Return type ID item with given index. | |
1717 def find_typeid_idx(self, idx): | |
1718 return self.typeIds.items[idx] | |
1697 | 1719 |
1698 def find_class_name(self, name): | 1720 def find_class_name(self, name): |
1699 for classdef in self.classDefs.items: | 1721 for classdef in self.classDefs.items: |
1700 classdef_name = DEXFile_linked.get_classdef_name(classdef) | 1722 classdef_name = DEXFile_linked.get_classdef_name(classdef) |
1701 if classdef_name == name: | 1723 if classdef_name == name: |
1702 return classdef | 1724 return classdef |
1703 pass | 1725 pass |
1704 raise ValueError, 'can not find class definition for \'%s\'' % (name) | 1726 raise ValueError, 'can not find class definition for \'%s\'' % (name) |
1727 | |
1728 ## \brief Return a class definition corresponding for give type ID. | |
1729 def find_class_typeid(self, typeid): | |
1730 for classdef in self.classDefs.items: | |
1731 if classdef.classIdx == typeid: | |
1732 return classdef | |
1733 pass | |
1734 raise ValueError, \ | |
1735 'can not find class definition for typeid %s' % (repr(typeid)) | |
1705 | 1736 |
1706 ## \brief Update size of map items. | 1737 ## \brief Update size of map items. |
1707 # | 1738 # |
1708 # Corresponding data lists of maps may be changed, it should be updated | 1739 # Corresponding data lists of maps may be changed, it should be updated |
1709 # before restore dependencies and keep it consistent. | 1740 # before restore dependencies and keep it consistent. |
1767 wmethod_name = DEXFile_linked.get_method_name(wmethod) | 1798 wmethod_name = DEXFile_linked.get_method_name(wmethod) |
1768 if method_name == wmethod_name: | 1799 if method_name == wmethod_name: |
1769 return wmethod | 1800 return wmethod |
1770 pass | 1801 pass |
1771 pass | 1802 pass |
1803 | |
1804 ## \brief Get name of given method ID. | |
1805 @staticmethod | |
1806 def get_methodid_name(methoid): | |
1807 return methoid.nameIdx.stringDataOff.data.data | |
1808 | |
1809 ## \brief Find the method ID item of given index. | |
1810 def find_methodid_idx(self, idx): | |
1811 methodid = self.methodIds.items[idx] | |
1812 return methodid | |
1813 | |
1814 ## \brief Find a method definition with an index to method ID. | |
1815 def find_method_idx(self, idx): | |
1816 methodid = self.find_methodid_idx(idx) | |
1817 method_name = DEXFile_linked.get_methoid_name(methodid) | |
1818 method_proto = methodid.protoIdx | |
1819 method_typeid = methodid.classIdx | |
1820 classdef = self.find_class_typeid(method_typeid) | |
1821 | |
1822 method = self.find_method_name_proto(method, method_proto, classdef) | |
1823 | |
1824 return method | |
1825 | |
1826 ## \brief Test if prototype of two methods are compatible. | |
1827 @staticmethod | |
1828 def _proto_is_compatible(proto1, proto2): | |
1829 if proto1.returnTypeIdx != proto2.returnTypeIdx: | |
1830 return False | |
1831 typelist1 = proto1.parametersOffRef.value | |
1832 typelist2 = proto2.parametersOffRef.value | |
1833 if len(typelist1.typeItems.items) != len(typelist2.typeItems.items): | |
1834 return False | |
1835 | |
1836 for typeid1, typeid2 in map(None, | |
1837 typelist1.typeItems.items, | |
1838 typelist2.typeItems.items): | |
1839 if typeid1 != typeid2: | |
1840 return False | |
1841 pass | |
1842 return True | |
1843 | |
1844 def find_method_name_proto(self, method_name, proto, classdef): | |
1845 if not classdef.classDataOffRef.is_true: | |
1846 return | |
1847 | |
1848 classdata = classdef.classDataOffRef.value | |
1849 for wmethod in classdata.directMethods.items + \ | |
1850 classdata.virtualMethods.items: | |
1851 wmethod_name = DEXFile_linked.get_method_name(wmethod) | |
1852 if method_name != wmethod_name: | |
1853 continue | |
1854 if DEXFile_linked._proto_is_compatible(wmethod.protoIdx, proto): | |
1855 return wmethod | |
1856 pass | |
1857 raise ValueError, 'can not find a method for given name and prototype' | |
1772 pass | 1858 pass |
1773 | 1859 |
1774 | 1860 |
1775 if __name__ == '__main__': | 1861 if __name__ == '__main__': |
1776 import sys | 1862 import sys |