48
48
)
49
49
50
50
51
- def readCString (f , nStrings = 1 , bufsize = 1000 , startPos = None , strip = True ,
52
- rewind = False ):
51
+ def read_c_string (f , n_strings = 1 , bufsize = 1000 , start_pos = None , strip = True ,
52
+ rewind = False ):
53
53
"""Read a zero-terminated string from a file object.
54
54
55
55
Read and return a zero-terminated string from a file object.
56
56
57
57
Parameters
58
58
----------
59
59
f : fileobj
60
- File object to use
61
- nStrings : int, optional
60
+ File object to use. Object should implement tell, seek, and read.
61
+ n_strings : int, optional
62
62
Number of strings to search (and return). Default is 1.
63
63
bufsize: int, optional
64
64
Define the buffer size that should be searched for the string.
65
65
Default is 1000 bytes.
66
- startPos : int, optional
66
+ start_pos : int, optional
67
67
Define the start file position from which to search. If None then start
68
68
where the file object currently points to. Default is None.
69
69
strip : bool, optional
@@ -77,24 +77,19 @@ def readCString(f, nStrings=1, bufsize=1000, startPos=None, strip=True,
77
77
-------
78
78
str_list : generator of string(s)
79
79
"""
80
- currentPos = f .tell ()
81
- if strip :
82
- suffix = b''
83
- else :
84
- suffix = b'\x00 '
85
- if startPos is not None :
86
- f .seek (startPos )
80
+ current_pos = f .tell ()
81
+ suffix = b'' if strip else b'\x00 '
82
+ if start_pos is not None :
83
+ f .seek (start_pos )
87
84
data = f .read (bufsize )
88
85
lines = data .split (b'\x00 ' )
89
86
str_list = []
90
87
if rewind :
91
- f .seek (currentPos )
88
+ f .seek (current_pos )
92
89
else :
93
- offset = 0
94
- for s in range (nStrings ):
95
- offset += len (lines [s ]) + 1
96
- f .seek (currentPos + offset )
97
- for s in range (nStrings ):
90
+ offsets = [len (lines [s ]) + 1 for s in range (n_strings )]
91
+ f .seek (current_pos + sum (offsets ))
92
+ for s in range (n_strings ):
98
93
str_list .append (lines [s ] + suffix )
99
94
return str_list
100
95
@@ -111,8 +106,10 @@ def parse_BV_header(hdr_dict_proto, fileobj, parent_hdr_dict=None):
111
106
tuple of format described in Notes below.
112
107
fileobj : fileobj
113
108
File object to use. Make sure that the current position is at the
114
- beginning of the header (e.g. at 0).
115
- parent_hdr_dict: OrderedDict
109
+ beginning of the header (e.g. at 0). Object should implement tell,
110
+ seek, and read.
111
+ parent_hdr_dict: None or OrderedDict, optional
112
+ Default is None. None results in empty `OrderedDict`.
116
113
When parse_BV_header() is called recursively the already filled
117
114
(parent) hdr_dict is passed to give access to n_fields_name fields
118
115
outside the current scope (see below).
@@ -158,30 +155,30 @@ def parse_BV_header(hdr_dict_proto, fileobj, parent_hdr_dict=None):
158
155
'NrOfLags' in the VMP file header).
159
156
"""
160
157
hdr_dict = OrderedDict ()
161
- for name , format , def_or_name in hdr_dict_proto :
158
+ for name , pack_format , def_or_name in hdr_dict_proto :
162
159
# handle zero-terminated strings
163
- if format == 'z' :
164
- value = readCString (fileobj )[0 ]
160
+ if pack_format == 'z' :
161
+ value = read_c_string (fileobj )[0 ]
165
162
# handle array fields
166
- elif isinstance (format , tuple ):
163
+ elif isinstance (pack_format , tuple ):
167
164
value = []
168
165
# check the length of the array to expect
169
166
if def_or_name in hdr_dict :
170
167
n_values = hdr_dict [def_or_name ]
171
168
else :
172
169
n_values = parent_hdr_dict [def_or_name ]
173
170
for i in range (n_values ):
174
- value .append (parse_BV_header (format , fileobj , hdr_dict ))
171
+ value .append (parse_BV_header (pack_format , fileobj , hdr_dict ))
175
172
# handle conditional fields
176
173
elif isinstance (def_or_name , tuple ):
177
174
if hdr_dict [def_or_name [1 ]] == def_or_name [2 ]:
178
- bytes = fileobj .read (calcsize (format ))
179
- value = unpack ('<' + format , bytes )[0 ]
175
+ raw_bytes = fileobj .read (calcsize (pack_format ))
176
+ value = unpack ('<' + pack_format , raw_bytes )[0 ]
180
177
else : # assign the default value
181
178
value = def_or_name [0 ]
182
- else : # unpack bytes of type format
183
- bytes = fileobj .read (calcsize (format ))
184
- value = unpack ('<' + format , bytes )[0 ]
179
+ else : # unpack raw_bytes of type pack_format
180
+ raw_bytes = fileobj .read (calcsize (pack_format ))
181
+ value = unpack ('<' + pack_format , raw_bytes )[0 ]
185
182
hdr_dict [name ] = value
186
183
return hdr_dict
187
184
@@ -197,43 +194,45 @@ def pack_BV_header(hdr_dict_proto, hdr_dict, parent_hdr_dict=None):
197
194
hdr_dict_proto: tuple
198
195
tuple of format described in Notes of :func:`parse_BV_header`
199
196
hdr_dict: OrderedDict
200
- hdr_dict that contains the fields and values to for the respective
201
- BV file format.
202
- parent_hdr_dict: OrderedDict
203
- When parse_BV_header() is called recursively the already filled
204
- (parent) hdr_dict is passed to give access to n_fields_name fields
205
- outside the current scope (see below).
197
+ hdr_dict that contains the fields and values to for the respective
198
+ BV file format.
199
+ parent_hdr_dict: None or OrderedDict, optional
200
+ Default is None. None results in empty `OrderedDict`.
201
+ When parse_BV_header() is called recursively the already filled
202
+ (parent) hdr_dict is passed to give access to n_fields_name fields
203
+ outside the current scope (see below).
206
204
207
205
Returns
208
206
-------
209
207
binaryblock : bytes
210
208
Binary representation of header ready for writing to file.
211
209
"""
212
210
binary_parts = []
213
- for name , format , def_or_name in hdr_dict_proto :
211
+ for name , pack_format , def_or_name in hdr_dict_proto :
214
212
value = hdr_dict [name ]
215
213
# handle zero-terminated strings
216
- if format == 'z' :
214
+ if pack_format == 'z' :
217
215
part = value + b'\x00 '
218
216
# handle array fields
219
- elif isinstance (format , tuple ):
217
+ elif isinstance (pack_format , tuple ):
220
218
# check the length of the array to expect
221
219
if def_or_name in hdr_dict :
222
220
n_values = hdr_dict [def_or_name ]
223
221
else :
224
222
n_values = parent_hdr_dict [def_or_name ]
225
223
sub_parts = []
226
224
for i in range (n_values ):
227
- sub_parts .append (pack_BV_header (format , value [i ], hdr_dict ))
225
+ sub_parts .append (pack_BV_header (pack_format , value [i ],
226
+ hdr_dict ))
228
227
part = b'' .join (sub_parts )
229
228
# handle conditional fields
230
229
elif isinstance (def_or_name , tuple ):
231
230
if hdr_dict [def_or_name [1 ]] == def_or_name [2 ]:
232
- part = pack ('<' + format , value )
231
+ part = pack ('<' + pack_format , value )
233
232
else :
234
233
continue
235
234
else :
236
- part = pack ('<' + format , value )
235
+ part = pack ('<' + pack_format , value )
237
236
binary_parts .append (part )
238
237
return b'' .join (binary_parts )
239
238
@@ -249,26 +248,27 @@ def calc_BV_header_size(hdr_dict_proto, hdr_dict, parent_hdr_dict=None):
249
248
hdr_dict_proto: tuple
250
249
tuple of format described in Notes of :func:`parse_BV_header`
251
250
hdr_dict: OrderedDict
252
- hdr_dict that contains the fields and values to for the respective
253
- BV file format.
254
- parent_hdr_dict: OrderedDict
255
- When parse_BV_header() is called recursively the already filled
256
- (parent) hdr_dict is passed to give access to n_fields_name fields
257
- outside the current scope (see below).
251
+ hdr_dict that contains the fields and values to for the respective
252
+ BV file format.
253
+ parent_hdr_dict: None or OrderedDict, optional
254
+ Default is None. None results in empty `OrderedDict`.
255
+ When parse_BV_header() is called recursively the already filled
256
+ (parent) hdr_dict is passed to give access to n_fields_name fields
257
+ outside the current scope (see below).
258
258
259
259
Returns
260
260
-------
261
261
hdr_size : int
262
262
Size of header when packed into bytes ready for writing to file.
263
263
"""
264
264
hdr_size = 0
265
- for name , format , def_or_name in hdr_dict_proto :
265
+ for name , pack_format , def_or_name in hdr_dict_proto :
266
266
value = hdr_dict [name ]
267
267
# handle zero-terminated strings
268
- if format == 'z' :
268
+ if pack_format == 'z' :
269
269
hdr_size += len (value ) + 1
270
270
# handle array fields
271
- elif isinstance (format , tuple ):
271
+ elif isinstance (pack_format , tuple ):
272
272
# check the length of the array to expect
273
273
if def_or_name in hdr_dict :
274
274
n_values = hdr_dict [def_or_name ]
@@ -277,15 +277,16 @@ def calc_BV_header_size(hdr_dict_proto, hdr_dict, parent_hdr_dict=None):
277
277
for i in range (n_values ):
278
278
# recursively iterate through the fields of all items
279
279
# in the array
280
- hdr_size += calc_BV_header_size (format , value [i ], hdr_dict )
280
+ hdr_size += calc_BV_header_size (pack_format , value [i ],
281
+ hdr_dict )
281
282
# handle conditional fields
282
283
elif isinstance (def_or_name , tuple ):
283
284
if hdr_dict [def_or_name [1 ]] == def_or_name [2 ]:
284
- hdr_size += calcsize (format )
285
+ hdr_size += calcsize (pack_format )
285
286
else :
286
287
continue
287
288
else :
288
- hdr_size += calcsize (format )
289
+ hdr_size += calcsize (pack_format )
289
290
return hdr_size
290
291
291
292
@@ -319,9 +320,9 @@ def update_BV_header(hdr_dict_proto, hdr_dict_old, hdr_dict_new,
319
320
An updated version hdr_dict correcting effects of changed nested and
320
321
conditional fields.
321
322
"""
322
- for name , format , def_or_name in hdr_dict_proto :
323
+ for name , pack_format , def_or_name in hdr_dict_proto :
323
324
# handle nested loop fields
324
- if isinstance (format , tuple ):
325
+ if isinstance (pack_format , tuple ):
325
326
# calculate the change of array length and the new array length
326
327
if def_or_name in hdr_dict_old :
327
328
delta_values = hdr_dict_new [def_or_name ] - \
@@ -333,13 +334,14 @@ def update_BV_header(hdr_dict_proto, hdr_dict_old, hdr_dict_new,
333
334
n_values = parent_new [def_or_name ]
334
335
if delta_values > 0 : # add nested loops
335
336
for i in range (delta_values ):
336
- hdr_dict_new [name ].append (_proto2default (format , hdr_dict_new ))
337
+ hdr_dict_new [name ].append (_proto2default (pack_format ,
338
+ hdr_dict_new ))
337
339
elif delta_values < 0 : # remove nested loops
338
340
for i in range (abs (delta_values )):
339
341
hdr_dict_new [name ].pop ()
340
342
# loop over nested fields
341
343
for i in range (n_values ):
342
- update_BV_header (format , hdr_dict_old [name ][i ],
344
+ update_BV_header (pack_format , hdr_dict_old [name ][i ],
343
345
hdr_dict_new [name ][i ], hdr_dict_old ,
344
346
hdr_dict_new )
345
347
return hdr_dict_new
@@ -354,16 +356,16 @@ def _proto2default(proto, parent_default_hdr=None):
354
356
See :func:`parse_BV_header` for description of `proto` format.
355
357
"""
356
358
default_hdr = OrderedDict ()
357
- for name , format , def_or_name in proto :
358
- if isinstance (format , tuple ):
359
+ for name , pack_format , def_or_name in proto :
360
+ if isinstance (pack_format , tuple ):
359
361
value = []
360
362
# check the length of the array to expect
361
363
if def_or_name in default_hdr :
362
364
n_values = default_hdr [def_or_name ]
363
365
else :
364
366
n_values = parent_default_hdr [def_or_name ]
365
367
for i in range (n_values ):
366
- value .append (_proto2default (format , default_hdr ))
368
+ value .append (_proto2default (pack_format , default_hdr ))
367
369
default_hdr [name ] = value
368
370
# handle conditional fields
369
371
elif isinstance (def_or_name , tuple ):
0 commit comments