1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8 /*
9 * $Header: /src/master/dx/src/exec/dxmods/genimp_io.c,v 1.10 2006/01/04 22:00:51 davidt Exp $
10 */
11
12 #include <dxconfig.h>
13
14
15 /*
16 * There are four variables fields(f), series(s), grid(g) and structure(d).
17 * I am representing them from slow to fastest changing variable index.
18 *
19 * 1. f, s, g, d :- vector
20 * 2. f, s, d, g :- vector-record ?
21 * 3. f, d, s, g
22 * 4. f, d, g, s
23 * 5. f, g, s, d
24 * 6. f, g, d, s
25 * 7. s, f, g, d :- record-vector
26 * 8. s, f, d, g :- record
27 * 9. s, g, f, d :- field
28 *10. g, f, s, d
29 *11. g, s, f, d
30 *12. g, f, d, s
31 */
32
33 #include <string.h>
34 #include "genimp.h"
35
36 static int FgetAsciiData(FILE *, void **, int);
37 static int FgetBinaryData(FILE *, void **, int);
38 static int RgetAsciiData(FILE *, void **, int);
39 static int RgetBinaryData(FILE *, void **, int);
40 static int VgetAsciiData(FILE *, void **, int);
41 static int VgetBinaryData(FILE *, void **, int);
42 static int RVgetAsciiData(FILE *, void **, int);
43 static int RVgetBinaryData(FILE *, void **, int);
44
45 static Error convert_string(char *s, Type t, void *data, int index, int *nl);
46 static Error read_ascii(FILE *fp, Type t, void *data, int index);
47 static Error skip_header(FILE *fp,struct header *);
48 static Error skip_bdata(FILE *fp, int toskip);
49 static Error skip_ascii(FILE *fp, int num);
50 static Error doread(void *p, int size, int cnt, FILE* fp);
51 static Error skip_numchar( FILE *, int, char **);
52 static void add_parse_message(char *op, int s, int f, int item, int comp);
53 static void *reorderData(void *data, int f);
54 static Pointer locations2float(Pointer from, Type from_type, int cnt);
55 static Error _dxf_getline(char **, FILE *);
56 static Error extract_fromline(char str[MAX_DSTR],int which);
57
58 #if !defined(DXD_STANDARD_IEEE)
59 static void _dxfdenormalize(void **);
60 #endif
61
62 static int (* FgetData[])(FILE *, void **, int) = {
63 FgetAsciiData,
64 FgetBinaryData};
65 static int (* RgetData[])(FILE *, void **, int) = {
66 RgetAsciiData,
67 RgetBinaryData};
68 static int (* VgetData[])(FILE *, void **, int) = {
69 VgetAsciiData,
70 VgetBinaryData};
71 static int (* RVgetData[])(FILE *, void **, int) = {
72 RVgetAsciiData,
73 RVgetBinaryData};
74
75 /*
76 * DXRead the data file as specified by the general import file.
77 * The data for series s and field f is placed in the buffer pointed
78 * to by XF[s*_dxd_gi_numflds + f]. After reading in the raw data from the
79 * file, we must
80 * 1) Change column majority data to row majority.
81 * 2) DXSwap byte order if they differ and it was binary data.
82 * 3) Denormalize floating point data for the PVS.
83 * So what is a returned in each XF[i] buffer is the data for each field
84 * of each requested series, in the correct majority and byte order.
85 *
86 * See genimp.c:import_Group for a discussion of XF.
87 */
_dxf_gi_read_file(void ** XF,FILE ** fp)88 int _dxf_gi_read_file(void **XF,FILE **fp)
89 {
90 int size,s,nitems,i,f;
91
92 /*
93 * DXRead the raw data into the XF[i].
94 */
95 if(!(_dxf_gi_importDatafile(XF,fp)))
96 goto error;
97
98 /*size = _dxfnumGridPoints();*/
99
100 /*
101 * Change the majority if the input data is in column majority order.
102 */
103 if ( _dxd_gi_majority == COL ) {
104 for (s=i=0 ; i<_dxd_gi_series ; i++, s+=_dxd_gi_numflds) {
105 for (f=0 ; f<_dxd_gi_numflds ; f++) {
106 size = _dxfnumGridPoints(f);
107 if (XF[s+f]) {
108 XF[s+f] = reorderData(XF[s+f],f);
109 if (!XF[s+f])
110 goto error;
111 }
112 }
113 }
114 }
115
116 /*
117 * Change the byte order if necessary.
118 */
119 if ((_dxd_gi_format == BINARY) &&
120 (_dxfLocalByteOrder() != _dxd_gi_byteorder)) {
121 for (f=0 ; f<_dxd_gi_numflds ; f++) {
122 if (_dxd_gi_whichflds[f] == ON) {
123 size = _dxfnumGridPoints(f);
124 nitems = size * _dxd_gi_var[f]->datadim;
125 for (s=i=0 ; i<_dxd_gi_series ; i++, s+=_dxd_gi_numflds)
126 if ((_dxd_gi_whichser[i] == ON) &&
127 !_dxfByteSwap(XF[s+f], XF[s+f],
128 nitems, _dxd_gi_var[f]->datatype))
129 goto error;
130 }
131 }
132 }
133
134 #if !defined(DXD_STANDARD_IEEE)
135 /*
136 * Denormalize the IEEE floating point numbers.
137 */
138 _dxfdenormalize(XF);
139 #endif /* !normal ieee */
140
141 /*
142 * If user has used the 'locations' keyword and the locations are
143 * not type float, then convert them to floats.
144 * Note that if we convert, then we free the old array.
145 */
146 if ((_dxd_gi_positions == FIELD_PRODUCT) &&
147 (_dxd_gi_var[_dxd_gi_loc_index]->datatype != TYPE_FLOAT)) {
148 int nfloats=0;
149 Type ltype;
150 size = _dxfnumGridPoints(_dxd_gi_loc_index);
151 nfloats = _dxd_gi_var[_dxd_gi_loc_index]->datadim * size;
152 ltype = _dxd_gi_var[_dxd_gi_loc_index]->datatype;
153 for (s=0 ; s<_dxd_gi_series ; s++) {
154 if (_dxd_gi_whichser[s] == ON) {
155 Pointer new_XF;
156 i = s*_dxd_gi_numflds + _dxd_gi_loc_index;
157 new_XF = locations2float( XF[i], ltype, nfloats);
158 if (!new_XF) goto error;
159 DXFree(XF[i]);
160 XF[i] = new_XF;
161 }
162 }
163 _dxd_gi_var[_dxd_gi_loc_index]->datatype = TYPE_FLOAT;
164 _dxd_gi_var[_dxd_gi_loc_index]->databytes = DXTypeSize(TYPE_FLOAT);
165 }
166
167 return OK;
168
169 error:
170 return ERROR;
171 }
172
173 /*
174 FN: open the data file
175 */
176 Error
_dxf_gi_OpenFile(char * name,FILE ** fp,int infofile)177 _dxf_gi_OpenFile(char *name, FILE **fp, int infofile)
178 {
179 int i;
180 char *outname, *f;
181 static char infopath[256]; /* Save the path when opening the info file */
182
183
184 /* try to open the filename as given, and save the name
185 * for error messages later.
186 */
187 outname = NULL;
188 if (!infofile && (strlen(infopath) > 0)) {
189 if (!(*fp = _dxfopen_dxfile(name,infopath,&outname,".general")))
190 goto error;
191 }
192 else{
193 if (!(*fp = _dxfopen_dxfile(name,NULL,&outname,".general")))
194 goto error;
195 /*
196 * Save the path to the info file so that we can use it to open the
197 * the data file if necessary.
198 */
199 if (infofile) {
200 if (strchr(outname,'/')) {
201 strcpy(infopath,outname);
202 for (i=strlen(outname)-1 ; i>=0 ; i--) {
203 if (infopath[i] == '/') {
204 infopath[i+1] = '\0';
205 break;
206 }
207 }
208 } else
209 infopath[0] = '\0';
210 }
211 }
212 DXFree(outname);
213 return OK;
214
215 error:
216 if (outname) DXFree(outname);
217 infopath[0] = '\0';
218 if (infofile)
219 f = "general import file";
220 else
221 f = "data file";
222 DXSetError(ERROR_BAD_PARAMETER, "#10903", f, name);
223 return ERROR;
224 }
225
226
227 /*
228 FN: According to the interleaving technique it calls different getdata
229 routines.
230 RT: Returns OK if succesful otherwise an ERROR.
231 */
232
_dxf_gi_importDatafile(void ** data,FILE ** fp)233 int _dxf_gi_importDatafile(void **data,FILE **fp)
234 {
235 int size, gd=ERROR;
236
237 /*size = _dxfnumGridPoints();*/
238 size = _dxfnumGridPoints(-1);
239
240 if(!*fp && !_dxf_gi_OpenFile(_dxd_gi_filename, fp, 0)) /* 0 = data file */
241 goto error;
242
243 if ((_dxd_gi_header.type != SKIP_NOTHING)&& !skip_header(*fp,&_dxd_gi_header))
244 goto error;
245
246 switch (_dxd_gi_interleaving) {
247 case IT_RECORD_VECTOR:
248 if(!(gd = (* RVgetData[_dxd_gi_format])(*fp, data, size)))
249 goto error;
250 break;
251 case IT_FIELD:
252 if(!(gd = (* FgetData[_dxd_gi_format])(*fp, data, size)))
253 goto error;
254 break;
255 case IT_RECORD:
256 if (!(gd = (* RgetData[_dxd_gi_format])(*fp, data, size)))
257 goto error;
258 break;
259 case IT_VECTOR:
260 if (!(gd = (* VgetData[_dxd_gi_format])(*fp, data, size)))
261 goto error;
262 break;
263 default:
264 DXErrorGoto(ERROR_INTERNAL,"Unexpected interleave");
265 }
266
267 return(gd);
268
269 error:
270 return ERROR;
271 }
272
273 /*
274 FN: Field interleaving ascii data read routine.
275 */
276
FgetAsciiData(FILE * fp,void ** data,int size)277 static int FgetAsciiData(FILE *fp, void **data, int size)
278 {
279 int cnt, f, k, comp, d, dim, width;
280 int step, s,nl=0,maxseries,sersize=0;
281 char *str, r[MAX_DSTR], *op;
282 Type t;
283
284 size = _dxfnumGridPoints(0);
285
286 /* what is the max series input */
287 for (s=_dxd_gi_series-1; s>=0; s--)
288 if (_dxd_gi_whichser[s] == ON) break;
289 maxseries = s+1;
290 /* how many numbers per series */
291 for (f=0; f<_dxd_gi_numflds; f++){
292 if (_dxd_gi_var[f]->datatype==TYPE_STRING) dim=1;
293 else dim = _dxd_gi_var[f]->datadim;
294 sersize += dim;
295 }
296 sersize = size * sersize;
297
298 if ( _dxd_gi_asciiformat == FREE )
299 {
300 for (s=step= 0; s<maxseries; s++, step += _dxd_gi_numflds)
301 {
302 for (cnt = 0; cnt < size; cnt++)
303 {
304 for (f = 0; f < _dxd_gi_numflds; f++)
305 {
306 t = _dxd_gi_var[f]->datatype;
307 dim = _dxd_gi_var[f]->datadim;
308 if (_dxd_gi_whichflds[f] == ON && _dxd_gi_whichser[s] == ON)
309 {
310 for (comp = 0; comp < dim; comp++)
311 {
312 d = (cnt*dim) + comp;
313 if (!read_ascii(fp,t,data[step+f],d)) {
314 op = "Reading";
315 goto parse_error;
316 }
317 if (t==TYPE_STRING) comp=dim;
318 }
319 }
320 else
321 {
322 for (comp = 0; comp < dim; comp++)
323 {
324 if (!skip_ascii(fp,1)) {
325 op = "Skipping";
326 goto parse_error;
327 }
328 if (t==TYPE_STRING) comp=dim;
329 }
330 }
331 }
332 }
333 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
334 DXAddMessage("error reading series separator %d",s+1);
335 goto error;
336 }
337 }
338 }
339 else if ( _dxd_gi_asciiformat == FIX )
340 {
341 op = "Reading";
342 str = (char *)DXAllocate(MAX_DSTR);
343 for (s=comp=f=step=0; s < maxseries; s++, step += _dxd_gi_numflds)
344 {
345 for (cnt=0; cnt < size; cnt++)
346 {
347 if (!_dxf_getline(&str, fp))
348 {
349 DXSetError(ERROR_MISSING_DATA,"#10898","data file");
350 f=0;
351 goto parse_error;
352 }
353 if (_dxd_gi_whichser[s] == ON)
354 {
355 k = 0;
356 for (f=0; f < _dxd_gi_numflds; f++)
357 {
358 k += _dxd_gi_var[f]->leading;
359 t = _dxd_gi_var[f]->datatype;
360 dim = _dxd_gi_var[f]->datadim;
361 width = _dxd_gi_var[f]->width;
362 if (_dxd_gi_whichflds[f] == ON)
363 {
364 for (comp = 0; comp < dim; comp++)
365 {
366 d = (cnt*dim) + comp;
367 strncpy(r, &str[k], width);
368 r[width] = (char)NULL;
369 if (!convert_string(r,t,data[step+f],d,&nl))
370 goto parse_error;
371 k += width;
372 if (t==TYPE_STRING) comp=dim;
373 }
374 }
375 else
376 {
377 if (t==TYPE_STRING) dim=1;
378 k += dim*width;
379 }
380 }
381 }
382 }
383 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
384 DXAddMessage("error reading series separator %d",s+1);
385 goto error;
386 }
387 }
388 DXFree(str);
389 }
390 else
391 {
392 DXSetError(ERROR_INTERNAL,"Unknown ascii format");
393 goto error;
394 }
395 return OK;
396
397 parse_error:
398 add_parse_message(op, s,f,cnt,comp);
399
400 error:
401 return ERROR;
402 }
403
404 /*
405 FN : Field interleaving binary data read routine.
406 */
407
FgetBinaryData(FILE * fp,void ** data,int size)408 static int FgetBinaryData(FILE *fp, void **data, int size)
409 {
410 int i, j, k, len, step, d, s, type_size;
411 char *p=NULL, *op,*tp;
412 int maxseries;
413
414 size = _dxfnumGridPoints(0); /* all fields same size */
415
416 for( len=j=0; j<_dxd_gi_numflds; j++)
417 len += _dxd_gi_var[j]->databytes * _dxd_gi_var[j]->datadim;
418
419 if (!(p = (char *)DXAllocate(len)) )
420 goto error;
421
422 /* what is the max series input */
423 for (s=_dxd_gi_series-1; s>=0; s--)
424 if (_dxd_gi_whichser[s] == ON) break;
425 maxseries = s+1;
426
427 for (s=step = 0; s < maxseries; s++, step += _dxd_gi_numflds)
428 {
429 for(i=0; i<size; i++)
430 {
431 if (_dxd_gi_whichser[s] == OFF) {
432 if (!skip_bdata(fp, len*size)) {
433 op = "skip";
434 goto parse_error;
435 }
436 continue;
437 } else {
438 if (!doread(p, 1, len, fp)) {
439 op = "read";
440 goto parse_error;
441 }
442 }
443 tp = p;
444 for(j=0; j<_dxd_gi_numflds; j++)
445 {
446 type_size = _dxd_gi_var[j]->databytes;
447 if (_dxd_gi_whichflds[j] == ON)
448 {
449 for(k=0; k<_dxd_gi_var[j]->datadim; k++)
450 {
451 d = (i*_dxd_gi_var[j]->datadim) + k;
452 switch( _dxd_gi_var[j]->datatype )
453 {
454 case TYPE_UBYTE:
455 DREF(ubyte,data[step+j],d) = DREF(ubyte,tp,0);
456 break;
457 case TYPE_BYTE:
458 DREF(byte,data[step+j],d) = DREF(byte,tp,0);
459 break;
460 case TYPE_SHORT:
461 DREF(short,data[step+j],d) = DREF(short,tp,0);
462 break;
463 case TYPE_USHORT:
464 DREF(unsigned short,data[step+j],d) = DREF(unsigned short,tp,0);
465 break;
466 case TYPE_INT:
467 DREF(int,data[step+j],d) = DREF(int,tp,0);
468 break;
469 case TYPE_UINT:
470 DREF(unsigned int,data[step+j],d) = DREF(unsigned int,tp,0);
471 break;
472 case TYPE_FLOAT:
473 DREF(float,data[step+j],d) = DREF(float,tp,0);
474 break;
475 case TYPE_DOUBLE:
476 DREF(double,data[step+j],d) = DREF(double,tp,0);
477 break;
478 default:
479 DXSetError(ERROR_INTERNAL,
480 "Unknown data type to read data file");
481 goto error;
482 }
483 tp += type_size;
484 }
485 }
486 else
487 { /* Skip the data for this field */
488 tp += _dxd_gi_var[j]->datadim * type_size;
489 }
490 }
491 }
492 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
493 DXAddMessage("error reading series header %d",s+1);
494 goto error;
495 }
496 }
497
498 DXFree((Pointer) p );
499 return OK;
500
501 parse_error:
502 if (_dxd_gi_series > 1)
503 DXAddMessage("\nTrying to %s item %d from all fields of series %d",op,s+1);
504 else
505 DXAddMessage("\nTrying to %s item %d from all fields",op);
506
507 error:
508 if (p) DXFree((Pointer)p);
509 return ERROR;
510 }
511
512 /*
513 FN: Record interleaving ascii format read.
514 */
515
RgetAsciiData(FILE * fp,void ** data,int size)516 static int RgetAsciiData(FILE *fp, void **data, int size)
517 {
518 int cnt=0, f, comp, d, dim, ll=0, kk, elements,leading,width;
519 int step, s, nl=0,maxseries;
520 char *str, r[MAX_DSTR], *op;
521 Type t;
522 struct header rec_sep;
523
524 /* what is the max series input */
525 for (s=_dxd_gi_series-1; s>=0; s--)
526 if (_dxd_gi_whichser[s] == ON) break;
527 maxseries = s+1;
528
529 if ( _dxd_gi_asciiformat == FREE )
530 {
531 for (s=step = 0; s < maxseries; s++, step += _dxd_gi_numflds)
532 {
533 for (f = 0; f < _dxd_gi_numflds; f++)
534 {
535 size = _dxfnumGridPoints(f);
536 dim = _dxd_gi_var[f]->datadim;
537 t = _dxd_gi_var[f]->datatype;
538 if (_dxd_gi_whichflds[f] == ON && _dxd_gi_whichser[s] == ON)
539 {
540 for (comp = 0; comp < dim; comp++)
541 {
542 d = comp;
543 for (cnt = 0; cnt < size; cnt++)
544 {
545 if (!read_ascii(fp,t,data[step+f],d)) {
546 op = "Reading";
547 goto parse_error;
548 }
549 d += dim;
550 }
551 if (t == TYPE_STRING) dim=1;
552 /* skip according to record separator */
553 rec_sep = _dxd_gi_var[f]->rec_separat[comp];
554 if (!skip_header(fp,&rec_sep)){
555 op = "record separator";
556 goto parse_error;
557 }
558 }
559 }
560 else
561 {
562 for (comp = 0; comp < dim; comp++)
563 {
564 if (!skip_ascii(fp,size)) /* read one record */
565 goto error;
566 rec_sep = _dxd_gi_var[f]->rec_separat[comp];
567 if (!skip_header(fp,&rec_sep)){
568 op = "record separator";
569 goto parse_error;
570 }
571 if (t == TYPE_STRING) dim=1;
572 }
573 }
574 }
575 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
576 DXAddMessage("error reading series separator %d",s+1);
577 goto error;
578 }
579 }
580 }
581 else if ( _dxd_gi_asciiformat == FIX )
582 {
583 op = "Reading";
584 str = (char *)DXAllocate(MAX_DSTR);
585 for (s=step= 0; s < maxseries; s++, step += _dxd_gi_numflds)
586 {
587 for (f = 0; f < _dxd_gi_numflds; f++)
588 {
589 size = _dxfnumGridPoints(f);
590 t = _dxd_gi_var[f]->datatype;
591 dim = _dxd_gi_var[f]->datadim;
592 elements = _dxd_gi_var[f]->elements;
593 leading = _dxd_gi_var[f]->leading;
594 width = _dxd_gi_var[f]->width;
595 for (comp = 0; comp < dim; comp++)
596 {
597 d = comp;
598 for (cnt=0; cnt<size; cnt+=elements)
599 {
600 if (!(skip_numchar(fp, leading, &str)))
601 goto parse_error;
602 kk = 0;
603 for( ll=0; ll<elements; ll++)
604 {
605 if (cnt+ll < size)
606 {
607 strncpy(r, &str[kk], width);
608 r[width] = (char)NULL;
609 if (_dxd_gi_whichflds[f] == ON &&
610 _dxd_gi_whichser[s] == ON)
611 {
612 if (!convert_string(r,t,data[step+f],d,&nl))
613 goto parse_error;
614 if (nl==1){
615 if (!(skip_numchar(fp, leading, &str)))
616 goto parse_error;
617 kk=0;
618 nl=0;
619 ll--;
620 }
621 else{
622 kk+=width;
623 d+=dim;
624 }
625 }
626 else
627 {
628 if (r[0] == '\n'){
629 ll--;
630 kk=0;
631 if (!skip_numchar(fp,leading,&str))
632 goto parse_error;
633 }
634 else{
635 d+=dim;
636 kk+=width;
637 }
638 }
639 }
640 }
641 }
642 if (t == TYPE_STRING) dim=1;
643 rec_sep = _dxd_gi_var[f]->rec_separat[comp];
644 if (!skip_header(fp,&rec_sep)){
645 op = " record separator";
646 goto parse_error;
647 }
648 }
649 }
650 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
651 DXAddMessage("error reading series separator %d",s+1);
652 goto error;
653 }
654 }
655 DXFree(str);
656 }
657 return OK;
658
659 parse_error:
660 add_parse_message(op,s,f,cnt+ll,comp);
661 error:
662 return ERROR;
663 }
664
665 /*
666 FN: Record interleaving binary read.
667 */
RgetBinaryData(FILE * fp,void ** data,int size)668 static int RgetBinaryData(FILE *fp, void **data, int size)
669 {
670 int i, j, k, maxlen, len, step, d, incd, s;
671 char *p=NULL, *op;
672 struct header rec_sep;
673 int maxseries;
674
675 for(maxlen=j=0; j<_dxd_gi_numflds; j++) {
676 len = size * _dxd_gi_var[j]->datadim * _dxd_gi_var[j]->databytes;
677 maxlen = (len > maxlen ? len : maxlen);
678 }
679 if (!(p = (char *)DXAllocate(maxlen)))
680 goto error;
681
682 /* what is the max series input */
683 for (s=_dxd_gi_series-1; s>=0; s--)
684 if (_dxd_gi_whichser[s] == ON) break;
685 maxseries = s+1;
686
687 for (s=step=0; s < maxseries; s++, step += _dxd_gi_numflds)
688 {
689 for(j=0; j<_dxd_gi_numflds; j++) {
690 size = _dxfnumGridPoints(j);
691 incd = _dxd_gi_var[j]->datadim;
692 for(k=0; k<_dxd_gi_var[j]->datadim; k++) {
693 d = k;
694 len = size * _dxd_gi_var[j]->databytes;
695 if (_dxd_gi_whichser[s]==OFF || _dxd_gi_whichflds[j]==OFF){
696 if(!(skip_bdata(fp, len))) {
697 op = "skip";
698 goto parse_error;
699 }
700 }
701 else {
702 if (!doread(p, 1, len, fp)) {
703 op = "read";
704 goto parse_error;
705 }
706 switch( _dxd_gi_var[j]->datatype ) {
707 case TYPE_UBYTE:
708 for(i=0; i<size; i++) {
709 DREF(ubyte,data[step+j],d) = DREF(ubyte,p, i);
710 d += incd;
711 }
712 break;
713 case TYPE_BYTE:
714 for(i=0; i<size; i++) {
715 DREF(byte,data[step+j],d) = DREF(byte,p, i);
716 d += incd;
717 }
718 break;
719 case TYPE_SHORT:
720 for(i=0; i<size; i++) {
721 DREF(short,data[step+j],d) = DREF(short,p,i);
722 d += incd;
723 }
724 break;
725 case TYPE_USHORT:
726 for(i=0; i<size; i++) {
727 DREF(unsigned short,data[step+j],d) = DREF(unsigned short,p,i);
728 d += incd;
729 }
730 break;
731 case TYPE_INT:
732 for(i=0; i<size; i++) {
733 DREF(int,data[step+j],d) = DREF(int,p,i);
734 d += incd;
735 }
736 break;
737 case TYPE_UINT:
738 for(i=0; i<size; i++) {
739 DREF(unsigned int,data[step+j],d) = DREF(unsigned int,p,i);
740 d += incd;
741 }
742 break;
743 case TYPE_FLOAT:
744 for(i=0; i<size; i++) {
745 DREF(float,data[step+j],d) = DREF(float,p,i);
746 d += incd;
747 }
748 break;
749 case TYPE_DOUBLE:
750 for(i=0; i<size; i++) {
751 DREF(double,data[step+j],d)=DREF(double,p,i);
752 d += incd;
753 }
754 break;
755 default:
756 DXSetError(ERROR_INTERNAL,
757 "Unknown data type to read data file");
758 goto error;
759 }
760 }
761 rec_sep = _dxd_gi_var[j]->rec_separat[k];
762 if (!skip_header(fp,&rec_sep)){
763 op = " record separator";
764 goto parse_error;
765 }
766 }
767 }
768 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
769 DXAddMessage("error reading series separator %d",s+1);
770 goto error;
771 }
772 }
773
774 DXFree((Pointer) p );
775 return OK;
776
777 parse_error:
778 if (_dxd_gi_series > 1)
779 DXAddMessage("\nTrying to %s field '%s' of series %d",op,_dxd_gi_var[j]->name,s+1);
780 else
781 DXAddMessage("\nTrying to %s field '%s'",op,_dxd_gi_var[j]->name);
782 error:
783 if (p) DXFree((Pointer)p);
784 return ERROR;
785 }
786
787 /*
788 FN: Vector interleaving ascii file format read.
789 */
790
VgetAsciiData(FILE * fp,void ** data,int size)791 static int VgetAsciiData(FILE *fp, void **data, int size)
792 {
793 int s, f, l=0, ll, kk, dim, elements, leading, width;
794 int step, dim_mul_size,nl=0;
795 char *str, r[MAX_DSTR], *op;
796 Type t;
797 struct header rec_sep;
798 int offset = 1, d;
799
800 if ( _dxd_gi_asciiformat == FREE )
801 {
802 for (f = 0; f < _dxd_gi_numflds; f++)
803 {
804 size = _dxfnumGridPoints(f);
805 t = _dxd_gi_var[f]->datatype;
806 dim = _dxd_gi_var[f]->datadim;
807 offset = 1;
808 if (t == TYPE_STRING) {
809 offset = dim;
810 dim = 1;
811 }
812 for (s = 0; s < _dxd_gi_series; s++)
813 {
814 if (_dxd_gi_whichflds[f] == ON && _dxd_gi_whichser[s] == ON)
815 {
816 step = s*_dxd_gi_numflds;
817 for (l = 0, d = 0; l < dim*size; l++) {
818 if (!read_ascii(fp,t,data[step+f],d)) {
819 op = "Reading";
820 goto parse_error;
821 }
822 d += offset;
823 }
824 }
825 else
826 {
827 if (!skip_ascii(fp,size*dim)) {
828 op = "Skipping";
829 goto parse_error;
830 }
831 }
832 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
833 DXAddMessage("error reading series separator %d",s+1);
834 goto error;
835 }
836 }
837 rec_sep = _dxd_gi_var[f]->rec_separat[0];
838 if (!skip_header(fp,&rec_sep)){
839 op = " record separator";
840 goto parse_error;
841 }
842 }
843 }
844 else if ( _dxd_gi_asciiformat == FIX )
845 {
846 op = "Reading";
847 str = (char *)DXAllocate(MAX_DSTR);
848 for (f = 0; f < _dxd_gi_numflds; f++)
849 {
850 size = _dxfnumGridPoints(f);
851 t = _dxd_gi_var[f]->datatype;
852 dim = _dxd_gi_var[f]->datadim;
853 elements = _dxd_gi_var[f]->elements;
854 leading = _dxd_gi_var[f]->leading;
855 width = _dxd_gi_var[f]->width;
856 offset = 1;
857 if (t == TYPE_STRING) {
858 offset = dim;
859 dim=1;
860 }
861 dim_mul_size = dim*size;
862 for (s = 0; s < _dxd_gi_series; s++)
863 {
864 step = s*_dxd_gi_numflds;
865 for (l = 0, d = 0; l < dim_mul_size; l+=elements)
866 {
867 if (!(skip_numchar(fp, leading, &str)))
868 goto parse_error;
869 kk = 0;
870 for( ll=0; ll<elements; ll++)
871 {
872 if ( l+ll < dim_mul_size )
873 {
874 if (_dxd_gi_whichflds[f] == ON && _dxd_gi_whichser[s] == ON)
875 {
876 strncpy(r, &str[kk], width);
877 r[width] = (char)NULL;
878 if (!convert_string(r,t,data[step+f],d,&nl))
879 goto parse_error;
880 if (nl==1){
881 nl=0;
882 kk=0;
883 ll--;
884 if (!(skip_numchar(fp, leading, &str)))
885 goto parse_error;
886 }
887 else{
888 d += offset;
889 kk+=width;
890 }
891 }
892 else
893 {
894 if (r[0] == '\n'){
895 ll--;
896 kk=0;
897 if (!skip_numchar(fp,leading,&str))
898 goto parse_error;
899 }
900 else{
901 d += offset;
902 kk += width;
903 }
904 }
905 }
906 }
907 }
908 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
909 DXAddMessage("error reading series separator %d",s+1);
910 goto error;
911 }
912 }
913 rec_sep = _dxd_gi_var[f]->rec_separat[0];
914 if (!skip_header(fp,&rec_sep)){
915 op = " record separator";
916 goto parse_error;
917 }
918 }
919 DXFree(str);
920 }
921 return OK;
922
923 parse_error:
924 add_parse_message(op,s,f,l/dim,l%dim);
925 error:
926 return ERROR;
927 }
928
929 /*
930 FN: Vector binary file format read.
931 */
932
VgetBinaryData(FILE * fp,void ** data,int size)933 static int VgetBinaryData(FILE *fp, void **data, int size)
934 {
935 int j, s, len, step;
936 char *op;
937 struct header rec_sep;
938
939 for(j=0; j<_dxd_gi_numflds; j++)
940 {
941 size = _dxfnumGridPoints(j);
942 for (s = 0; s < _dxd_gi_series; s++)
943 {
944 step = s*_dxd_gi_numflds;
945 len = _dxd_gi_var[j]->databytes * _dxd_gi_var[j]->datadim * size;
946 if (_dxd_gi_whichser[s] == OFF || _dxd_gi_whichflds[j] == OFF)
947 {
948 if(!(skip_bdata(fp, len))) {
949 op = "read";
950 goto error;
951 }
952 }
953 else if(!doread(data[step+j], 1, len, fp)) {
954 op = "read";
955 goto error;
956 }
957 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
958 op = "read series header";
959 goto error;
960 }
961 }
962 rec_sep = _dxd_gi_var[j]->rec_separat[0];
963 if (!skip_header(fp,&rec_sep)){
964 op = " record separator";
965 goto error;
966 }
967 }
968 return OK;
969
970 error:
971 if (_dxd_gi_series > 1)
972 DXAddMessage("\nTrying to %s field '%s' of series %d",op,_dxd_gi_var[j]->name,s+1);
973 else
974 DXAddMessage("\nTrying to %s field '%s'",op,_dxd_gi_var[j]->name);
975 return ERROR;
976 }
977
978 /*
979 FN: Record Vector ascii file format read.
980 */
981
RVgetAsciiData(FILE * fp,void ** data,int size)982 static int RVgetAsciiData(FILE *fp, void **data, int size)
983 {
984 int f, cnt=0, ll=0, kk, dim,elements,leading,width;
985 int step=0, s=0, dim_mul_size,nl=0,maxseries;
986 char *str, r[MAX_DSTR], *op;
987 Type t;
988 struct header rec_sep;
989 int d, offset = 1;
990
991 /* what is the max series input */
992 for (s=_dxd_gi_series-1; s>=0; s--)
993 if (_dxd_gi_whichser[s] == ON) break;
994 maxseries = s+1;
995
996 if ( _dxd_gi_asciiformat == FREE )
997 {
998 for (s = step = 0; s < maxseries; s++, step += _dxd_gi_numflds)
999 {
1000 for (f = 0; f < _dxd_gi_numflds; f++)
1001 {
1002 size = _dxfnumGridPoints(f);
1003 dim = _dxd_gi_var[f]->datadim;
1004 t = _dxd_gi_var[f]->datatype;
1005 offset = 1;
1006 if (t == TYPE_STRING) {
1007 offset = dim;
1008 dim=1;
1009 }
1010 if (_dxd_gi_whichflds[f] == ON && _dxd_gi_whichser[s] == ON)
1011 {
1012 for (cnt = 0, d = 0; cnt < dim*size; cnt++)
1013 {
1014 if (!read_ascii(fp,t,data[step+f],d)) {
1015 op = "Reading";
1016 goto parse_error;
1017 }
1018 d += offset;
1019 }
1020 }
1021 else
1022 {
1023 if (!skip_ascii(fp,dim*size)) {
1024 op = "Skipping";
1025 goto parse_error;
1026 }
1027 }
1028 rec_sep = _dxd_gi_var[f]->rec_separat[0];
1029 if (!skip_header(fp,&rec_sep)){
1030 DXAddMessage("error reading record separator");
1031 goto error;
1032 }
1033 }
1034 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
1035 DXAddMessage("error reading series separator %d",s+1);
1036 goto error;
1037 }
1038 }
1039 }
1040 else if ( _dxd_gi_asciiformat == FIX )
1041 {
1042 op = "Reading";
1043 str = (char *)DXAllocate(MAX_DSTR);
1044 for (s=step = 0; s < maxseries; s++, step += _dxd_gi_numflds)
1045 {
1046 for (f = 0; f < _dxd_gi_numflds; f++)
1047 {
1048 size = _dxfnumGridPoints(f);
1049 dim = _dxd_gi_var[f]->datadim;
1050 t = _dxd_gi_var[f]->datatype;
1051 elements = _dxd_gi_var[f]->elements;
1052 leading = _dxd_gi_var[f]->leading;
1053 width = _dxd_gi_var[f]->width;
1054 offset = 1;
1055 if (t == TYPE_STRING) {
1056 offset = dim;
1057 dim=1;
1058 }
1059 dim_mul_size = dim*size;
1060 for (cnt = 0, d = 0; cnt < dim_mul_size; cnt+=elements)
1061 {
1062 if (!(skip_numchar(fp, leading, &str)))
1063 goto parse_error;
1064 kk = 0;
1065 for( ll=0; ll<elements; ll++)
1066 {
1067 if ( cnt+ll < dim_mul_size )
1068 {
1069 strncpy(r, &str[kk], width);
1070 r[width] = (char)NULL;
1071 if (_dxd_gi_whichflds[f] == ON && _dxd_gi_whichser[s]==ON)
1072 {
1073 if (!convert_string(r,t,data[step+f],d,&nl))
1074 goto parse_error;
1075 if (nl==1){
1076 ll--;
1077 nl=0;
1078 kk=0;
1079 if (!(skip_numchar(fp, leading, &str)))
1080 goto parse_error;
1081 }
1082 else{
1083 d += offset;
1084 kk+=width;
1085 }
1086 }
1087 else
1088 {
1089 if (r[0] == '\n'){
1090 ll--;
1091 kk=0;
1092 if (!skip_numchar(fp,leading,&str))
1093 goto parse_error;
1094 }
1095 else{
1096 d += offset;
1097 kk+=width;
1098 }
1099 }
1100 }
1101 }
1102 }
1103 rec_sep = _dxd_gi_var[f]->rec_separat[0];
1104 if (!skip_header(fp,&rec_sep)){
1105 DXAddMessage("error reading record separator");
1106 goto error;
1107 }
1108 }
1109 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
1110 DXAddMessage("error reading series separator %d",s+1);
1111 goto error;
1112 }
1113 }
1114 DXFree(str);
1115 }
1116 return OK;
1117
1118 parse_error:
1119 add_parse_message(op, s,f,(cnt+ll)/dim,(cnt+ll)%dim);
1120 error:
1121 return ERROR;
1122 }
1123
1124 /*
1125 FN: Record Vector binary file format read.
1126 */
1127
RVgetBinaryData(FILE * fp,void ** data,int size)1128 static int RVgetBinaryData(FILE *fp, void **data, int size)
1129 {
1130 int j, len, step, s;
1131 char *op;
1132 struct header rec_sep;
1133 int maxseries;
1134
1135 /* what is the max series input */
1136 for (s=_dxd_gi_series-1; s>=0; s--)
1137 if (_dxd_gi_whichser[s] == ON) break;
1138 maxseries = s+1;
1139
1140 for (s=step= 0; s<maxseries; s++, step += _dxd_gi_numflds)
1141 {
1142 for(j=0; j<_dxd_gi_numflds; j++)
1143 {
1144 size = _dxfnumGridPoints(j);
1145 len = _dxd_gi_var[j]->databytes * _dxd_gi_var[j]->datadim * size;
1146 if (_dxd_gi_whichser[s] == OFF || _dxd_gi_whichflds[j] == OFF)
1147 {
1148 if(!(skip_bdata(fp, len))) {
1149 op = "skip";
1150 goto error;
1151 }
1152 }
1153 else if(!doread(data[step+j], 1, len, fp)) {
1154 op = "read";
1155 goto error;
1156 }
1157 rec_sep = _dxd_gi_var[j]->rec_separat[0];
1158 if (!skip_header(fp,&rec_sep)){
1159 op = " read record separator";
1160 goto error;
1161 }
1162 }
1163 if ((_dxd_gi_series-1) != s && !skip_header(fp,&_dxd_gi_serseparat)){
1164 op = "read series separator";
1165 goto error;
1166 }
1167 }
1168 return OK;
1169
1170 error:
1171 if (_dxd_gi_series > 1)
1172 DXAddMessage("\nTrying to %s field '%s' of series %d",op,_dxd_gi_var[j]->name,s+1);
1173 else
1174 DXAddMessage("\nTrying to %s field '%s'",op,_dxd_gi_var[j]->name);
1175 return ERROR;
1176 }
1177
1178 /*
1179 * DXRead a value of type 't' from stream fp and put it in the index'th
1180 * array position relative to data for the given type.
1181 *
1182 */
1183 static Error
read_ascii(FILE * fp,Type t,void * data,int index)1184 read_ascii(FILE *fp, Type t, void *data, int index)
1185 {
1186 int r, i;
1187 char string[80];
1188
1189 switch (t) {
1190 case TYPE_BYTE:
1191 r = fscanf(fp,"%d",&i);
1192 if (i<DXD_MIN_BYTE || i>DXD_MAX_BYTE) {
1193 DXSetError(ERROR_DATA_INVALID,"#10905",i,"byte");
1194 goto error;
1195 }
1196 DREF(byte,data,index) = (byte)i;
1197 break;
1198 case TYPE_UBYTE:
1199 r = fscanf(fp,"%d",&i);
1200 if (i<0 || i>DXD_MAX_UBYTE) {
1201 DXSetError(ERROR_DATA_INVALID,"#10905",i,"ubyte");
1202 goto error;
1203 }
1204 DREF(ubyte,data,index) = (ubyte)i;
1205 break;
1206 case TYPE_SHORT:
1207 r = fscanf(fp,"%d",&i);
1208 if (i<DXD_MIN_SHORT || i>DXD_MAX_SHORT) {
1209 DXSetError(ERROR_DATA_INVALID,"#10905",i,"short");
1210 goto error;
1211 }
1212 DREF(short,data,index) = (short)i;
1213 break;
1214 case TYPE_USHORT:
1215 r = fscanf(fp,"%d",&i);
1216 if (i<0 || i>DXD_MAX_USHORT) {
1217 DXSetError(ERROR_DATA_INVALID,"#10905",i,"ushort");
1218 goto error;
1219 }
1220 DREF(unsigned short,data,index) = (unsigned short)i;
1221 break;
1222 case TYPE_INT:
1223 r = fscanf(fp,"%d",&DREF(int,data,index));
1224 break;
1225 case TYPE_UINT:
1226 r = fscanf(fp,"%u",&DREF(unsigned int,data,index));
1227 break;
1228 case TYPE_FLOAT:
1229 r = fscanf(fp,"%f",&DREF(float,data,index));
1230 break;
1231 case TYPE_DOUBLE:
1232 r = fscanf(fp,"%lf",&DREF(double,data,index));
1233 break;
1234 case TYPE_STRING:
1235 r = fscanf(fp,"%s",&DREF(char,data,index));
1236 break;
1237 default:
1238 DXErrorGoto(ERROR_INTERNAL,
1239 "Type not implemented for ascii files");
1240 }
1241
1242 if (r == 0){
1243 fscanf(fp,"%70s",string);
1244 DXSetError(ERROR_DATA_INVALID, "#10906",string);
1245 goto error;
1246 }
1247
1248 if (r == EOF){
1249 DXSetError(ERROR_MISSING_DATA, "#10898",_dxd_gi_filename);
1250 goto error;
1251 }
1252
1253 return OK;
1254 error:
1255 return ERROR;
1256
1257 }
1258
1259 /* skip n numbers */
1260 static Error
skip_ascii(FILE * fp,int num)1261 skip_ascii(FILE *fp, int num)
1262 {
1263 int c,prev,curr,found;
1264
1265 c = getc(fp);
1266 if (c == ' ' || c == '\n' || c == '\t'){
1267 prev = 0;
1268 found = 0;
1269 }
1270 else {
1271 prev = 1;
1272 found = 1;
1273 }
1274 while (1) {
1275 c = getc(fp);
1276 if (c == ' ' || c == '\n' || c == '\t') curr = 0;
1277 else curr = 1;
1278 if (prev != curr) found++;
1279 if (found == 2*num) break;
1280 prev=curr;
1281 }
1282 /* put back last whitespace */
1283 ungetc(c,fp);
1284 return OK;
1285 }
1286
1287 /*
1288 * Convert the string of characters to a numeric value of type 't'
1289 * and put it in the index'th array position relative to data for the
1290 * given type.
1291 */
1292 static Error
convert_string(char * s,Type t,void * data,int index,int * nl)1293 convert_string(char *s, Type t, void *data, int index,int *nl)
1294 {
1295 int i;
1296 float f;
1297 double d;
1298 char format[5];
1299
1300 /* if newline return nl=1 */
1301 if (s[0]=='\n') {*nl=1; return OK;}
1302
1303 switch (t) {
1304 case TYPE_BYTE:
1305 if (sscanf(s,"%d",&i) <= 0) {
1306 DXSetError(ERROR_DATA_INVALID,"#10907","byte",s);
1307 goto error;
1308 }
1309 if (i<DXD_MIN_BYTE || i>DXD_MAX_BYTE) {
1310 DXSetError(ERROR_DATA_INVALID,"#10905",i,"byte");
1311 goto error;
1312 }
1313 DREF(byte,data,index) = (byte)i;
1314 break;
1315 case TYPE_UBYTE:
1316 if (sscanf(s,"%d",&i) <= 0) {
1317 DXSetError(ERROR_DATA_INVALID,"#10907","ubyte",s);
1318 goto error;
1319 }
1320 if (i<0 || i>DXD_MAX_UBYTE) {
1321 DXSetError(ERROR_DATA_INVALID,"#10905",i,"ubyte");
1322 goto error;
1323 }
1324 DREF(ubyte,data,index) = (ubyte)i;
1325 break;
1326 case TYPE_SHORT:
1327 if (sscanf(s,"%d",&i) <= 0) {
1328 DXSetError(ERROR_DATA_INVALID,"#10907","short",s);
1329 goto error;
1330 }
1331 if (i<DXD_MIN_SHORT || i>DXD_MAX_SHORT) {
1332 DXSetError(ERROR_DATA_INVALID,"#10905",i,"short");
1333 goto error;
1334 }
1335 DREF(short,data,index) = (short)i;
1336 break;
1337 case TYPE_USHORT:
1338 if (sscanf(s,"%d",&i) <= 0) {
1339 DXSetError(ERROR_DATA_INVALID,"#10907","ushort",s);
1340 goto error;
1341 }
1342 if (i<0 || i>DXD_MAX_USHORT) {
1343 DXSetError(ERROR_DATA_INVALID,"#10905",i,"ushort");
1344 goto error;
1345 }
1346 DREF(unsigned short,data,index) = (unsigned short)i;
1347 break;
1348 case TYPE_INT:
1349 if (sscanf(s,"%d",&i) <= 0) {
1350 DXSetError(ERROR_DATA_INVALID,"#10907","int",s);
1351 goto error;
1352 }
1353 DREF(int,data,index) = i;
1354 break;
1355 case TYPE_UINT:
1356 if (sscanf(s,"%u",&i) <= 0) {
1357 DXSetError(ERROR_DATA_INVALID,"#10907","uint",s);
1358 goto error;
1359 }
1360 DREF(unsigned int,data,index) = i;
1361 break;
1362 case TYPE_FLOAT:
1363 if (sscanf(s,"%f",&f) <= 0) {
1364 DXSetError(ERROR_DATA_INVALID,"#10907","float",s);
1365 goto error;
1366 }
1367 DREF(float,data,index) = f;
1368 break;
1369 case TYPE_DOUBLE:
1370 if (sscanf(s,"%lf",&d) <= 0) {
1371 DXSetError(ERROR_DATA_INVALID,"#10907","double",s);
1372 goto error;
1373 }
1374 DREF(double,data,index) = d;
1375 break;
1376 case TYPE_STRING:
1377 i = strlen(s)+1;
1378 if (s[i-2] == '\n')
1379 s[i-2] = (char)NULL;
1380 i = strlen(s) + 1;
1381 sprintf(format,"%%%dc",i);
1382 if (sscanf(s,format,&DREF(char,data,index)) <=0){
1383 DXSetError(ERROR_DATA_INVALID,"#10907","string",s);
1384 goto error;
1385 }
1386 break;
1387 default:
1388 DXErrorGoto(ERROR_INTERNAL, "Unexpected type for ascii files");
1389 }
1390
1391 return OK;
1392 error:
1393 return ERROR;
1394
1395 }
1396
1397 /*
1398 * Skip the header, which can be denoted by either a number of lines
1399 * or bytes, or a marker string.
1400 * Returns OK/ERROR, and sets error code on ERROR.
1401 */
1402 static Error
skip_header(FILE * fp,struct header * head)1403 skip_header(FILE *fp, struct header *head)
1404 {
1405 int i, c;
1406 char s[MAX_DSTR];
1407
1408
1409 switch (head->type) {
1410 case SKIP_MARKER:
1411 for (i=0;;) {
1412 c = getc(fp);
1413 if (c == EOF) {
1414 DXSetError(ERROR_DATA_INVALID,"#10898",
1415 "before encountering header marker");
1416 goto error;
1417 } else if ((char)c == head->marker[i]) {
1418 if (head->marker[++i] == '\0')
1419 break;
1420 } else
1421 i=0;
1422 }
1423 break;
1424 case SKIP_LINES:
1425 for (i=0; i<head->size; ) {
1426 if (!fgets(s, MAX_DSTR, fp)){
1427 DXSetError(ERROR_MISSING_DATA,"#10910","lines");
1428 goto error;
1429 }
1430 if (s[strlen(s)-1] == '\n')
1431 i++;
1432 }
1433 break;
1434 case SKIP_BYTES:
1435 if (fseek(fp, head->size, 1) != 0){
1436 DXSetError(ERROR_MISSING_DATA,"#10910","byte");
1437 goto error;
1438 }
1439 break;
1440 case SKIP_NOTHING:
1441 break;
1442 default:
1443 DXSetError(ERROR_INTERNAL,"#10910","all");
1444 goto error;
1445 }
1446
1447 return OK;
1448
1449 error:
1450 return ERROR;
1451 }
1452
1453 /*
1454 * Skip some bytes in a file.
1455 * Returns OK/ERROR, and sets error code on ERROR.
1456 */
1457 static Error
skip_bdata(FILE * fp,int toskip)1458 skip_bdata(FILE *fp, int toskip)
1459 {
1460
1461 if (_dxd_gi_format == BINARY && toskip != 0) {
1462 if (fseek(fp, toskip, 1) != 0) {
1463 DXSetError(ERROR_MISSING_DATA,"#10911",
1464 ftell(fp) + toskip);
1465 goto error;
1466 }
1467 }
1468
1469 return OK;
1470
1471 error:
1472 return ERROR;
1473 }
1474 /*
1475 * Do fread()s until we are sure we either have all the data or
1476 * we hit an end of file.
1477 */
1478 static Error
doread(void * p,int size,int cnt,FILE * fp)1479 doread(void *p, int size, int cnt, FILE* fp)
1480 {
1481 int left,n;
1482
1483 for (left=cnt*size; left>0 ; ) {
1484 n = fread((char*)p, 1, left, fp);
1485 if (n == 0) {
1486 DXSetError(ERROR_MISSING_DATA,"#10898","data file");
1487 goto error;
1488 }
1489 left -= n;
1490 p = (char*)p + n;
1491 }
1492
1493 return OK;
1494
1495 error:
1496 return ERROR;
1497 }
1498
1499 /*
1500 * Skip number of characters in a file from the point defined by fp.
1501 * Returns OK/ERROR and sets error code on ERROR.
1502 */
1503 static Error
skip_numchar(FILE * fp,int num_char,char ** ret_str)1504 skip_numchar(FILE *fp, int num_char, char **ret_str)
1505 {
1506 int i, c;
1507
1508 for (i=0; i<num_char; i++)
1509 {
1510 c = getc(fp);
1511 if (c == EOF)
1512 {
1513 DXSetError(ERROR_DATA_INVALID,"#10898",
1514 "skipping beginning of line characters");
1515 goto error;
1516 }
1517 else if (c == '\n')
1518 {
1519 DXSetError(ERROR_DATA_INVALID,"#10899",
1520 "skipping beginning of line characters");
1521 goto error;
1522 }
1523 }
1524 /* if (!fgets(ret_str, MAX_DSTR, fp)) */
1525 if (!_dxf_getline(ret_str,fp))
1526 goto error;
1527 return OK;
1528
1529 error:
1530 return ERROR;
1531 }
1532
1533 /* getline allocating space as you go
1534 */
1535 static
_dxf_getline(char ** ret_str,FILE * fp)1536 Error _dxf_getline(char **ret_str,FILE *fp)
1537 {
1538 char str[MAX_DSTR];
1539 int n=0;
1540 char *line = *ret_str;
1541
1542 /* get newline allocating space if ness */
1543 if ((fgets(str,MAX_DSTR,fp))==NULL){
1544 DXSetError(ERROR_DATA_INVALID,"#10898",_dxd_gi_filename);
1545 return ERROR;
1546 }
1547 strcpy(line,str);
1548 while ((int)strlen(str)>MAX_DSTR-2){
1549 if ((fgets(str,MAX_DSTR,fp))==NULL){
1550 DXSetError(ERROR_DATA_INVALID,"#10898","data file");
1551 return ERROR;
1552 }
1553 n++;
1554 line = (char *)DXReAllocate(line,(unsigned int)strlen(str)+n*MAX_DSTR);
1555 strcat(line,str);
1556 }
1557 *ret_str = line;
1558 return OK;
1559 }
1560
1561 /* search for header info (keeping track of lines and bytes read)
1562 * and when found place into data
1563 */
1564 Error
_dxf_gi_extract(struct place_state * dataps,int * read_header)1565 _dxf_gi_extract(struct place_state *dataps,int *read_header)
1566 {
1567 int i,k;
1568 int num_sets=0,sets_read=0;
1569 char str[MAX_DSTR], *pmark;
1570 int read[MAX_POS_DIMS*3];
1571
1572 /* open the data file if not already open */
1573 if(!dataps->fp && !_dxf_gi_OpenFile(_dxd_gi_filename, &dataps->fp, 0))
1574 return ERROR;
1575
1576 /* how many offset are there? */
1577 for (i=0; _dxd_gi_fromfile[i]; i++){
1578 if (_dxd_gi_fromfile[i]->begin.type==SKIP_NOTHING){
1579 sets_read++;
1580 read[i]=1;
1581 }
1582 else
1583 read[i]=0;
1584 }
1585 num_sets=i;
1586
1587 /* read one line at a time searching for any header */
1588 while (fgets(str, MAX_DSTR, dataps->fp) != NULL){
1589 /* are any header lines and if so are the the current line */
1590 for (i=0; i<num_sets; i++){
1591 if (_dxd_gi_fromfile[i]->begin.type==SKIP_LINES &&
1592 dataps->lines == _dxd_gi_fromfile[i]->begin.size){
1593 if (!extract_fromline(str,i))
1594 goto error;
1595 sets_read++;
1596 read[i]=1;
1597 }
1598 else if (_dxd_gi_fromfile[i]->begin.type==SKIP_BYTES &&
1599 dataps->bytes <= _dxd_gi_fromfile[i]->begin.size &&
1600 (dataps->bytes+strlen(str))>_dxd_gi_fromfile[i]->begin.size){
1601 k = _dxd_gi_fromfile[i]->begin.size - dataps->bytes;
1602 if (!extract_fromline(&str[k],i))
1603 goto error;
1604 sets_read++;
1605 read[i]=1;
1606 }
1607 else if (_dxd_gi_fromfile[i]->begin.type==SKIP_MARKER &&
1608 (pmark = strstr(str,_dxd_gi_fromfile[i]->begin.marker))!=NULL){
1609 if (read[i] == 1){ /* already hit this marker once */
1610 DXWarning("the marker \"%s\" is defined more than one place in this file, check your results",_dxd_gi_fromfile[i]->begin.marker);
1611 continue;
1612 }
1613 for( k=0; k<strlen(_dxd_gi_fromfile[i]->begin.marker);k++)
1614 pmark++;
1615 if (!extract_fromline(pmark,i))
1616 goto error;
1617 sets_read++;
1618 read[i]=1;
1619 }
1620 }
1621 dataps->lines++;
1622 dataps->bytes += strlen(str);
1623 /* search for header marker if exists and if found return flag */
1624 if (_dxd_gi_header.type==SKIP_MARKER &&
1625 strstr(str,_dxd_gi_header.marker)){
1626 if (sets_read == num_sets &&
1627 _dxd_gi_header.marker[strlen(_dxd_gi_header.marker-1)]=='\n')
1628 _dxd_gi_header.type = SKIP_NOTHING;
1629 else
1630 *read_header=1;
1631 }
1632 if (sets_read == num_sets) break;
1633 }
1634
1635 /* all offsets were found? */
1636 if (sets_read < num_sets){
1637 for (i=0; i<num_sets; i++){
1638 if (read[i]==0){
1639 DXSetError(ERROR_DATA_INVALID,"offset for field %d not found",i);
1640 goto error;
1641 }
1642 }
1643 }
1644
1645 return OK;
1646
1647 error:
1648 return ERROR;
1649 }
1650
1651 /* read data from a line */
1652 static Error
extract_fromline(char str[MAX_DSTR],int which)1653 extract_fromline(char str[MAX_DSTR],int which)
1654 {
1655 int i,j,k,index,width,nl=0;
1656 Type t;
1657 char r[MAX_DSTR];
1658
1659 i = which;
1660 t = _dxd_gi_fromfile[i]->type;
1661 j=0;
1662 k=0;
1663 index=0;
1664 while (_dxd_gi_fromfile[i]->skip[j] >= 0){
1665 k += _dxd_gi_fromfile[i]->skip[j];
1666 width = _dxd_gi_fromfile[i]->width[j];
1667 strncpy(r, &str[k], width);
1668 r[width] = (char)NULL;
1669 if (!convert_string(r,t,_dxd_gi_fromfile[i]->data,index,&nl))
1670 goto error;
1671 if (nl){
1672 DXSetError(ERROR_DATA_INVALID,"error reading values");
1673 goto error;
1674 }
1675 index++;
1676 j++;
1677 k += width;
1678 }
1679 if (j==0){ /* not skip info read all values on this line */
1680 index=0;
1681 for (k=0; k<strlen(str); ){
1682 while(str[k]==' ' || str[k]=='\t') /* skip whitespace */
1683 k++;
1684 if (k>=strlen(str)) break;
1685 if (isdigit(str[k]) || str[k]=='-' || str[k]=='.'){
1686 strcpy(r,&str[k]);
1687 if (!convert_string(r,t,_dxd_gi_fromfile[i]->data,index,&nl))
1688 goto error;
1689 if (nl){
1690 DXSetError(ERROR_DATA_INVALID,"error reading values");
1691 goto error;
1692 }
1693 _dxd_gi_fromfile[i]->skip[index] = 0; /*set skip to indicate number*/
1694 index++;
1695 while(str[k]!=' ' && str[k]!='\t') /* skip number */
1696 k++;
1697 }
1698 else
1699 break;
1700 }
1701 _dxd_gi_fromfile[i]->skip[index]=-1;
1702 }
1703 return OK;
1704
1705 error:
1706 return ERROR;
1707 }
1708
1709
1710 /*
1711 * DXAdd a message to the current error message indicating the give
1712 * series number (s), field name (from f), item number in field (item)
1713 * and the component of the given item (comp).
1714 */
1715 static void
add_parse_message(char * op,int s,int f,int item,int comp)1716 add_parse_message(char *op, int s, int f, int item, int comp)
1717 {
1718
1719 item++; /* Change to a base 1 */
1720
1721 if (_dxd_gi_series > 1) {
1722 s++;
1723 if (_dxd_gi_var[f]->datadim > 1)
1724 DXAddMessage("\n%s Series %d, Field '%s', Datum %d, Component %d",
1725 op, s,_dxd_gi_var[f]->name,item,comp+1);
1726 else
1727 DXAddMessage("\n%s Series %d, Field '%s', Datum %d",
1728 op, s,_dxd_gi_var[f]->name,item);
1729 } else {
1730 if (_dxd_gi_var[f]->datadim > 1)
1731 DXAddMessage("\n%s Field '%s', Datum %d, Component %d",
1732 op, _dxd_gi_var[f]->name,item,comp+1);
1733 else
1734 DXAddMessage("\n%s Field '%s', Datum %d",op,_dxd_gi_var[f]->name,item);
1735 }
1736 }
1737
1738 /*
1739 FN: reorder data arg1 from row majority to column majority.
1740 EF: arg1 pointer points to a set of reordered data and original space has
1741 been freed. NULL on error and sets error code.
1742 Note: handle only 2, 3 and 4 dimensional data.
1743 */
1744
1745 static void*
reorderData(void * data,int f)1746 reorderData(void *data, int f)
1747 /*reorderData(void *data, int ndatum, int rank, Type type) */
1748 {
1749 void *d1 = NULL;
1750 int xskip, k, x, y, z, v, offset, data_size;
1751 int dim0,dim1,dim2,dim3,adjust,rank,ndatum;
1752 Type type;
1753
1754 ndatum = _dxfnumGridPoints(f);
1755 type = _dxd_gi_var[f]->datatype;
1756 rank = _dxd_gi_var[f]->datadim;
1757 if (_dxd_gi_var[f]->datadep==DEP_CONNECTIONS) adjust=1;
1758 else adjust=0;
1759
1760 if ( _dxd_gi_numdims == 1 )
1761 return data;
1762
1763 data_size = DXTypeSize(type) * rank;
1764 dim0 = _dxd_gi_dimsize[0]-adjust;
1765 dim1 = _dxd_gi_dimsize[1]-adjust;
1766
1767 if (!(d1 = (void *)DXAllocate(ndatum * data_size)))
1768 goto error;
1769
1770 k = 0;
1771
1772 if (_dxd_gi_numdims == 2)
1773 {
1774 xskip = dim1 * data_size;
1775 for (y = 0; y < dim1; y++)
1776 {
1777 offset = y * data_size;
1778 for (x = 0; x < dim0; x++)
1779 {
1780 memcpy((char*)d1 + offset, (char*)data + k, data_size);
1781 k += data_size;
1782 offset += xskip;
1783 }
1784 }
1785 }
1786 else if (_dxd_gi_numdims == 3)
1787 {
1788 dim2 = _dxd_gi_dimsize[2] - adjust;
1789 for (z = 0; z < dim2; z++)
1790 {
1791 for (y = 0; y < dim1; y++)
1792 {
1793 for (x = 0; x < dim0; x++)
1794 {
1795 offset = (x*dim1*dim2)+(y*dim2)+z;
1796 offset *= data_size;
1797 memcpy((char*)d1 + offset, (char*)data + k, data_size);
1798 k += data_size;
1799 }
1800 }
1801 }
1802 }
1803 else if (_dxd_gi_numdims == 4)
1804 {
1805 dim2 = _dxd_gi_dimsize[2] - adjust;
1806 dim3 = _dxd_gi_dimsize[3] - adjust;
1807 for (v = 0; v < dim3; v++)
1808 {
1809 for (z = 0; z < dim2; z++)
1810 {
1811 for (y = 0; y < dim1; y++)
1812 {
1813 for (x = 0; x < dim0; x++)
1814 {
1815 offset = (x*dim1*dim2*dim3) +
1816 (y*dim2*dim3) + (z*dim3) + v;
1817 offset *= data_size;
1818 memcpy((char*)d1 + offset, (char*)data + k, data_size);
1819 k += data_size;
1820 }
1821 }
1822 }
1823 }
1824 }
1825 else
1826 {
1827 DXSetError(ERROR_NOT_IMPLEMENTED,"#10913",_dxd_gi_numdims);
1828 goto error;
1829 }
1830
1831 DXFree((Pointer) data );
1832 return d1;
1833
1834 error:
1835 if (d1) DXFree((Pointer)d1);
1836
1837 return NULL;
1838 }
1839
1840 /*
1841 * Denormalize any floating point numbers in XF.
1842 */
1843 #if !defined(DXD_STANDARD_IEEE)
1844 static void
_dxfdenormalize(void ** XF)1845 _dxfdenormalize(void **XF)
1846 {
1847 int size, f, s, i, badfp, denorm, nitems;
1848
1849 for (f=0 ; f<_dxd_gi_numflds ; f++) {
1850 size = _dxfnumGridPoints(f);
1851 if (_dxd_gi_whichflds[f] == ON) {
1852 nitems = size * _dxd_gi_var[f]->datadim;
1853 badfp = denorm = 0;
1854 switch (_dxd_gi_var[f]->datatype) {
1855 case TYPE_DOUBLE:
1856 for (s=i=0 ; i<_dxd_gi_series ; i++, s+=_dxd_gi_numflds)
1857 if (_dxd_gi_whichser[i] == ON)
1858 _dxfdouble_denorm(XF[s+f],nitems,&denorm,&badfp);
1859 break;
1860 case TYPE_FLOAT:
1861 for (s=i=0 ; i<_dxd_gi_series ; i++, s+=_dxd_gi_numflds)
1862 if (_dxd_gi_whichser[i] == ON)
1863 _dxffloat_denorm(XF[s+f],nitems,&denorm,&badfp);
1864 break;
1865 }
1866 if (denorm && badfp)
1867 DXWarning("Denormalized and NaN/Infinite floating point numbers in field '%s'",
1868 _dxd_gi_var[f]->name);
1869 else if (denorm)
1870 DXWarning("Denormalized floating point numbers in field '%s'",
1871 _dxd_gi_var[f]->name);
1872 else if (badfp)
1873 DXWarning("NaN/Infinite floating point numbers in field '%s'",
1874 _dxd_gi_var[f]->name);
1875
1876 }
1877 }
1878 }
1879 #endif /* !normal ieee */
1880
1881 /*
1882 * Convert cnt items of type from_type in the given array to floats.
1883 * Return a pointer to the converted array.
1884 * We do an DXAllocateLocal here, because we know that the array data
1885 * will eventually be copied into an Array with DXAddArrayData.
1886 */
1887 static Pointer
locations2float(Pointer from,Type from_type,int cnt)1888 locations2float(Pointer from, Type from_type, int cnt)
1889 {
1890 int i;
1891 float *f;
1892
1893 f = (float*)DXAllocateLocal(cnt * sizeof(float));
1894 if (!f) {
1895 f = (float *)DXAllocate(cnt * sizeof(float));
1896 if (!f)
1897 goto error;
1898 }
1899
1900 switch (from_type) {
1901 case TYPE_UBYTE:
1902 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(ubyte,from,i);
1903 break;
1904 case TYPE_BYTE:
1905 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(byte,from,i);
1906 break;
1907 case TYPE_SHORT:
1908 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(short,from,i);
1909 break;
1910 case TYPE_USHORT:
1911 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(ushort,from,i);
1912 break;
1913 case TYPE_INT:
1914 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(int,from,i);
1915 break;
1916 case TYPE_UINT:
1917 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(uint,from,i);
1918 break;
1919 case TYPE_DOUBLE: /* FIXME: may need to check value on PVS */
1920 for (i=0 ; i<cnt ; i++) f[i] = (float)DREF(double,from,i);
1921 break;
1922 default:
1923 DXErrorGoto(ERROR_UNEXPECTED,"Can't copy locations for given type");
1924 }
1925 return (Pointer)f;
1926 error:
1927 if (f) DXFree((Pointer)f);
1928 return NULL;
1929 }
1930
1931