@@ -91,8 +91,8 @@ def is_correct_format(cls, fileobj):
91
91
otherwise returns False.
92
92
"""
93
93
with Opener (fileobj ) as f :
94
- magic_number = asstr (f .fobj .readline ( ))
95
- f .seek (- len (magic_number ), os .SEEK_CUR )
94
+ magic_number = asstr (f .fobj .read ( len ( cls . MAGIC_NUMBER ) ))
95
+ f .seek (- len (cls . MAGIC_NUMBER ), os .SEEK_CUR )
96
96
97
97
return magic_number .strip () == cls .MAGIC_NUMBER
98
98
@@ -287,8 +287,8 @@ def _write_header(fileobj, header):
287
287
fileobj .write (asbytes (str (new_offset ) + "\n " ))
288
288
fileobj .write (asbytes ("END\n " ))
289
289
290
- @staticmethod
291
- def _read_header (fileobj ):
290
+ @classmethod
291
+ def _read_header (cls , fileobj ):
292
292
""" Reads a TCK header from a file.
293
293
294
294
Parameters
@@ -304,23 +304,50 @@ def _read_header(fileobj):
304
304
header : dict
305
305
Metadata associated with this tractogram file.
306
306
"""
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
309
311
310
312
with Opener (fileobj ) as f :
313
+
314
+ # Record start position
315
+ start_position = f .fobj .tell ()
316
+
317
+ # Make sure we are at the beginning of the file
318
+ f .fobj .seek (0 , os .SEEK_SET )
319
+
311
320
# Read magic number
312
- magic_number = f .fobj .readline ().strip ()
321
+ magic_number = asstr (f .fobj .read (len (cls .MAGIC_NUMBER )))
322
+
323
+ if magic_number != cls .MAGIC_NUMBER :
324
+ raise HeaderError (f"Invalid magic number: { magic_number } " )
313
325
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 ())
326
+ hdr [Field .MAGIC_NUMBER ] = magic_number
327
+
328
+ f .fobj .seek (1 , os .SEEK_CUR ) # Skip \n
329
+
330
+ # Read all key-value pairs contained in the header
331
+ for n_line , line in enumerate (f .fobj , 1 ):
332
+ line = asstr (line ).strip ()
333
+
334
+ if not line : # Skip empty lines
335
+ continue
336
+
337
+ if line == "END" : # End of the header
338
+ break
339
+
340
+ if ':' not in line : # Invalid header line
341
+ raise HeaderError (f"Invalid header (line { n_line } ): { line } " )
342
+
343
+ key , value = line .split (":" , 1 )
344
+ hdr [key .strip ()] = value .strip ()
318
345
319
346
offset_data = f .tell ()
320
347
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
348
+ # Set the file position where it was, in case it was previously open
349
+ if start_position is not None :
350
+ f . fobj . seek ( start_position , os . SEEK_SET )
324
351
325
352
# Check integrity of TCK header.
326
353
if 'datatype' not in hdr :
@@ -352,10 +379,6 @@ def _read_header(fileobj):
352
379
# Keep the file position where the data begin.
353
380
hdr ['_offset_data' ] = int (hdr ['file' ].split ()[1 ])
354
381
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
-
359
382
return hdr
360
383
361
384
@classmethod
0 commit comments