@@ -129,11 +129,11 @@ def get_affine_rasmm_to_trackvis(header):
129129
130130
131131def encode_value_in_name (value , name , max_name_len = 20 ):
132- """ Encodes a value in the last two bytes of a string.
132+ """ Encodes a value in the last bytes of a string.
133133
134- If `value` is one, then there is no encoding and the last two bytes
135- are left untouched. Otherwise, the byte before the last will be
136- set to \x00 and the last byte will correspond to the value.
134+ If `value` is one, then there is no encoding and the last bytes
135+ are left untouched. Otherwise, a \x00 byte is added after `name`
136+ and followed by the ascii represensation of the value.
137137
138138 This function also verifies that the length of name is less
139139 than `max_name_len`.
@@ -157,20 +157,56 @@ def encode_value_in_name(value, name, max_name_len=20):
157157 msg = ("Data information named '{0}' is too long"
158158 " (max {1} characters.)" ).format (name , max_name_len )
159159 raise ValueError (msg )
160- elif len ( name ) > max_name_len - 2 and value > 1 :
160+ elif value > 1 and len ( name ) + len ( str ( value )) + 1 > max_name_len :
161161 msg = ("Data information named '{0}' is too long (need to be less"
162162 " than {1} characters when storing more than one value"
163163 " for a given data information."
164- ).format (name , max_name_len - 2 )
164+ ).format (name , max_name_len - ( len ( str ( value )) + 1 ) )
165165 raise ValueError (msg )
166166
167- name = name . ljust ( max_name_len , ' \x00 ' )
167+ encoded_name = name
168168 if value > 1 :
169- # Use the last two bytes of `name` to store `value`.
170- name = (asbytes (name [:max_name_len - 2 ]) + b'\x00 ' +
171- np .array (value , dtype = np .int8 ).tostring ())
169+ # Store the name followed by \x00 and the `value` (in ascii).
170+ encoded_name += '\x00 ' + str (value )
172171
173- return name
172+ encoded_name = encoded_name .ljust (max_name_len , '\x00 ' )
173+ return encoded_name
174+
175+
176+ def decode_value_from_name (encoded_name ):
177+ """ Decodes a value that has been encoded in the last bytes of a string.
178+
179+ Check :func:`encode_value_in_name` to see how the value has been encoded.
180+
181+ Parameters
182+ ----------
183+ encoded_name : bytes
184+ Name in which a value has been encoded or not.
185+
186+ Returns
187+ -------
188+ name : bytes
189+ Name without the encoded value.
190+ value : int
191+ Value decoded from the name.
192+ """
193+ encoded_name = asstr (encoded_name )
194+ if len (encoded_name ) == 0 :
195+ return encoded_name , 0
196+
197+ splits = encoded_name .rstrip ('\x00 ' ).split ('\x00 ' )
198+ name = splits [0 ]
199+ value = 1
200+
201+ if len (splits ) == 2 :
202+ value = int (splits [1 ]) # Decode value.
203+ elif len (splits ) > 2 :
204+ # The remaining bytes are not \x00, raising.
205+ msg = ("Wrong scalar_name or property_name: '{}'."
206+ " Unused characters should be \\ x00." ).format (name )
207+ raise HeaderError (msg )
208+
209+ return name , value
174210
175211
176212def create_empty_header ():
@@ -289,17 +325,11 @@ def load(cls, fileobj, lazy_load=False):
289325 if hdr [Field .NB_SCALARS_PER_POINT ] > 0 :
290326 cpt = 0
291327 for scalar_name in hdr ['scalar_name' ]:
292- scalar_name = asstr (scalar_name )
293- if len (scalar_name ) == 0 :
294- continue
328+ scalar_name , nb_scalars = decode_value_from_name (scalar_name )
295329
296- # Check if we encoded the number of values we stocked for this
297- # scalar name.
298- nb_scalars = 1
299- if scalar_name [- 2 ] == '\x00 ' and scalar_name [- 1 ] != '\x00 ' :
300- nb_scalars = int (np .fromstring (scalar_name [- 1 ], np .int8 ))
330+ if nb_scalars == 0 :
331+ continue
301332
302- scalar_name = scalar_name .split ('\x00 ' )[0 ]
303333 slice_obj = slice (cpt , cpt + nb_scalars )
304334 data_per_point_slice [scalar_name ] = slice_obj
305335 cpt += nb_scalars
@@ -312,18 +342,12 @@ def load(cls, fileobj, lazy_load=False):
312342 if hdr [Field .NB_PROPERTIES_PER_STREAMLINE ] > 0 :
313343 cpt = 0
314344 for property_name in hdr ['property_name' ]:
315- property_name = asstr (property_name )
316- if len (property_name ) == 0 :
317- continue
345+ results = decode_value_from_name (property_name )
346+ property_name , nb_properties = results
318347
319- # Check if we encoded the number of values we stocked for this
320- # property name.
321- nb_properties = 1
322- if property_name [- 2 ] == '\x00 ' and property_name [- 1 ] != '\x00 ' :
323- nb_properties = int (np .fromstring (property_name [- 1 ],
324- np .int8 ))
348+ if nb_properties == 0 :
349+ continue
325350
326- property_name = property_name .split ('\x00 ' )[0 ]
327351 slice_obj = slice (cpt , cpt + nb_properties )
328352 data_per_streamline_slice [property_name ] = slice_obj
329353 cpt += nb_properties
0 commit comments