diff python/hexfile.py @ 244:58155c7c4a8e

Add hexutil
author Windel Bouwman
date Wed, 24 Jul 2013 19:47:13 +0200
parents 6259856841a0
children 66912720d712
line wrap: on
line diff
--- a/python/hexfile.py	Tue Jul 23 16:50:02 2013 +0200
+++ b/python/hexfile.py	Wed Jul 24 19:47:13 2013 +0200
@@ -1,4 +1,5 @@
 import os
+import struct
 
 class HexFileException(Exception):
     pass
@@ -13,11 +14,30 @@
     crc = sum(nums)
     if (crc & 0xFF) != 0:
         raise HexFileException('crc incorrect')
-    address = nums[1] * 256 + nums[2]
+    address = struct.unpack('>H', nums[1:3])[0]
     typ = nums[3]
     data = nums[4:-1]
     return (address, typ, data)
 
+def makeHexLine(address, typ, data=bytes()):
+    bytecount = len(data)
+    nums = bytearray()
+    nums.append(bytecount)
+    nums.extend(struct.pack('>H', address))
+    nums.append(typ)
+    nums.extend(data)
+    crc = sum(nums)
+    crc = ((~crc) + 1) & 0xFF
+    nums.append(crc)
+    line = ':' + ''.join(['{:02X}'.format(b) for b in nums])
+    return line
+
+def chunks(data, csize=16):
+    idx = 0
+    while idx < len(data):
+        s = min(len(data) - idx, csize)
+        yield data[idx:idx+s]
+        idx += s
 
 class HexFile:
     """ Represents an intel hexfile """
@@ -65,27 +85,48 @@
             self.regions.append(HexFileRegion(startAddress, bytes(curData)))
 
     def __repr__(self):
-        i = []
-        i.append(super().__repr__())
-        i.append('Start address {0}'.format(hex(self.startAddress)))
+        return 'Hexfile with {} regions'.format(len(self.regions))
+
+    def dump(self):
+        print(self)
         for r in self.regions:
-            i.append(str(r))
-        return os.linesep.join(i)
+            print(r)
+
+    def __eq__(self, other):
+        regions = self.regions
+        oregions = other.regions
+        if len(regions) != len(oregions):
+            return False
+        return all(rs == ro for rs, ro in zip(regions, oregions))
+
+    def addRegion(self, address, data):
+        r = HexFileRegion(address, data)
+        # TODO: check touches
+        self.regions.append(r)
+        self.regions.sort(key=lambda r: r.address)
 
     def save(self, f):
         for r in self.regions:
             offset = 0
-            while offset < len(r.data):
-                f.write('a')
-                offset += 16
-
+            for chunk in chunks(r.data):
+                print(makeHexLine(r.address + offset, 0x0, bytes(r.data[offset:offset+16])), file=f)
+                offset += len(chunk)
+        print(makeHexLine(0, 0x1, bytes()), file=f)
 
 class HexFileRegion:
-   def __init__(self, address, data = bytes()):
-      self.address = address
-      self.data = data
-   def __repr__(self):
-      return 'Region at 0x{0:X} of {1} bytes'.format(self.address, len(self.data))
+    def __init__(self, address, data = bytes()):
+        self.address = address
+        self.data = data
+
+    def __repr__(self):
+        return 'Region at 0x{0:X} of {1} bytes'.format(self.address, len(self.data))
+
+    def __eq__(self, other):
+        return (self.address, self.data) == (other.address, other.data)
+
+    @property
+    def EndAddress(self):
+        return self.address + len(self.data)
 
 
 if __name__ == '__main__':