77import struct
88
99from abc import ABC , abstractmethod
10+ from typing_extensions import deprecated
1011
1112from mcap_protobuf .decoder import DecoderFactory
1213from mcap .reader import make_reader
@@ -139,40 +140,38 @@ def __iter__(self):
139140 def close (self ):
140141 return self .reader .close ()
141142
143+ @deprecated ("This is a legacy interface only supported for single-channel traces, which will be removed in future versions." )
142144 def retrieve_offsets (self , limit = None ):
143145 if isinstance (self .reader , OSITraceSingle ):
144146 return self .reader .retrieve_offsets (limit )
145147 raise NotImplementedError ("Offsets are only supported for single-channel traces." )
146148
149+ @deprecated ("This is a legacy interface only supported for single-channel traces, which will be removed in future versions." )
147150 def retrieve_message (self , index = None , skip = False ):
148151 if isinstance (self .reader , OSITraceSingle ):
149152 return self .reader .retrieve_message (index , skip )
150153 raise NotImplementedError ("Index-based message retrieval is only supported for single-channel traces." )
151154
155+ @deprecated ("This is a legacy interface only supported for single-channel traces, which will be removed in future versions." )
152156 def get_message_by_index (self , index ):
153157 if isinstance (self .reader , OSITraceSingle ):
154158 return self .reader .get_message_by_index (index )
155159 raise NotImplementedError ("Index-based message retrieval is only supported for single-channel traces." )
156160
161+ @deprecated ("This is a legacy interface only supported for single-channel traces, which will be removed in future versions." )
157162 def get_messages_in_index_range (self , begin , end ):
158163 if isinstance (self .reader , OSITraceSingle ):
159164 return self .reader .get_messages_in_index_range (begin , end )
160165 raise NotImplementedError ("Index-based message retrieval is only supported for single-channel traces." )
161166
162167 def get_available_topics (self ):
163- if isinstance (self .reader , OSITraceMulti ):
164- return self .reader .get_available_topics ()
165- raise NotImplementedError ("Getting available topics is only supported for multi-channel traces." )
168+ return self .reader .get_available_topics ()
166169
167170 def get_file_metadata (self ):
168- if isinstance (self .reader , OSITraceMulti ):
169- return self .reader .get_file_metadata ()
170- raise NotImplementedError ("Getting file metadata is only supported for multi-channel traces." )
171+ return self .reader .get_file_metadata ()
171172
172173 def get_channel_metadata (self ):
173- if isinstance (self .reader , OSITraceMulti ):
174- return self .reader .get_channel_metadata ()
175- raise NotImplementedError ("Getting channel metadata is only supported for multi-channel traces." )
174+ return self .reader .get_channel_metadata ()
176175
177176
178177class ReaderBase (ABC ):
@@ -190,6 +189,18 @@ def __iter__(self):
190189 def close (self ):
191190 pass
192191
192+ @abstractmethod
193+ def get_available_topics (self ):
194+ pass
195+
196+ @abstractmethod
197+ def get_file_metadata (self ):
198+ pass
199+
200+ @abstractmethod
201+ def get_channel_metadata (self ):
202+ pass
203+
193204
194205class OSITraceSingle (ReaderBase ):
195206 """OSI single-channel trace reader"""
@@ -203,21 +214,16 @@ def __init__(self, path=None, type_name="SensorView", cache_messages=False):
203214 self .message_cache = {} if cache_messages else None
204215 self ._header_length = 4
205216 if path :
206- self .from_file (path , type_name , cache_messages )
207-
208- def from_file (self , path , type_name = "SensorView" , cache_messages = False ):
209- """Import a trace from a file"""
210- self .type = OSITrace .map_message_type (type_name )
217+ self .type = OSITrace .map_message_type (type_name )
211218
212- if path .suffix .lower () in [".lzma" , ".xz" ]:
213- self .file = lzma .open (path , "rb" )
214- else :
215- self .file = open (path , "rb" )
216-
217- self .read_complete = False
218- self .current_index = 0
219- self .message_offsets = [0 ]
220- self .message_cache = {} if cache_messages else None
219+ if path .suffix .lower () in [".lzma" , ".xz" ]:
220+ self .file = lzma .open (path , "rb" )
221+ else :
222+ self .file = open (path , "rb" )
223+ self .read_complete = False
224+ self .current_index = 0
225+ self .message_offsets = [0 ]
226+ self .message_cache = {} if cache_messages else None
221227
222228 def retrieve_offsets (self , limit = None ):
223229 """Retrieve the offsets of the messages from the file."""
@@ -337,6 +343,15 @@ def close(self):
337343 self .read_limit = None
338344 self .type = None
339345
346+ def get_available_topics (self ):
347+ raise NotImplementedError ("Getting available topics is only supported for multi-channel traces." )
348+
349+ def get_file_metadata (self ):
350+ raise NotImplementedError ("Getting file metadata is only supported for multi-channel traces." )
351+
352+ def get_channel_metadata (self ):
353+ raise NotImplementedError ("Getting channel metadata is only supported for multi-channel traces." )
354+
340355
341356class OSITraceMulti (ReaderBase ):
342357 """OSI multi-channel trace reader"""
@@ -387,7 +402,7 @@ def get_channel_metadata(self):
387402 if channel .topic == self .topic :
388403 return channel .metadata
389404 return None
390-
405+
391406 def get_message_type (self ):
392407 for channel in self ._summary .channels .values ():
393408 if channel .topic == self .topic :
@@ -397,7 +412,7 @@ def get_message_type(self):
397412 else :
398413 raise ValueError (f"Schema '{ schema .name } ' is not an 'osi3.' schema." )
399414 return None
400-
415+
401416 def _channel_is_of_type (self , channel , type_name ):
402417 schema = self ._summary .schemas [channel .schema_id ]
403418 return type_name is None or schema .name == f"osi3.{ type_name } "
0 commit comments