about summary refs log tree commit diff stats
path: root/miasm2/core/utils.py
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2019-02-25 11:09:54 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2019-03-05 16:52:49 +0100
commit02bbb30efea4980c9d133947cbbf69fb599071ad (patch)
tree3fea6826fcc5354840a27cb1dc99ff31eef81896 /miasm2/core/utils.py
parenteab809932871f91d6f4aa770fc321af9e156e0f5 (diff)
downloadmiasm-02bbb30efea4980c9d133947cbbf69fb599071ad.tar.gz
miasm-02bbb30efea4980c9d133947cbbf69fb599071ad.zip
Support python2/python3
Diffstat (limited to 'miasm2/core/utils.py')
-rw-r--r--miasm2/core/utils.py84
1 files changed, 68 insertions, 16 deletions
diff --git a/miasm2/core/utils.py b/miasm2/core/utils.py
index c1f48418..9856d4f2 100644
--- a/miasm2/core/utils.py
+++ b/miasm2/core/utils.py
@@ -1,7 +1,15 @@
+from __future__ import print_function
+from builtins import range
 import struct
 import inspect
-import UserDict
+from collections import MutableMapping as DictMixin
+
 from operator import itemgetter
+import codecs
+
+from future.utils import viewitems
+
+import collections
 
 upck8 = lambda x: struct.unpack('B', x)[0]
 upck16 = lambda x: struct.unpack('H', x)[0]
@@ -62,23 +70,57 @@ class Disasm_Exception(Exception):
     pass
 
 
+def printable(string):
+    if isinstance(string, bytes):
+        return "".join(
+            c.decode() if b" " <= c < b"~" else "."
+            for c in (string[i:i+1] for i in range(len(string)))
+        )
+    return string
+
+
+def force_bytes(value):
+    try:
+        return value.encode()
+    except AttributeError:
+        return value
+
+
+def iterbytes(string):
+    for i in range(len(string)):
+        yield string[i:i+1]
+
+
+def int_to_byte(value):
+    return struct.pack('B', value)
+
+def cmp_elts(elt1, elt2):
+    return (elt1 > elt2) - (elt1 < elt2)
+
+
+_DECODE_HEX = codecs.getdecoder("hex_codec")
+_ENCODE_HEX = codecs.getencoder("hex_codec")
+
+def decode_hex(value):
+    return _DECODE_HEX(value)[0]
+
+def encode_hex(value):
+    return _ENCODE_HEX(value)[0]
+
+
 def hexdump(src, length=16):
-    FILTER = ''.join(
-        [(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
     lines = []
-    for c in xrange(0, len(src), length):
+    for c in range(0, len(src), length):
         chars = src[c:c + length]
-        hexa = ' '.join(["%02x" % ord(x) for x in chars])
+        hexa = ' '.join("%02x" % ord(x) for x in iterbytes(chars))
         printable = ''.join(
-            ["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars])
+            x.decode() if 32 <= ord(x) <= 126 else '.' for x in iterbytes(chars)
+        )
         lines.append("%04x  %-*s  %s\n" % (c, length * 3, hexa, printable))
-    print ''.join(lines)
-
-# stackoverflow.com/questions/2912231
-
-import collections
+    print(''.join(lines))
 
 
+# stackoverflow.com/questions/2912231
 class keydefaultdict(collections.defaultdict):
 
     def __missing__(self, key):
@@ -88,7 +130,7 @@ class keydefaultdict(collections.defaultdict):
         return value
 
 
-class BoundedDict(UserDict.DictMixin):
+class BoundedDict(DictMixin):
 
     """Limited in size dictionary.
 
@@ -108,7 +150,7 @@ class BoundedDict(UserDict.DictMixin):
         @delete_cb: (optional) callback called when an element is removed
         """
         self._data = initialdata.copy() if initialdata else {}
-        self._min_size = min_size if min_size else max_size / 3
+        self._min_size = min_size if min_size else max_size // 3
         self._max_size = max_size
         self._size = len(self._data)
         # Do not use collections.Counter as it is quite slow
@@ -122,8 +164,11 @@ class BoundedDict(UserDict.DictMixin):
 
             # Bound can only be reached on a new element
             if (self._size >= self._max_size):
-                most_common = sorted(self._counter.iteritems(),
-                                     key=itemgetter(1), reverse=True)
+                most_common = sorted(
+                    viewitems(self._counter),
+                    key=itemgetter(1),
+                    reverse=True
+                )
 
                 # Handle callback
                 if self._delete_cb is not None:
@@ -154,7 +199,7 @@ class BoundedDict(UserDict.DictMixin):
 
     def keys(self):
         "Return the list of dict's keys"
-        return self._data.keys()
+        return list(self._data)
 
     @property
     def data(self):
@@ -180,3 +225,10 @@ class BoundedDict(UserDict.DictMixin):
         if self._delete_cb:
             for key in self._data:
                 self._delete_cb(key)
+
+
+    def __len__(self):
+        return len(self._data)
+
+    def __iter__(self):
+        return iter(self._data)