@@ -91,10 +91,10 @@ 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 = f . read ( len ( cls . MAGIC_NUMBER ))
95
+ f .seek (- len (cls . MAGIC_NUMBER ), os .SEEK_CUR )
96
96
97
- return magic_number . strip ( ) == cls .MAGIC_NUMBER
97
+ return asstr ( magic_number ) == cls .MAGIC_NUMBER
98
98
99
99
@classmethod
100
100
def create_empty_header (cls ):
@@ -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,56 @@ 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 .tell ()
316
+
317
+ # Make sure we are at the beginning of the file
318
+ f .seek (0 , os .SEEK_SET )
319
+
311
320
# 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
313
327
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." )
318
351
319
352
offset_data = f .tell ()
320
353
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 )
324
357
325
358
# Check integrity of TCK header.
326
359
if 'datatype' not in hdr :
@@ -352,10 +385,6 @@ def _read_header(fileobj):
352
385
# Keep the file position where the data begin.
353
386
hdr ['_offset_data' ] = int (hdr ['file' ].split ()[1 ])
354
387
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
388
return hdr
360
389
361
390
@classmethod
0 commit comments