@@ -11,6 +11,15 @@ class UMFileException(Exception):
11
11
pass
12
12
13
13
14
+ LBLREC = 14
15
+ LBROW = 17
16
+ LBNPT = 18
17
+ LBEXT = 19
18
+ LBPACK = 20
19
+ LBEGIN = 28
20
+ LBNREC = 29
21
+
22
+
14
23
class File :
15
24
"""A class for a UM file that gives a view of the file including
16
25
sets of PP records combined into variables."""
@@ -34,7 +43,7 @@ def __init__(
34
43
'little_endian' or 'big_endian'
35
44
36
45
word_size: `int`, optional
37
- 4 or 8
46
+ The size in bytes of one word. Either ``4`` or ``8``.
38
47
39
48
fmt: `str`, optional
40
49
'FF' or 'PP'
@@ -280,8 +289,13 @@ def __init__(
280
289
if file :
281
290
self .file = file
282
291
292
+ # import cf; pp = cf.umread_lib.umfile.File('/home/david/test2.pp', fmt='PP', byte_ordering= 'little_endian' , word_size=4, parse=False)
293
+ # cf.umread_lib.umfile.Rec.from_file_and_offsets(pp, 4, 268, 46640)
294
+
283
295
@classmethod
284
- def from_file_and_offsets (cls , file , hdr_offset , data_offset , disk_length ):
296
+ def from_file_and_offsets (
297
+ cls , file , hdr_offset , data_offset = None , disk_length = None
298
+ ):
285
299
"""Instantiate a `Rec` object from the `File` object and the
286
300
header and data offsets.
287
301
@@ -295,24 +309,59 @@ def from_file_and_offsets(cls, file, hdr_offset, data_offset, disk_length):
295
309
into variables.
296
310
297
311
hdr_offset: `int`
298
- The start word in the file of the header.
312
+ The file start address of the header, in bytes .
299
313
300
- data_offset: `int`
301
- The start word in the file of the data.
314
+ data_offset: `int`, optional
315
+ The file start address of the data, in bytes. If
316
+ `None`, the default, then the data offset will be
317
+ calculated from the integer header.
302
318
303
319
disk_length: `int`
304
- The length in words of the data in the file.
320
+ The length in bytes of the data in the file. If
321
+ `None`, the default, then the disk length will be
322
+ calculated from the integer header.
305
323
306
324
:Returns:
307
325
308
326
`Rec`
309
327
310
328
"""
311
329
c = file ._c_interface
330
+ word_size = file .word_size
312
331
int_hdr , real_hdr = c .read_header (
313
- file .fd , hdr_offset , file .byte_ordering , file . word_size
332
+ file .fd , hdr_offset , file .byte_ordering , word_size
314
333
)
315
-
334
+ PP = file .fmt == "PP"
335
+ print (c .lib .arse )
336
+ if data_offset is None :
337
+ # Calculate the data offset from the integer header
338
+ if PP :
339
+ # We only support 64-word headers, so the data starts
340
+ # 66 words after the header, i.e. 64 words of the
341
+ # header plus two block control words.
342
+ data_offset = hdr_offset + 66 * word_size
343
+ else :
344
+ # Fields file
345
+ data_offset = int_hdr [LBEGIN ] * word_size
346
+
347
+ if disk_length is None :
348
+ # Calculate the disk length from the integer header
349
+ lbpack = int_hdr [LBPACK ]
350
+ lbnrec = int_hdr [LBNREC ]
351
+ lblrec = int_hdr [LBLREC ]
352
+
353
+ if not lbpack :
354
+ disk_length = (lblrec - int_hdr [LBEXT ]) * word_size
355
+ elif lbpack != 0 and lblrec * word_size :
356
+ disk_length = lblrec * word_size
357
+ elif lbpack % 10 == 2 :
358
+ lbnpt = int_hdr [LBNPT ]
359
+ lbrow = int_hdr [LBROW ]
360
+ if lbnpt > 0 and lbrow > 0 :
361
+ disk_length = lbnpt * lbrow * 4
362
+ else :
363
+ disk_length = (lblrec - int_hdr [LBEXT ]) * 4
364
+
316
365
return cls (
317
366
int_hdr , real_hdr , hdr_offset , data_offset , disk_length , file = file
318
367
)
0 commit comments