1111import os
1212from datetime import datetime , timedelta , timezone
1313from enum import Enum
14- from typing import Any , Callable , Dict , Generator , List , Optional , TextIO , Union
14+ from typing import (
15+ Any ,
16+ Callable ,
17+ Dict ,
18+ Generator ,
19+ List ,
20+ Mapping ,
21+ Optional ,
22+ TextIO ,
23+ Tuple ,
24+ Union ,
25+ )
1526
1627from ..message import Message
1728from ..typechecking import StringPathLike
@@ -257,18 +268,19 @@ class TRCWriter(TextIOMessageWriter):
257268 file : TextIO
258269 first_timestamp : Optional [float ]
259270
260- FORMAT_MESSAGE = (
261- "{msgnr:>7} {time:13.3f} DT {channel:>2} {id:>8} {dir:>2} - {dlc:<4} {data}"
262- )
263- FORMAT_MESSAGE_V1_1 = "{msgnr:>6}){time:12.3f} Rx {id:>8} {dlc:<1} {data}"
264-
265- FORMAT_MESSAGE_V1_0 = "{msgnr:>6}) {time:7.0f} {id:>8} {dlc:<1} {data}"
271+ MESSAGE_FORMAT_MAP : Mapping [TRCFileVersion , str ] = {
272+ TRCFileVersion .V1_0 : "{msgnr:>6}) {time:7.0f} {id:>8} {dlc:<1} {data}" ,
273+ TRCFileVersion .V1_1 : "{msgnr:>6}){time:12.3f} Rx {id:>8} {dlc:<1} {data}" ,
274+ TRCFileVersion .V2_1 : (
275+ "{msgnr:>7} {time:13.3f} DT {channel:>2} {id:>8} {dir:>2} - {dlc:<4} {data}"
276+ ),
277+ }
266278
267279 def __init__ (
268280 self ,
269281 file : Union [StringPathLike , TextIO ],
270282 channel : int = 1 ,
271- fileversion : int = TRCFileVersion .V2_1 ,
283+ file_version : Union [ int , TRCFileVersion ] = TRCFileVersion .V1_0 ,
272284 ** kwargs : Any ,
273285 ) -> None :
274286 """
@@ -278,6 +290,12 @@ def __init__(
278290 :param channel: a default channel to use when the message does not
279291 have a channel set
280292 """
293+ if kwargs .get ("append" , False ):
294+ raise ValueError (
295+ f"{ self .__class__ .__name__ } is currently not equipped to "
296+ f"append messages to an existing file."
297+ )
298+
281299 super ().__init__ (file , mode = "w" )
282300 self .channel = channel
283301
@@ -289,10 +307,19 @@ def __init__(
289307 self .filepath = os .path .abspath (self .file .name )
290308 self .header_written = False
291309 self .msgnr = 0
292- self .first_timestamp = None
293- self .file_version = fileversion
294- self ._msg_fmt_string = self .FORMAT_MESSAGE_V1_0
295- self ._format_message = self ._format_message_init
310+ self .first_timestamp : Optional [float ] = None
311+ self .file_version , self ._msg_fmt_string = self ._parse_version (file_version )
312+
313+ def _parse_version (
314+ self , file_version : Union [int , TRCFileVersion ]
315+ ) -> Tuple [TRCFileVersion , str ]:
316+ try :
317+ version = TRCFileVersion (file_version )
318+ msg_fmt_string = self .MESSAGE_FORMAT_MAP [version ]
319+ return version , msg_fmt_string
320+ except (KeyError , ValueError ) as exc :
321+ err_msg = f"File version is not supported: { file_version } "
322+ raise NotImplementedError (err_msg ) from exc
296323
297324 def _write_header_v1_0 (self , start_time : datetime ) -> None :
298325 lines = [
@@ -316,7 +343,7 @@ def _write_header_v1_0(self, start_time: datetime) -> None:
316343 self .file .writelines (line + "\n " for line in lines )
317344
318345 def _write_header_v1_1 (self , start_time : datetime ) -> None :
319- header_time = start_time - datetime (year = 1899 , month = 12 , day = 30 )
346+ header_time = start_time - datetime (year = 1899 , month = 12 , day = 30 )
320347 lines = [
321348 ";$FILEVERSION=1.1" ,
322349 f";$STARTTIME={ header_time / timedelta (days = 1 )} " ,
@@ -337,11 +364,10 @@ def _write_header_v1_1(self, start_time: datetime) -> None:
337364 "; | | | | Data Length" ,
338365 "; | | | | | Data Bytes (hex) ..." ,
339366 "; | | | | | |" ,
340- ";---+-- ----+---- --+-- ----+--- + -+ -- -- -- -- -- -- --" ,
367+ ";---+-- ----+---- --+-- ----+--- + -+ -- -- -- -- -- -- --" ,
341368 ]
342369 self .file .writelines (line + "\n " for line in lines )
343370
344-
345371 def _write_header_v2_1 (self , start_time : datetime ) -> None :
346372 header_time = start_time - datetime (year = 1899 , month = 12 , day = 30 )
347373 lines = [
@@ -366,7 +392,7 @@ def _write_header_v2_1(self, start_time: datetime) -> None:
366392 ]
367393 self .file .writelines (line + "\n " for line in lines )
368394
369- def _format_message_by_format (self , msg , channel ) :
395+ def _format_message (self , msg : Message , channel : int ) -> str :
370396 if msg .is_extended_id :
371397 arb_id = f"{ msg .arbitration_id :07X} "
372398 else :
@@ -376,7 +402,7 @@ def _format_message_by_format(self, msg, channel):
376402
377403 serialized = self ._msg_fmt_string .format (
378404 msgnr = self .msgnr ,
379- time = (msg .timestamp - self .first_timestamp ) * 1000 ,
405+ time = (msg .timestamp - ( self .first_timestamp or 0.0 ) ) * 1000 ,
380406 channel = channel ,
381407 id = arb_id ,
382408 dir = "Rx" if msg .is_rx else "Tx" ,
@@ -385,28 +411,13 @@ def _format_message_by_format(self, msg, channel):
385411 )
386412 return serialized
387413
388- def _format_message_init (self , msg , channel ):
389- if self .file_version == TRCFileVersion .V1_0 :
390- self ._format_message = self ._format_message_by_format
391- self ._msg_fmt_string = self .FORMAT_MESSAGE_V1_0
392- elif self .file_version == TRCFileVersion .V2_1 :
393- self ._format_message = self ._format_message_by_format
394- self ._msg_fmt_string = self .FORMAT_MESSAGE
395- elif self .file_version == TRCFileVersion .V1_1 :
396- self ._format_message = self ._format_message_by_format
397- self ._msg_fmt_string = self .FORMAT_MESSAGE_V1_1
398- else :
399- raise NotImplementedError ("File format is not supported" )
400-
401- return self ._format_message_by_format (msg , channel )
402-
403414 def write_header (self , timestamp : float ) -> None :
404415 # write start of file header
405416 start_time = datetime .utcfromtimestamp (timestamp )
406417
407418 if self .file_version == TRCFileVersion .V1_0 :
408419 self ._write_header_v1_0 (start_time )
409- elif self .file_version == TRCFileVersion .V1_1 :
420+ elif self .file_version == TRCFileVersion .V1_1 :
410421 self ._write_header_v1_1 (start_time )
411422 elif self .file_version == TRCFileVersion .V2_1 :
412423 self ._write_header_v2_1 (start_time )
0 commit comments