Mercurial > paraspace
diff paraspace/dexfile.py @ 40:0c0a659187c2
Use _objs_asso to define association between two set of items.
Derivation of _objs_asso define a rule to assocate elements from first set
to another element in second set.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sat, 18 Jun 2011 23:59:37 +0800 |
parents | e625ebf17441 |
children | c5cfc796af8b |
line wrap: on
line diff
--- a/paraspace/dexfile.py Thu Jun 16 08:03:50 2011 +0800 +++ b/paraspace/dexfile.py Sat Jun 18 23:59:37 2011 +0800 @@ -175,7 +175,7 @@ class tap(_dex_type): @staticmethod def parse(parent, data, off): - pass + return tap() @staticmethod def sizeof(v): @@ -329,6 +329,84 @@ return o.__class__.sizeof(o) +## \biref Associate objects from two set of objects. +# +class _objs_asso(_dex_type): + left = None + left_ref = None + right = None + right_ref = None + + ## \brief Update references for a element pair from left and right. + # + # This method must be called by derivation to associate a pair of + # elements. + # + def _update_refs(self, left_elt, right_elt): + lref = getattr(left_elt, self.left_ref) + if not isinstance(right_elt, lref.target_path): + raise TypeError, 'invalid target_path in left %s' % (repr(le)) + + rref = getattr(right_elt, self.right_ref) + if not isinstance(left_elt, rref.target_path): + raise TypeError, 'invalid target_path in right %s' % (repr(re)) + + new_lref = ref(lref.target_path) + new_lref.target = right_elt + setattr(left_elt, self.left_ref, new_lref) + + new_rref = ref(rref.target_path) + new_rref.target = left_elt + setattr(right_elt, self.right_ref, new_rref) + pass + + ## \brief Assocate elements from left list to a respective right element. + # + # This method must be called before linking dependencies. + # + def build_associations(self, left, right): + raise NotImplementedError, 'build_associations is not implemented' + pass + + +## \brief One to one association. +# +# Associate nth element from left sequence to nth element in right +# sequence. +# +class one2one(_objs_asso): + def __init__(self, left, left_ref, right, right_ref): + self.left = left + self.left_ref = left_ref + self.right = right + self.right_ref = right_ref + pass + + ## \brief Associate elements from left list to elements from right list + # + def build_associations(self, left, right): + assert len(left) == len(right) + for le, re in map(None, left, right): + self._update_refs(le, re) + pass + pass + pass + + +## \brief Implicit reference to a target. +# +# It is a placeholder for storing relationship defined by an association. +# +class ref(_dex_type): + target_path = None + target = None + + def __init__(self, target_path=None): + self.target_path = target_path + pass + pass + + class relocatable(_dex_type): data_size = None @@ -832,11 +910,18 @@ class _DEX_TypeList(composite): - padding = auto_align(2) # 2 bits alignment num = uint32 typeItems = array('num', uint16) - child_names = 'padding num typeItems'.split() + child_names = 'num typeItems'.split() + pass + + +class _DEX_TypeList_align(composite): + padding = auto_align(2) # 2 bits alignment + value = _DEX_TypeList + + child_names = 'padding value'.split() pass @@ -844,7 +929,8 @@ startAddr = uint32 insnCount = uint16 handlerOff = depend_off_rel('_DEX_Code.handlers_size', - '_DEX_Catch')(uint16) + '_DEX_Try.catch_ref.target')(uint16) + catch_ref = ref('_DEX_Catch') child_names = 'startAddr insnCount handlerOff'.split() pass @@ -870,6 +956,7 @@ handlers = array('count', _DEX_CatchHandler) catchAllHandler = cond((lambda parent, data, off: parent.catchesAll), _DEX_CatchAllHandler) + try_ref = ref('_DEX_Try') child_names = 'size handlers catchAllHandler'.split() @@ -903,6 +990,8 @@ handlers_size = cond(_has_tries, uleb128) catch_handler_items = cond(_has_tries, array('handlers_size.value', _DEX_Catch)) + try_catch_asso = one2one('try_items.value.items', 'catch_ref', + 'catch_handler_items.value.items', 'try_ref') padding2 = auto_align(2) @@ -1326,7 +1415,7 @@ methodIds = array(None, _DEX_MethodId) classDefs = array(None, _DEX_ClassDef) classDatas = array(None, _DEX_ClassData) - typeLists = array(None, _DEX_TypeList) + typeLists = array(None, _DEX_TypeList_align) codeItems = array(None, _DEX_Code) annotationSetItems = array(None, _DEX_AnnotationSetItem) annotationsDirectoryItems = array(None, _DEX_AnnotationsDirectoryItem)