changeset 3:a78db169b0c8

parse AnnotationSetItems
author Thinker K.F. Li <thinker@codemud.net>
date Mon, 23 May 2011 21:44:58 +0800
parents add64d56b0e2
children b0766f1984bb
files paraspace/dexfile.py
diffstat 1 files changed, 73 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/paraspace/dexfile.py	Mon May 23 21:11:11 2011 +0800
+++ b/paraspace/dexfile.py	Mon May 23 21:44:58 2011 +0800
@@ -51,6 +51,20 @@
     pass
 
 
+class man_off(object):
+    off = None
+    
+    def __init__(self, off):
+        self.off = off
+        pass
+
+    def __call__(self, sz):
+        off = self.off
+        self.off = off + sz
+        return off
+    pass
+
+
 def _to_uint(data):
     v = 0
     sh = 0
@@ -118,6 +132,13 @@
         self.size = _to_uint(data[4:8])
         self.offset = _to_uint(data[8:12])
         pass
+
+    @classmethod
+    def find_type_name(self, type_name):
+        type_value = [v
+                      for v, name in _DEX_MapItem.types.items()
+                      if name == type_name][0]
+        return type_value
     pass
 
 
@@ -529,6 +550,24 @@
     pass
 
 
+class _DEX_AnnotationSetItem(object):
+    size = None                 # 4 bytes
+    annotations = None          # 4 * size bytes
+
+    data_size = None
+
+    def parse(self, data, off):
+        moff = man_off(off)
+        
+        self.size = _to_uint(data[moff(4):moff(0)])
+        self.annotations = [_to_uint(data[moff(4):moff(0)])
+                            for i in range(self.size)]
+
+        self.data_size = moff(0) - off
+        pass
+    pass
+
+
 class DEXFile(object):
     _data = None
     _header = None
@@ -542,6 +581,7 @@
     _classDatas = None
     _typeLists = None
     _codeItems = None
+    _annotationSetItems = None
     
     def __init__(self):
         pass
@@ -573,6 +613,17 @@
         self._maps = maps
         pass
 
+    def find_map_item(self, type_value):
+        maps = self._maps
+        codeItem_map = [map for map in maps if map.type == type_value][0]
+        
+        return codeItem_map
+
+    def find_map_item_name(self, type_name):
+        type_value = _DEX_MapItem.find_type_name(type_name)
+        map = self.find_map_item(type_value)
+        return map
+    
     def _parse_strings(self):
         data = self._data
         header = self._header
@@ -761,6 +812,23 @@
         self._codeItems = codeItems
         pass
 
+    def _parse_annotationSetItems(self):
+        data = self._data
+        
+        annoset_map = self.find_map_item_name('kDexTypeAnnotationSetItem')
+        
+        moff = man_off(annoset_map.offset)
+        
+        def parse_annotationSetItem():
+            item = _DEX_AnnotationSetItem()
+            item.parse(data, moff(0))
+            moff(item.data_size)
+            return item
+        
+        self._annotationSetItems = [parse_annotationSetItem()
+                                    for i in range(annoset_map.size)]
+        pass
+
     def parse(self, data):
         self._data = data
         header = _DEX_header()
@@ -777,6 +845,7 @@
         self._parse_classDatas()
         self._parse_typeLists()
         self._parse_codeItems()
+        self._parse_annotationSetItems()
         pass
     pass
 
@@ -836,6 +905,10 @@
     print
     print 'CodeItems size is %d bytes' % (bytes)
     
+    bytes = sum([annoset.data_size for annoset in dex._annotationSetItems])
+    print
+    print 'AnnotationSetItems size is %d bytes' % (bytes)
+    
     print
     print 'Data maps'
     maps = dex._maps