@@ -91,6 +91,7 @@ int mat_element_length(int type)
9191 int t = (type %10 );
9292 if (m ) return -1 ; /* We require IEEE Little Endian for now */
9393 if (o ) return -1 ; /* Reserved number; forced 0 */
94+ if (t == 1 && p == 0 ) return 8 ; /* Double text matrix? */
9495 if (t == 1 && p != 5 ) return -1 ; /* Text matrix? Force element length=1 */
9596 if (t == 2 ) return -1 ; /* Sparse matrix fails */
9697 switch (p ) {
@@ -152,6 +153,65 @@ void remSpaces(char *ch){
152153 }
153154}
154155
156+ /* Read n elements into str; convert from double if necessary, etc */
157+ static int read_chars (int type , size_t n , FILE * file , char * str )
158+ {
159+ int p = (type %100 )/10 ;
160+ if (p == 0 ) { /* Double */
161+ double d = 0.0 ;
162+ int k ;
163+ for (k = 0 ; k < n ; k ++ ) {
164+ if (fread (& d , sizeof (double ), 1 , file ) != 1 ) {
165+ return 1 ;
166+ }
167+ str [k ] = (char ) d ;
168+ }
169+ return 0 ;
170+ } else if (p == 5 ) { /* Byte */
171+ return fread (str ,n ,1 ,file ) != 1 ;
172+ }
173+ return 1 ;
174+ }
175+
176+ static int read_int32 (int type , size_t n , FILE * file , int32_t * val )
177+ {
178+ int p = (type %100 )/10 ;
179+ if (p == 0 ) { /* Double */
180+ double d = 0.0 ;
181+ int k ;
182+ for (k = 0 ; k < n ; k ++ ) {
183+ if (fread (& d , sizeof (double ), 1 , file ) != 1 ) {
184+ return 1 ;
185+ }
186+ val [k ] = (int32_t ) d ;
187+ }
188+ return 0 ;
189+ } else if (p == 2 ) { /* int32 */
190+ return fread (val ,n * sizeof (int32_t ),1 ,file ) != 1 ;
191+ }
192+ return 1 ;
193+ }
194+
195+ static int read_double (int type , size_t n , FILE * file , double * val )
196+ {
197+ int p = (type %100 )/10 ;
198+ if (p == 0 ) { /* Double */
199+ return fread (val ,n * sizeof (double ),1 ,file ) != 1 ;
200+ } else if (p == 1 ) { /* float */
201+ float f = 0.0 ;
202+ int k ;
203+ for (k = 0 ; k < n ; k ++ ) {
204+ if (fread (& f , sizeof (float ), 1 , file ) != 1 ) {
205+ return 1 ;
206+ }
207+ val [k ] = (double ) f ;
208+ }
209+ return 0 ;
210+ }
211+ return 1 ;
212+ }
213+
214+
155215/* Returns 0 on success; the error message on error */
156216const char * omc_new_matlab4_reader (const char * filename , ModelicaMatReader * reader )
157217{
@@ -172,16 +232,8 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
172232 int nr = fread (& hdr ,sizeof (MHeader_t ),1 ,reader -> file );
173233 size_t matrix_length ,element_length ;
174234 char * name ;
175- reader -> doublePrecision = 1 ;
176235 if (nr != 1 ) return "Corrupt header (1)" ;
177- /* fprintf(stderr, "Found matrix type=%04d mrows=%d ncols=%d imagf=%d namelen=%d\n", hdr.type, hdr.mrows, hdr.ncols, hdr.imagf, hdr.namelen); */
178- if (hdr .type != matrixTypes [i ])
179- {
180- if ((i > 3 ) && (hdr .type == 10 ))
181- reader -> doublePrecision = 0 ;
182- else
183- return "Matrix type mismatch" ;
184- }
236+ /* fprintf(stderr, "Found matrix %d=%s type=%04d mrows=%d ncols=%d imagf=%d namelen=%d\n", i, name, hdr.type, hdr.mrows, hdr.ncols, hdr.imagf, hdr.namelen); */
185237 if (hdr .imagf > 1 ) return "Matrix uses imaginary numbers" ;
186238 if ((element_length = mat_element_length (hdr .type )) == -1 ) return "Could not determine size of matrix elements" ;
187239 name = (char * ) malloc (hdr .namelen );
@@ -209,8 +261,8 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
209261 char tmp [45 ];
210262 if (hdr .mrows != 4 ) return "Aclass matrix does not have 4 rows" ;
211263 if (hdr .ncols != 11 ) return "Aclass matrix does not have 11 cols" ;
212- if ( fread ( tmp , hdr .ncols * hdr .mrows ,1 , reader -> file ) != 1 ) {
213- return "Corrupt header : Aclass matrix" ;
264+ if ( read_chars ( hdr . type , hdr .ncols * hdr .mrows , reader -> file , tmp )) {
265+ return "Could not read : Aclass matrix as text " ;
214266 }
215267 for (k = 0 ; k < hdr .mrows ; k ++ ) {
216268 char row [12 ];
@@ -230,7 +282,7 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
230282 /* fprintf(stderr, "use binNormal format\n"); */
231283 binTrans = 0 ;
232284 } else {
233- fprintf (stderr , "row 3: %s\n" , row );
285+ /* fprintf(stderr, "row 3: %s\n", row); */
234286 return "Aclass matrix does not match binTrans or binNormal format" ;
235287 }
236288 }
@@ -247,20 +299,21 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
247299 if (binTrans == 1 ) {
248300 for (k = 0 ; k < hdr .ncols ; k ++ ) {
249301 reader -> allInfo [k ].name = (char * ) malloc (hdr .mrows + 1 );
250- if (fread (reader -> allInfo [k ].name ,hdr .mrows ,1 ,reader -> file ) != 1 ) return "Corrupt header: names matrix" ;
302+ if (read_chars (hdr .type , hdr .mrows , reader -> file , reader -> allInfo [k ].name )) {
303+ return "Could not read: names matrix as text" ;
304+ }
251305 reader -> allInfo [k ].name [hdr .mrows ] = '\0' ;
252306 reader -> allInfo [k ].isParam = -1 ;
253307 reader -> allInfo [k ].index = -1 ;
254308 remSpaces (reader -> allInfo [k ].name );
255- /* fprintf(stderr, " Adding variable %s \n", reader->allInfo[k].name); */
309+ /* fprintf(stderr, " Adding variable '%s' \n", reader->allInfo[k].name); */
256310 }
257311 }
258312 if (binTrans == 0 ) {
259- uint32_t j ;
260- char * tmp = (char * ) malloc (hdr .ncols * hdr .mrows + 1 );
261- if (fread (tmp ,hdr .ncols * hdr .mrows ,1 ,reader -> file ) != 1 ) {
262- free (tmp );
263- return "Corrupt header: names matrix" ;
313+ uint32_t j ;
314+ char * tmp = (char * ) malloc (hdr .ncols * hdr .mrows + 1 );
315+ if (read_chars (hdr .type , hdr .ncols * hdr .mrows , reader -> file , tmp )) {
316+ return "Could not read: names matrix as text" ;
264317 }
265318 for (k = 0 ; k < hdr .mrows ; k ++ ) {
266319 reader -> allInfo [k ].name = (char * ) malloc (hdr .ncols + 1 );
@@ -271,7 +324,7 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
271324 reader -> allInfo [k ].isParam = -1 ;
272325 reader -> allInfo [k ].index = -1 ;
273326 remSpaces (reader -> allInfo [k ].name );
274- /* fprintf(stderr, " Adding variable %s \n", reader->allInfo[k].name); */
327+ /* fprintf(stderr, " Adding variable '%s' \n", reader->allInfo[k].name); */
275328 }
276329 free (tmp );
277330 }
@@ -282,23 +335,25 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
282335 if (binTrans == 1 ) {
283336 for (k = 0 ; k < hdr .ncols ; k ++ ) {
284337 reader -> allInfo [k ].descr = (char * ) malloc (hdr .mrows + 1 );
285- if (fread (reader -> allInfo [k ].descr ,hdr .mrows ,1 ,reader -> file ) != 1 ) return "Corrupt header: names matrix" ;
338+ if (read_chars (hdr .type , hdr .mrows , reader -> file , reader -> allInfo [k ].descr )) {
339+ return "Could not read: description matrix as text" ;
340+ }
286341 reader -> allInfo [k ].descr [hdr .mrows ] = '\0' ;
287- }
342+ /* fprintf(stderr, " Adding description %s\n", reader->allInfo[k].descr); */
343+ }
288344 } else if (binTrans == 0 ) {
289345 uint32_t j ;
290346 char * tmp = (char * ) malloc (hdr .ncols * hdr .mrows + 1 );
291- if (fread (tmp ,hdr .ncols * hdr .mrows ,1 ,reader -> file ) != 1 ) {
292- free (tmp );
293- return "Corrupt header: names matrix" ;
347+ if (read_chars (hdr .type , hdr .ncols * hdr .mrows , reader -> file , tmp )) {
348+ return "Could not read: description matrix as text" ;
294349 }
295350 for (k = 0 ; k < hdr .mrows ; k ++ ) {
296351 reader -> allInfo [k ].descr = (char * ) malloc (hdr .ncols + 1 );
297352 for (j = 0 ; j < hdr .ncols ; j ++ ) {
298353 reader -> allInfo [k ].descr [j ] = tmp [j * hdr .mrows + k ];
299354 }
300355 reader -> allInfo [k ].descr [hdr .ncols ] = '\0' ;
301- /* fprintf(stderr, " Adding variable %s\n", reader->allInfo[k].name ); */
356+ /* fprintf(stderr, " Adding description %s\n", reader->allInfo[k].descr ); */
302357 }
303358 free (tmp );
304359 }
@@ -307,7 +362,7 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
307362 case 3 : { /* "dataInfo" */
308363 unsigned int k ;
309364 int32_t * tmp = (int32_t * ) malloc (sizeof (int32_t )* hdr .ncols * hdr .mrows );
310- if ( 1 != fread ( tmp , sizeof ( int32_t ) * hdr .ncols * hdr .mrows ,1 , reader -> file )) {
365+ if ( read_int32 ( hdr .type , hdr . ncols * hdr .mrows , reader -> file , tmp )) {
311366 free (tmp ); tmp = NULL ;
312367 return "Corrupt header: dataInfo matrix" ;
313368 }
@@ -331,72 +386,50 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
331386 break ;
332387 }
333388 case 4 : { /* "data_1" */
389+ unsigned int k ;
334390 if (binTrans == 1 ) {
335- unsigned int k ;
336391 if (hdr .mrows == 0 ) return "data_1 matrix does not contain at least 1 variable" ;
337392 if (hdr .ncols != 2 && hdr .ncols != 1 ) return "data_1 matrix does not have 1 or 2 cols" ;
338393 reader -> nparam = hdr .mrows ;
339- if (reader -> doublePrecision == 1 )
340- {
341- reader -> params = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
342- if (1 != fread (reader -> params ,matrix_length ,1 ,reader -> file )) return "Corrupt header: data_1 matrix" ;
343- }
344- else
345- {
346- float * buffer = (float * ) malloc (hdr .mrows * hdr .ncols * sizeof (float ));
347- reader -> params = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
348- if (1 != fread (buffer ,matrix_length ,1 ,reader -> file )) return "Corrupt header: data_1 matrix" ;
349- for (k = 0 ;k < hdr .mrows * hdr .ncols ;k ++ )
350- {
351- reader -> params [k ] = buffer [k ];
352- }
353- free (buffer );
394+ reader -> params = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
395+ if (read_double (hdr .type , hdr .mrows * hdr .ncols , reader -> file , reader -> params )) {
396+ return "Corrupt header: data_1 matrix" ;
354397 }
355398 /* fprintf(stderr, " startTime = %.6g\n", reader->params[0]);
356399 * fprintf(stderr, " stopTime = %.6g\n", reader->params[1]); */
357- for (k = 1 ; k < reader -> nparam ; k ++ ) {
358- if (hdr .ncols == 2 && reader -> params [k ] != reader -> params [k + reader -> nparam ]) return "data_1 matrix contained parameter that changed between start and stop-time" ;
359- /* fprintf(stderr, " Parameter[%d] = %.6g\n", k, reader->params[k]); */
360- }
361400 }
362401 if (binTrans == 0 ) {
363- unsigned int k , j ;
402+ unsigned int j ;
364403 if (hdr .ncols == 0 ) return "data_1 matrix does not contain at least 1 variable" ;
365404 if (hdr .mrows != 2 && hdr .mrows != 1 ) return "data_1 matrix does not have 1 or 2 rows" ;
366405 reader -> nparam = hdr .ncols ;
367- if (reader -> doublePrecision == 1 )
368- {
369- double * tmp = NULL ;
370- tmp = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
371- reader -> params = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
372- if (1 != fread (tmp ,matrix_length ,1 ,reader -> file )) return "Corrupt header: data_1 matrix" ;
373- for (k = 0 ; k < hdr .mrows ; k ++ ) {
374- for (j = 0 ; j < hdr .ncols ; j ++ ) {
375- reader -> params [k * hdr .ncols + j ] = tmp [k + j * hdr .mrows ];
376- }
377- }
378- free (tmp );
406+ double * tmp = NULL ;
407+ tmp = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
408+ reader -> params = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
409+ if (read_double (hdr .type , hdr .mrows * hdr .ncols , reader -> file , tmp )) {
410+ return "Corrupt header: data_1 matrix" ;
379411 }
380- else
381- {
382- float * tmp = NULL ;
383- tmp = (float * ) malloc (hdr .mrows * hdr .ncols * sizeof (float ));
384- reader -> params = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
385- if (1 != fread (tmp ,matrix_length ,1 ,reader -> file )) return "Corrupt header: data_1 matrix" ;
386- for (k = 0 ; k < hdr .mrows ; k ++ ) {
387- for (j = 0 ; j < hdr .ncols ; j ++ ) {
388- reader -> params [k * hdr .ncols + j ] = tmp [k + j * hdr .mrows ];
389- }
412+ for (k = 0 ; k < hdr .mrows ; k ++ ) {
413+ for (j = 0 ; j < hdr .ncols ; j ++ ) {
414+ reader -> params [k * hdr .ncols + j ] = tmp [k + j * hdr .mrows ];
390415 }
391- free (tmp );
392- }
393- for (k = 1 ; k < reader -> nparam ; k ++ ) {
394- if (hdr .mrows == 2 && reader -> params [k ] != reader -> params [k + reader -> nparam ]) return "data_1 matrix contained parameter that changed between start and stop-time" ;
395416 }
417+ free (tmp );
418+ }
419+ for (k = 1 ; k < reader -> nparam ; k ++ ) {
420+ if (hdr .mrows == 2 && reader -> params [k ] != reader -> params [k + reader -> nparam ]) return "data_1 matrix contained parameter that changed between start and stop-time" ;
396421 }
397422 break ;
398423 }
399424 case 5 : { /* "data_2" */
425+ int p = (hdr .type / 10 )%10 ;
426+ if (p == 0 ) {
427+ reader -> doublePrecision = 1 ;
428+ } else if (p == 1 ) {
429+ reader -> doublePrecision = 0 ;
430+ } else {
431+ return "data_2 matrix not in double/float representation" ;
432+ }
400433 if (binTrans == 1 ) {
401434 reader -> nrows = hdr .ncols ;
402435 /* Allow empty matrix; it's not a complete file, but ok... */
@@ -414,42 +447,27 @@ const char* omc_new_matlab4_reader(const char *filename, ModelicaMatReader *read
414447 reader -> nvar = hdr .ncols ;
415448 reader -> var_offset = ftell (reader -> file );
416449 reader -> vars = (double * * ) calloc (reader -> nvar * 2 ,sizeof (double * ));
417- if (reader -> doublePrecision == 1 )
418- {
419- double * tmp = NULL ;
420- tmp = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
421- if (1 != fread (tmp ,matrix_length ,1 ,reader -> file )) return "Corrupt header: data_2 matrix" ;
422- for (k = 0 ; k < hdr .ncols ; k ++ ) {
423- reader -> vars [k ] = (double * ) malloc (hdr .mrows * sizeof (double ));
424- for (j = 0 ; j < hdr .mrows ; j ++ ) {
425- reader -> vars [k ][j ] = tmp [j + k * hdr .mrows ];
426- }
427- }
428- for (k = reader -> nvar ; k < reader -> nvar * 2 ; k ++ ) {
429- reader -> vars [k ] = (double * ) malloc (hdr .mrows * sizeof (double ));
430- for (j = 0 ; j < hdr .mrows ; j ++ ) {
431- reader -> vars [k ][j ] = - reader -> vars [k - reader -> nvar ][j ];
432- }
433- }
434- free (tmp );
435- } else {
436- float * tmp = NULL ;
437- tmp = (float * ) malloc (hdr .mrows * hdr .ncols * sizeof (float ));
438- if (1 != fread (tmp ,matrix_length ,1 ,reader -> file )) return "Corrupt header: data_2 matrix" ;
439- for (k = 0 ; k < hdr .ncols ; k ++ ) {
440- reader -> vars [k ] = (double * ) malloc (hdr .mrows * sizeof (double ));
441- for (j = 0 ; j < hdr .mrows ; j ++ ) {
442- reader -> vars [k ][j ] = tmp [j + k * hdr .mrows ];
443- }
450+
451+
452+ double * tmp = NULL ;
453+ tmp = (double * ) malloc (hdr .mrows * hdr .ncols * sizeof (double ));
454+ if (read_double (hdr .type , hdr .mrows * hdr .ncols , reader -> file , tmp )) {
455+ return "Corrupt header: data_2 matrix" ;
456+ }
457+ for (k = 0 ; k < hdr .ncols ; k ++ ) {
458+ reader -> vars [k ] = (double * ) malloc (hdr .mrows * sizeof (double ));
459+ for (j = 0 ; j < hdr .mrows ; j ++ ) {
460+ reader -> vars [k ][j ] = tmp [j + k * hdr .mrows ];
444461 }
445- for ( k = reader -> nvar ; k < reader -> nvar * 2 ; k ++ ) {
446- reader -> vars [ k ] = ( double * ) malloc ( hdr . mrows * sizeof ( double ));
447- for ( j = 0 ; j < hdr .mrows ; j ++ ) {
448- reader -> vars [ k ][ j ] = - reader -> vars [ k - reader -> nvar ][ j ];
449- }
462+ }
463+ for ( k = reader -> nvar ; k < reader -> nvar * 2 ; k ++ ) {
464+ reader -> vars [ k ] = ( double * ) malloc ( hdr .mrows * sizeof ( double ));
465+ for ( j = 0 ; j < hdr . mrows ; j ++ ) {
466+ reader -> vars [ k ][ j ] = - reader -> vars [ k - reader -> nvar ][ j ];
450467 }
451- free (tmp );
452468 }
469+ free (tmp );
470+
453471 if (-1 == fseek (reader -> file ,matrix_length ,SEEK_CUR )) return "Corrupt header: data_2 matrix" ;
454472 }
455473 break ;
0 commit comments