about summary refs log tree commit diff stats
path: root/miasm2/core/interval.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/core/interval.py')
-rw-r--r--miasm2/core/interval.py124
1 files changed, 63 insertions, 61 deletions
diff --git a/miasm2/core/interval.py b/miasm2/core/interval.py
index cd2a793e..d76cbd15 100644
--- a/miasm2/core/interval.py
+++ b/miasm2/core/interval.py
@@ -1,59 +1,62 @@
-INT_EQ = 0
-INT_B_IN_A = 1
-INT_A_IN_B = -1
-INT_DISJOIN = 2
-INT_JOIN = 3
-INT_JOIN_AB = 4
-INT_JOIN_BA = 5
-
-# 0  => eq
-# 1  => b in a
-# -1 => a in b
-# 2  => disjoin
-# 3  => join
-# 4  => join a,b touch
-# 5  => join b,a touch
-
-
-def cmp_interval(a, b):
-    if a == b:
+INT_EQ = 0      # Equivalent
+INT_B_IN_A = 1  # B in A
+INT_A_IN_B = -1 # A in B
+INT_DISJOIN = 2 # Disjoint
+INT_JOIN = 3    # Overlap
+INT_JOIN_AB = 4 # B starts at the end of A
+INT_JOIN_BA = 5 # A starts at the end of B
+
+
+def cmp_interval(inter1, inter2):
+    """Compare @inter1 and @inter2 and returns the associated INT_* case
+    @inter1, @inter2: interval instance
+    """
+    if inter1 == inter2:
         return INT_EQ
-    a1, a2 = a
-    b1, b2 = b
-    if a1 <= b1 and a2 >= b2:
-        return INT_B_IN_A
-    if b1 <= a1 and b2 >= a2:
-        return INT_A_IN_B
-    if a2 + 1 == b1:
-        return INT_JOIN_AB
-    if b2 + 1 == a1:
-        return INT_JOIN_BA
-    if a1 > b2 + 1 or b1 > a2 + 1:
-        return INT_DISJOIN
-    return INT_JOIN
-
-# interval is: [a, b]
-
-
-class interval:
-
-    def __init__(self, a=None):
-        if a is None:
-            a = []
-        if isinstance(a, interval):
-            a = a.intervals
+
+    inter1_start, inter1_stop = inter1
+    inter2_start, inter2_stop = inter2
+    result = INT_JOIN
+    if inter1_start <= inter2_start and inter1_stop >= inter2_stop:
+        result = INT_B_IN_A
+    if inter2_start <= inter1_start and inter2_stop >= inter1_stop:
+        result = INT_A_IN_B
+    if inter1_stop + 1 == inter2_start:
+        result = INT_JOIN_AB
+    if inter2_stop + 1 == inter1_start:
+        result = INT_JOIN_BA
+    if inter1_start > inter2_stop + 1 or inter2_start > inter1_stop + 1:
+        result = INT_DISJOIN
+    return result
+
+
+class interval(object):
+    """Stands for intervals with integer bounds
+
+    Offers common methods to work with interval"""
+
+    def __init__(self, bounds=None):
+        """Instance an interval object
+        @bounds: (optional) list of (int, int) and/or interval instance
+        """
+        if bounds is None:
+            bounds = []
+        elif isinstance(bounds, interval):
+            bounds = bounds.intervals
         self.is_cannon = False
-        self.intervals = a
+        self.intervals = bounds
         self.cannon()
 
     def __iter__(self):
-        for x in self.intervals:
-            yield x
+        """Iterate on intervals"""
+        for inter in self.intervals:
+            yield inter
 
-    @classmethod
-    def cannon_list(cls, tmp):
+    @staticmethod
+    def cannon_list(tmp):
         """
         Return a cannonizes list of intervals
+        @tmp: list of (int, int)
         """
         tmp = sorted([x for x in tmp if x[0] <= x[1]])
         out = []
@@ -63,7 +66,7 @@ class interval:
         while tmp:
             x = tmp.pop()
             rez = cmp_interval(out[-1], x)
-            # print out[-1], x, rez
+
             if rez == INT_EQ:
                 continue
             elif rez == INT_DISJOIN:
@@ -83,6 +86,7 @@ class interval:
         return out[::-1]
 
     def cannon(self):
+        "Apply .cannon_list() on self contained intervals"
         if self.is_cannon is True:
             return
         self.intervals = interval.cannon_list(self.intervals)
@@ -130,12 +134,12 @@ class interval:
             i += 1
             x = to_test[i]
             if x[0] > x[1]:
-                del(to_test[i])
+                del to_test[i]
                 i -= 1
                 continue
 
             while to_del and to_del[0][1] < x[0]:
-                del(to_del[0])
+                del to_del[0]
 
             for y in to_del:
                 if y[0] > x[1]:
@@ -144,15 +148,15 @@ class interval:
                 if rez == INT_DISJOIN:
                     continue
                 elif rez == INT_EQ:
-                    del(to_test[i])
+                    del to_test[i]
                     i -= 1
                     break
                 elif rez == INT_A_IN_B:
-                    del(to_test[i])
+                    del to_test[i]
                     i -= 1
                     break
                 elif rez == INT_B_IN_A:
-                    del(to_test[i])
+                    del to_test[i]
                     i1 = (x[0], y[0] - 1)
                     i2 = (y[1] + 1, x[1])
                     to_test[i:i] = [i1, i2]
@@ -161,7 +165,7 @@ class interval:
                 elif rez in [INT_JOIN_AB, INT_JOIN_BA]:
                     continue
                 elif rez == INT_JOIN:
-                    del(to_test[i])
+                    del to_test[i]
                     if x[0] < y[0]:
                         to_test[i:i] = [(x[0], y[0] - 1)]
                     else:
@@ -175,13 +179,11 @@ class interval:
     def __and__(self, v):
         out = []
         for x in self.intervals:
-            # print "x", x
             if x[0] > x[1]:
                 continue
             for y in v.intervals:
-                # print 'y', y
                 rez = cmp_interval(x, y)
-                # print x, y, rez
+
                 if rez == INT_DISJOIN:
                     continue
                 elif rez == INT_EQ:
@@ -208,13 +210,14 @@ class interval:
         return interval(out)
 
     def hull(self):
+        "Return the first and the last bounds of intervals"
         if not self.intervals:
             return None, None
         return self.intervals[0][0], self.intervals[-1][1]
 
     def show(self, img_x=1350, img_y=20, dry_run=False):
         """
-        show image representing the itnerval
+        show image representing the interval
         """
         try:
             import Image
@@ -229,8 +232,7 @@ class interval:
 
         print hex(i_min), hex(i_max)
 
-        def addr2x(addr):
-            return (addr - i_min) * img_x / (i_max - i_min)
+        addr2x = lambda addr: (addr - i_min) * img_x / (i_max - i_min)
         for a, b in self.intervals:
             draw.rectangle((addr2x(a), 0, addr2x(b), img_y), (200, 0, 0))