diff --git a/can/io/asc.py b/can/io/asc.py
index 2e25e5c2c..5bc19c0b0 100644
--- a/can/io/asc.py
+++ b/can/io/asc.py
@@ -9,6 +9,7 @@
"""
from datetime import datetime
+import re
import time
import logging
@@ -18,8 +19,15 @@
from .generic import BaseIOHandler
+class ASCParseError(Exception):
+ """ASC file could not be parsed correctly."""
+
+
+BASES = {"dec": 10, "hex": 16}
CAN_MSG_EXT = 0x80000000
CAN_ID_MASK = 0x1FFFFFFF
+BEGIN_TRIGGERBLOCK = "Begin Triggerblock"
+MAX_HEADER_ROW_LENGTH = 10 # TODO Just guessing here, is there an actual max row length of asc header?
logger = logging.getLogger("can.io.asc")
@@ -38,15 +46,32 @@ def __init__(self, file):
read mode, not binary read mode.
"""
super().__init__(file, mode="r")
-
- @staticmethod
- def _extract_can_id(str_can_id):
+ self.base = 16
+ self.absolute_timestamps = False
+ self._parse_header()
+
+ def _parse_header(self):
+ """Parse the header for information about base and timestamps."""
+ base_regex = r"base\s+(?P\w+)\s+timestamps\s+(?P\w+)"
+ for _ in range(MAX_HEADER_ROW_LENGTH):
+ line = self.file.readline()
+ if line.startswith(BEGIN_TRIGGERBLOCK):
+ break # Header end
+ m = re.search(base_regex, line)
+ if m:
+ base = m.group("base")
+ if base not in BASES:
+ raise ValueError("Support for base %s not implemented" % base)
+ self.base = BASES[base]
+ self.absolute_timestamps = m.group("timestamps") == "absolute"
+
+ def _extract_can_id(self, str_can_id):
if str_can_id[-1:].lower() == "x":
is_extended = True
- can_id = int(str_can_id[0:-1], 16)
+ can_id = int(str_can_id[0:-1], self.base)
else:
is_extended = False
- can_id = int(str_can_id, 16)
+ can_id = int(str_can_id, self.base)
return can_id, is_extended
def __iter__(self):
@@ -108,7 +133,7 @@ def __iter__(self):
frame = bytearray()
data = data.split()
for byte in data[0:dlc]:
- frame.append(int(byte, 16))
+ frame.append(int(byte, self.base))
can_id_num, is_extended_id = self._extract_can_id(can_id_str)