@@ -91,10 +91,10 @@ def is_correct_format(cls, fileobj):
9191 otherwise returns False.
9292 """
9393 with Opener (fileobj ) as f :
94- magic_number = asstr ( f . fobj . readline ( ))
95- f .seek (- len (magic_number ), os .SEEK_CUR )
94+ magic_number = f . read ( len ( cls . MAGIC_NUMBER ))
95+ f .seek (- len (cls . MAGIC_NUMBER ), os .SEEK_CUR )
9696
97- return magic_number . strip ( ) == cls .MAGIC_NUMBER
97+ return asstr ( magic_number ) == cls .MAGIC_NUMBER
9898
9999 @classmethod
100100 def create_empty_header (cls ):
@@ -287,8 +287,8 @@ def _write_header(fileobj, header):
287287 fileobj .write (asbytes (str (new_offset ) + "\n " ))
288288 fileobj .write (asbytes ("END\n " ))
289289
290- @staticmethod
291- def _read_header (fileobj ):
290+ @classmethod
291+ def _read_header (cls , fileobj ):
292292 """ Reads a TCK header from a file.
293293
294294 Parameters
@@ -304,23 +304,56 @@ def _read_header(fileobj):
304304 header : dict
305305 Metadata associated with this tractogram file.
306306 """
307- # Record start position if this is a file-like object
308- start_position = fileobj .tell () if hasattr (fileobj , 'tell' ) else None
307+
308+ # Build header dictionary from the buffer
309+ hdr = {}
310+ offset_data = 0
309311
310312 with Opener (fileobj ) as f :
313+
314+ # Record start position
315+ start_position = f .tell ()
316+
317+ # Make sure we are at the beginning of the file
318+ f .seek (0 , os .SEEK_SET )
319+
311320 # Read magic number
312- magic_number = f .fobj .readline ().strip ()
321+ magic_number = f .read (len (cls .MAGIC_NUMBER ))
322+
323+ if asstr (magic_number ) != cls .MAGIC_NUMBER :
324+ raise HeaderError (f"Invalid magic number: { magic_number } " )
325+
326+ hdr [Field .MAGIC_NUMBER ] = magic_number
313327
314- # Read all key-value pairs contained in the header.
315- buf = asstr (f .fobj .readline ())
316- while not buf .rstrip ().endswith ("END" ):
317- buf += asstr (f .fobj .readline ())
328+ f .seek (1 , os .SEEK_CUR ) # Skip \n
329+
330+ found_end = False
331+
332+ # Read all key-value pairs contained in the header, stop at EOF
333+ for n_line , line in enumerate (f , 1 ):
334+ line = asstr (line ).strip ()
335+
336+ if not line : # Skip empty lines
337+ continue
338+
339+ if line == "END" : # End of the header
340+ found_end = True
341+ break
342+
343+ if ':' not in line : # Invalid header line
344+ raise HeaderError (f"Invalid header (line { n_line } ): { line } " )
345+
346+ key , value = line .split (":" , 1 )
347+ hdr [key .strip ()] = value .strip ()
348+
349+ if not found_end :
350+ raise HeaderError ("Missing END in the header." )
318351
319352 offset_data = f .tell ()
320353
321- # Build header dictionary from the buffer.
322- hdr = dict ( item . split ( ': ' ) for item in buf . rstrip (). split ( ' \n ' )[: - 1 ])
323- hdr [ Field . MAGIC_NUMBER ] = magic_number
354+ # Set the file position where it was, in case it was previously open
355+ if start_position is not None :
356+ f . seek ( start_position , os . SEEK_SET )
324357
325358 # Check integrity of TCK header.
326359 if 'datatype' not in hdr :
@@ -352,10 +385,6 @@ def _read_header(fileobj):
352385 # Keep the file position where the data begin.
353386 hdr ['_offset_data' ] = int (hdr ['file' ].split ()[1 ])
354387
355- # Set the file position where it was, if it was previously open.
356- if start_position is not None :
357- fileobj .seek (start_position , os .SEEK_SET )
358-
359388 return hdr
360389
361390 @classmethod
0 commit comments