1 /*============================================================================
2 MetaIO
3 Copyright 2000-2010 Insight Software Consortium
4
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
7
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #ifdef _MSC_VER
13 #pragma warning(disable:4702)
14 #pragma warning(disable:4996)
15 namespace {
IsBlank(int c)16 inline bool IsBlank(int c)
17 {
18 return c == '\t' || c == ' ';
19 }
20 }
21 #else
22 //# ifdef isblank
23 # define IsBlank(c) isblank((c))
24 //# else
25 //# define IsBlank(x) (((x)==32) || ((x)==9))
26 //# endif
27 #endif
28
29 #include "metaUtils.h"
30
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <stddef.h>
34
35 #include <sys/stat.h>
36 #include <fcntl.h>
37
38 #if defined(_WIN32) && !defined(__CYGWIN__)
39 #include <winsock2.h>
40 #else
41 #include <unistd.h>
42 #include <arpa/inet.h>
43 #endif
44
45 #include <stdlib.h>
46 #include <string.h>
47 #include <string>
48
49 #if defined (__BORLANDC__) && (__BORLANDC__ >= 0x0580)
50 #include <mem.h>
51 #endif
52
53 #if (METAIO_USE_NAMESPACE)
54 namespace METAIO_NAMESPACE {
55 #endif
56
57 int META_DEBUG = 0;
58
59 static char MET_SeperatorChar = '=';
60
61 MET_FieldRecordType *
MET_GetFieldRecord(const char * _fieldName,METAIO_STL::vector<MET_FieldRecordType * > * _fields)62 MET_GetFieldRecord(const char * _fieldName,
63 METAIO_STL::vector<MET_FieldRecordType *> * _fields)
64 {
65 METAIO_STL::vector<MET_FieldRecordType *>::iterator fieldIter;
66 for(fieldIter=_fields->begin(); fieldIter!=_fields->end(); fieldIter++)
67 {
68 if(!strcmp((*fieldIter)->name, _fieldName))
69 {
70 return *fieldIter;
71 }
72 }
73 return NULL;
74 }
75
76
77 int
MET_GetFieldRecordNumber(const char * _fieldName,METAIO_STL::vector<MET_FieldRecordType * > * _fields)78 MET_GetFieldRecordNumber(const char * _fieldName,
79 METAIO_STL::vector<MET_FieldRecordType *> * _fields)
80 {
81 int i;
82 for(i=0; i<(int)_fields->size(); i++)
83 {
84 if(!strcmp((*_fields)[i]->name, _fieldName))
85 {
86 return i;
87 }
88 }
89 return -1;
90 }
91
92
93 //
94 // Sizeof METTYPE
95 //
MET_SizeOfType(MET_ValueEnumType _vType,int * s)96 bool MET_SizeOfType(MET_ValueEnumType _vType, int *s)
97 {
98 *s = MET_ValueTypeSize[_vType];
99 if(_vType < MET_STRING)
100 {
101 return true;
102 }
103 else
104 {
105 return false;
106 }
107 }
108
109
110 //
111 //
112 //
MET_SystemByteOrderMSB(void)113 bool MET_SystemByteOrderMSB(void)
114 {
115 const int l = 1;
116 const char * u = (const char *) & l;
117
118 if (u[0])
119 {
120 return false;
121 }
122 else
123 {
124 return true;
125 }
126 }
127
128
129 //
130 // Read the type of the object
131 //
MET_ReadForm(METAIO_STREAM::istream & _fp)132 METAIO_STL::string MET_ReadForm(METAIO_STREAM::istream &_fp)
133 {
134 METAIO_STL::streampos pos = _fp.tellg();
135 METAIO_STL::vector<MET_FieldRecordType *> fields;
136 MET_FieldRecordType* mF = new MET_FieldRecordType;
137 MET_InitReadField(mF, "FormTypeName", MET_STRING, false);
138 mF->required = false;
139 mF->terminateRead = true;
140 fields.push_back(mF);
141
142 MET_Read(_fp, &fields, '=', true);
143 _fp.seekg(pos);
144
145 if(mF->defined)
146 {
147 METAIO_STL::string value = (char *)(mF->value);
148 delete mF;
149 return value;
150 }
151
152 delete mF;
153 return METAIO_STL::string();
154 }
155
156 //
157 // Read the type of the object
158 //
MET_ReadType(METAIO_STREAM::istream & _fp)159 METAIO_STL::string MET_ReadType(METAIO_STREAM::istream &_fp)
160 {
161 METAIO_STL::streampos pos = _fp.tellg();
162 METAIO_STL::vector<MET_FieldRecordType *> fields;
163 MET_FieldRecordType* mF = new MET_FieldRecordType;
164 MET_InitReadField(mF, "ObjectType", MET_STRING, false);
165 mF->required = false;
166 mF->terminateRead = true;
167 fields.push_back(mF);
168
169 MET_Read(_fp, &fields, '=', true);
170 _fp.seekg(pos);
171
172 if(mF->defined)
173 {
174 METAIO_STL::string value = (char *)(mF->value);
175 delete mF;
176 return value;
177 }
178
179 delete mF;
180 return METAIO_STL::string();
181 }
182
183 //
184 // Read the subtype of the object
185 //
MET_ReadSubType(METAIO_STREAM::istream & _fp)186 char* MET_ReadSubType(METAIO_STREAM::istream &_fp)
187 {
188 METAIO_STL::streampos pos = _fp.tellg();
189 METAIO_STL::vector<MET_FieldRecordType *> fields;
190 MET_FieldRecordType* mF;
191 mF = new MET_FieldRecordType;
192 MET_InitReadField(mF, "ObjectType", MET_STRING, false);
193 mF->required = false;
194 fields.push_back(mF);
195
196 MET_Read(_fp, &fields, '=', true);
197
198 // Find the line right after the ObjectType
199 char s[1024];
200 _fp.getline( s, 500 );
201 METAIO_STL::string value = s;
202 size_t position = value.find("=");
203 if(position!=METAIO_STL::string::npos)
204 {
205 value = value.substr(position+2,value.size()-position);
206 }
207 _fp.seekg(pos);
208
209 char* ret = new char[value.size()+1];
210 strncpy(ret,value.c_str(),value.size());
211 ret[value.size()] = '\0';
212 delete mF;
213 return ret;
214 }
215
216
217 //
218 // String To Type
219 //
MET_StringToType(const char * _s,MET_ValueEnumType * _vType)220 bool MET_StringToType(const char *_s, MET_ValueEnumType *_vType)
221 {
222 int i;
223 for(i=0; i<MET_NUM_VALUE_TYPES; i++)
224 {
225 if(!strcmp(_s, MET_ValueTypeName[i]))
226 {
227 *_vType = (MET_ValueEnumType)i;
228 return true;
229 }
230 }
231
232 *_vType = MET_OTHER;
233 return false;
234 }
235
236 //
237 // METType To String
238 //
MET_TypeToString(MET_ValueEnumType _vType,char * _s)239 bool MET_TypeToString(MET_ValueEnumType _vType, char *_s)
240 {
241 if(_vType>=0 && _vType<=MET_NUM_VALUE_TYPES)
242 {
243 strcpy(_s, MET_ValueTypeName[_vType]);
244 return true;
245 }
246
247 return false;
248 }
249
250
251
252 //
253 // Value to Double
254 //
MET_ValueToDouble(MET_ValueEnumType _type,const void * _data,METAIO_STL::streamoff _index,double * _value)255 bool MET_ValueToDouble(MET_ValueEnumType _type, const void *_data,
256 METAIO_STL::streamoff _index,
257 double *_value)
258 {
259 switch(_type)
260 {
261 case MET_ASCII_CHAR:
262 case MET_CHAR:
263 case MET_CHAR_ARRAY:
264 *_value = (double)(((const MET_CHAR_TYPE *)_data)[_index]);
265 return true;
266 case MET_UCHAR:
267 case MET_UCHAR_ARRAY:
268 *_value = (double)(((const MET_UCHAR_TYPE *)_data)[_index]);
269 return true;
270 case MET_SHORT:
271 case MET_SHORT_ARRAY:
272 *_value = (double)(((const MET_SHORT_TYPE *)_data)[_index]);
273 return true;
274 case MET_USHORT:
275 case MET_USHORT_ARRAY:
276 *_value = (double)(((const MET_USHORT_TYPE *)_data)[_index]);
277 return true;
278 case MET_INT:
279 case MET_INT_ARRAY:
280 *_value = (double)(((const MET_INT_TYPE *)_data)[_index]);
281 return true;
282 case MET_LONG:
283 case MET_LONG_ARRAY:
284 *_value = (double)(((const MET_LONG_TYPE *)_data)[_index]);
285 return true;
286 case MET_UINT:
287 case MET_UINT_ARRAY:
288 *_value = (double)(((const MET_UINT_TYPE *)_data)[_index]);
289 return true;
290 case MET_ULONG:
291 case MET_ULONG_ARRAY:
292 *_value = (double)(((const MET_ULONG_TYPE *)_data)[_index]);
293 return true;
294 case MET_LONG_LONG:
295 case MET_LONG_LONG_ARRAY:
296 *_value = (double)(((const MET_LONG_LONG_TYPE *)_data)[_index]);
297 return true;
298 case MET_ULONG_LONG:
299 case MET_ULONG_LONG_ARRAY:
300 #if defined(_MSC_VER) || defined(__HP_aCC)
301 // NOTE: you cannot use __int64 in an ostream in MSV6 or HPUX
302 *_value = (double)((MET_LONG_LONG_TYPE)
303 ((((const MET_ULONG_LONG_TYPE *)_data)[_index])));
304 #else
305 *_value = (double)((((const MET_ULONG_LONG_TYPE *)_data)[_index]));
306 #endif
307 return true;
308 case MET_FLOAT:
309 case MET_FLOAT_ARRAY:
310 case MET_FLOAT_MATRIX:
311 *_value = (double)(((const MET_FLOAT_TYPE *)_data)[_index]);
312 return true;
313 case MET_DOUBLE:
314 case MET_DOUBLE_ARRAY:
315 *_value = (double)(((const MET_DOUBLE_TYPE *)_data)[_index]);
316 return true;
317 case MET_STRING:
318 *_value = atof(&(((const MET_CHAR_TYPE *)_data)[_index]));
319 return true;
320 default:
321 *_value = 0;
322 return false;
323 }
324 }
325
MET_DoubleToValue(double _value,MET_ValueEnumType _type,void * _data,METAIO_STL::streamoff _index)326 bool MET_DoubleToValue(double _value,
327 MET_ValueEnumType _type,
328 void *_data,
329 METAIO_STL::streamoff _index)
330 {
331 switch(_type)
332 {
333 case MET_ASCII_CHAR:
334 case MET_CHAR:
335 case MET_CHAR_ARRAY:
336 ((MET_CHAR_TYPE *)_data)[_index] = (MET_CHAR_TYPE)_value;
337 return true;
338 case MET_UCHAR:
339 case MET_UCHAR_ARRAY:
340 ((MET_UCHAR_TYPE *)_data)[_index] = (MET_UCHAR_TYPE)_value;
341 return true;
342 case MET_SHORT:
343 case MET_SHORT_ARRAY:
344 ((MET_SHORT_TYPE *)_data)[_index] = (MET_SHORT_TYPE)_value;
345 return true;
346 case MET_USHORT:
347 case MET_USHORT_ARRAY:
348 ((MET_USHORT_TYPE *)_data)[_index] = (MET_USHORT_TYPE)_value;
349 return true;
350 case MET_INT:
351 case MET_INT_ARRAY:
352 ((MET_INT_TYPE *)_data)[_index] = (MET_INT_TYPE)_value;
353 return true;
354 case MET_LONG:
355 case MET_LONG_ARRAY:
356 ((MET_LONG_TYPE *)_data)[_index] = (MET_LONG_TYPE)_value;
357 return true;
358 case MET_UINT:
359 case MET_UINT_ARRAY:
360 ((MET_UINT_TYPE *)_data)[_index] = (MET_UINT_TYPE)_value;
361 return true;
362 case MET_ULONG:
363 case MET_ULONG_ARRAY:
364 ((MET_ULONG_TYPE *)_data)[_index] = (MET_ULONG_TYPE)_value;
365 return true;
366 case MET_LONG_LONG:
367 case MET_LONG_LONG_ARRAY:
368 ((MET_LONG_LONG_TYPE *)_data)[_index] = (MET_LONG_LONG_TYPE)_value;
369 return true;
370 case MET_ULONG_LONG:
371 case MET_ULONG_LONG_ARRAY:
372 ((MET_ULONG_LONG_TYPE *)_data)[_index] = (MET_ULONG_LONG_TYPE)_value;
373 return true;
374 case MET_FLOAT:
375 case MET_FLOAT_ARRAY:
376 case MET_FLOAT_MATRIX:
377 ((MET_FLOAT_TYPE *)_data)[_index] = (MET_FLOAT_TYPE)_value;
378 return true;
379 case MET_DOUBLE:
380 case MET_DOUBLE_ARRAY:
381 ((MET_DOUBLE_TYPE *)_data)[_index] = (MET_DOUBLE_TYPE)_value;
382 return true;
383 case MET_STRING:
384 sprintf(&(((MET_CHAR_TYPE *)_data)[_index]), "%f", _value);
385 return true;
386 default:
387 return false;
388 }
389 }
390
MET_ValueToValue(MET_ValueEnumType _fromType,const void * _fromData,METAIO_STL::streamoff _index,MET_ValueEnumType _toType,void * _toData,double _fromMin,double _fromMax,double _toMin,double _toMax)391 bool MET_ValueToValue(MET_ValueEnumType _fromType, const void *_fromData,
392 METAIO_STL::streamoff _index,
393 MET_ValueEnumType _toType, void *_toData,
394 double _fromMin, double _fromMax,
395 double _toMin, double _toMax)
396 {
397 double tf;
398 MET_ValueToDouble(_fromType, _fromData, _index, &tf);
399 if(_toMin != _toMax && _fromMin != _fromMax)
400 {
401 tf = (tf-_fromMin)/(_fromMax-_fromMin) * (_toMax-_toMin) + _toMin;
402 if(tf<_toMin)
403 {
404 tf = _toMin;
405 }
406 else if(tf>_toMax)
407 {
408 tf = _toMax;
409 }
410 }
411 switch(_toType)
412 {
413 case MET_ASCII_CHAR:
414 case MET_CHAR:
415 case MET_CHAR_ARRAY:
416 (((MET_CHAR_TYPE *)_toData)[_index]) = (MET_CHAR_TYPE)tf;
417 return true;
418 case MET_UCHAR:
419 case MET_UCHAR_ARRAY:
420 (((MET_UCHAR_TYPE *)_toData)[_index]) = (MET_UCHAR_TYPE)tf;
421 return true;
422 case MET_SHORT:
423 case MET_SHORT_ARRAY:
424 (((MET_SHORT_TYPE *)_toData)[_index]) = (MET_SHORT_TYPE)tf;
425 return true;
426 case MET_USHORT:
427 case MET_USHORT_ARRAY:
428 (((MET_USHORT_TYPE *)_toData)[_index]) = (MET_USHORT_TYPE)tf;
429 return true;
430 case MET_INT:
431 case MET_INT_ARRAY:
432 (((MET_INT_TYPE *)_toData)[_index]) = (MET_INT_TYPE)tf;
433 return true;
434 case MET_LONG:
435 case MET_LONG_ARRAY:
436 (((MET_LONG_TYPE *)_toData)[_index]) = (MET_LONG_TYPE)tf;
437 return true;
438 case MET_UINT:
439 case MET_UINT_ARRAY:
440 (((MET_UINT_TYPE *)_toData)[_index]) = (MET_UINT_TYPE)tf;
441 return true;
442 case MET_ULONG:
443 case MET_ULONG_ARRAY:
444 (((MET_ULONG_TYPE *)_toData)[_index]) = (MET_ULONG_TYPE)tf;
445 return true;
446 case MET_LONG_LONG:
447 case MET_LONG_LONG_ARRAY:
448 (((MET_LONG_LONG_TYPE *)_toData)[_index]) = (MET_LONG_LONG_TYPE)tf;
449 return true;
450 case MET_ULONG_LONG:
451 case MET_ULONG_LONG_ARRAY:
452 (((MET_ULONG_LONG_TYPE *)_toData)[_index]) = (MET_ULONG_LONG_TYPE)tf;
453 return true;
454 case MET_DOUBLE:
455 case MET_DOUBLE_ARRAY:
456 (((MET_DOUBLE_TYPE *)_toData)[_index]) = (MET_DOUBLE_TYPE)tf;
457 return true;
458 case MET_FLOAT:
459 case MET_FLOAT_ARRAY:
460 case MET_FLOAT_MATRIX:
461 (((MET_FLOAT_TYPE *)_toData)[_index]) = (MET_FLOAT_TYPE)tf;
462 return true;
463 case MET_STRING:
464 sprintf(&(((MET_CHAR_TYPE *)_toData)[_index]), "%f", tf);
465 return true;
466 default:
467 return false;
468 }
469 }
470
471 // Uncompress a stream given an uncompressedSeekPosition
472 METAIO_EXPORT
MET_UncompressStream(METAIO_STREAM::ifstream * stream,METAIO_STL::streamoff uncompressedSeekPosition,unsigned char * uncompressedData,METAIO_STL::streamoff uncompressedDataSize,METAIO_STL::streamoff compressedDataSize,MET_CompressionTableType * compressionTable)473 METAIO_STL::streamoff MET_UncompressStream(METAIO_STREAM::ifstream * stream,
474 METAIO_STL::streamoff uncompressedSeekPosition,
475 unsigned char * uncompressedData,
476 METAIO_STL::streamoff uncompressedDataSize,
477 METAIO_STL::streamoff compressedDataSize,
478 MET_CompressionTableType * compressionTable
479 )
480 {
481 // Keep the currentpos of the string
482 METAIO_STL::streampos currentPos = stream->tellg();
483 if(currentPos == METAIO_STL::streampos(-1))
484 {
485 METAIO_STREAM::cout << "MET_UncompressStream: ERROR Stream is not valid!" << METAIO_STREAM::endl;
486 return -1;
487 }
488
489 METAIO_STL::streamoff read = 0;
490
491 //METAIO_STREAM::cout << "Wanted Seek = " << uncompressedSeekPosition << METAIO_STREAM::endl;
492 //METAIO_STREAM::cout << "Wanted size = " << uncompressedDataSize << METAIO_STREAM::endl;
493
494 // Size of the output buffer
495 METAIO_STL::streamoff buffersize = 1000;
496
497 // We try to guess the compression rate
498 // Note that sometime the size of the input buffer
499 // has to be bigger than the output buffer (bad compression)
500 // We assume that they are equal
501 double compressionRate = 1;
502
503 METAIO_STL::streamoff zseekpos = 0;
504 METAIO_STL::streamoff seekpos = 0;
505 bool firstchunk = true;
506
507 // Allocate the stream if necessary
508 z_stream* d_stream = compressionTable->compressedStream;
509 if(compressionTable->compressedStream == NULL)
510 {
511 d_stream = new z_stream;
512 d_stream->zalloc = (alloc_func)0;
513 d_stream->zfree = (free_func)0;
514 d_stream->opaque = (voidpf)0;
515 inflateInit2(d_stream,47); // allow both gzip and zlib compression headers
516 compressionTable->compressedStream = d_stream;
517 compressionTable->buffer = new char[1001];
518 compressionTable->bufferSize = 0;
519 }
520
521
522 // Try to find the current seek position in the compressed
523 // and uncompressed stream from the compressionTable
524 // The table is stored in order
525 if(compressionTable->offsetList.size()>0)
526 {
527 MET_CompressionOffsetListType::const_iterator it = compressionTable->offsetList.end();
528 it--;
529
530 if(uncompressedSeekPosition < (*it).uncompressedOffset)
531 {
532 if((*it).uncompressedOffset-uncompressedSeekPosition > compressionTable->bufferSize)
533 {
534 METAIO_STREAM::cout << "ERROR: Cannot go backward by more than the buffer size (1000)"
535 << METAIO_STREAM::endl;
536 return 0;
537 }
538
539 char* buffer = compressionTable->buffer;
540 METAIO_STL::streamoff start = uncompressedSeekPosition-((*it).uncompressedOffset-compressionTable->bufferSize);
541 buffer += start;
542
543 METAIO_STL::streamoff readSize = uncompressedDataSize;
544 METAIO_STL::streamoff sizeInBuffer = compressionTable->bufferSize-start;
545 if(readSize>sizeInBuffer)
546 {
547 memcpy(uncompressedData,buffer,(size_t)sizeInBuffer);
548 uncompressedData += sizeInBuffer;
549 zseekpos = (*it).compressedOffset;
550 seekpos = (*it).uncompressedOffset;
551 uncompressedSeekPosition += sizeInBuffer;
552 uncompressedDataSize -= sizeInBuffer;
553 }
554 else // read from buffer and return
555 {
556 memcpy(uncompressedData,buffer,(size_t)readSize);
557 return uncompressedDataSize;
558 }
559 }
560 else
561 {
562 zseekpos = (*it).compressedOffset;
563 seekpos = (*it).uncompressedOffset;
564 }
565 }
566
567 //METAIO_STREAM::cout << "Using = " << seekpos << " : " << zseekpos << METAIO_STREAM::endl;
568
569 while(seekpos < uncompressedSeekPosition+uncompressedDataSize)
570 {
571 // If we are reading the current buffer we read everything
572 if(seekpos >= uncompressedSeekPosition)
573 {
574 buffersize = uncompressedSeekPosition+uncompressedDataSize-seekpos;
575 firstchunk = false;
576 }
577
578 unsigned char* outdata = new unsigned char[buffersize];
579
580 d_stream->avail_out = (uInt)( buffersize );
581
582 // How many byte from compressed streamed should we read
583 METAIO_STL::streamoff inputBufferSize = (METAIO_STL::streamoff)(buffersize/compressionRate);
584
585 if(inputBufferSize == 0)
586 {
587 inputBufferSize = 1;
588 }
589 if((currentPos+zseekpos+inputBufferSize) > compressedDataSize)
590 {
591 inputBufferSize = compressedDataSize-zseekpos;
592 }
593
594 unsigned char* inputBuffer = new unsigned char[inputBufferSize];
595 stream->seekg(currentPos+zseekpos,METAIO_STREAM::ios::beg);
596 stream->read((char *)inputBuffer, (size_t)inputBufferSize);
597
598 d_stream->next_in = inputBuffer;
599 d_stream->avail_in = stream->gcount();
600 d_stream->next_out = outdata;
601
602 int inflate_error = inflate(d_stream, Z_NO_FLUSH);
603 if(inflate_error < 0)
604 {
605 return -1;
606 }
607
608 METAIO_STL::streampos previousSeekpos = seekpos;
609
610 seekpos += buffersize-d_stream->avail_out;
611 zseekpos += stream->gcount()-d_stream->avail_in;
612
613 // Store the last buffer into memory in case we need it
614 // in the near future.
615 METAIO_STL::streamoff previousBufferSize = seekpos-previousSeekpos;
616 if(previousBufferSize>1000)
617 {
618 // WARNING: We probably need to offset outdata at some point...
619 previousBufferSize = 1000;
620 }
621
622 memcpy(compressionTable->buffer,outdata,(size_t)previousBufferSize);
623 compressionTable->bufferSize = previousBufferSize;
624
625 //METAIO_STREAM::cout << "Current pos = " << seekpos << " : " << zseekpos << METAIO_STREAM::endl;
626
627 // If go further than the uncompressedSeekPosition we start writing the stream
628 if(seekpos >= uncompressedSeekPosition)
629 {
630 if(firstchunk)
631 {
632 outdata += uncompressedSeekPosition-previousSeekpos;
633 METAIO_STL::streamoff writeSize = seekpos-uncompressedSeekPosition;
634
635 if(writeSize > uncompressedDataSize)
636 {
637 writeSize = uncompressedDataSize;
638 }
639
640 memcpy(uncompressedData,outdata,(size_t)writeSize);
641
642 // Restore the position of the buffer
643 outdata -= uncompressedSeekPosition-previousSeekpos;
644
645 uncompressedData += writeSize;
646 read += writeSize;
647
648 firstchunk = false;
649 }
650 else // read everything
651 {
652 METAIO_STL::streamoff writeSize = seekpos-previousSeekpos;
653 memcpy(uncompressedData,outdata,(size_t)writeSize);
654 if(writeSize > uncompressedDataSize)
655 {
656 writeSize = uncompressedDataSize;
657 }
658 uncompressedData += writeSize;
659 read += writeSize;
660 }
661 }
662 delete [] outdata;
663 delete [] inputBuffer;
664 }
665
666 // Save the state of the compression for later use
667 MET_CompressionOffsetType offset;
668 offset.compressedOffset = zseekpos; // compressed
669 offset.uncompressedOffset = seekpos; // uncompressed
670 compressionTable->offsetList.push_back(offset);
671
672 // Seek to the current position
673 stream->seekg(currentPos,METAIO_STREAM::ios::beg);
674 return read;
675 }
676
677
678 //
679 //
680 //
MET_PerformCompression(const unsigned char * source,METAIO_STL::streamoff sourceSize,METAIO_STL::streamoff * compressedDataSize)681 unsigned char * MET_PerformCompression(const unsigned char * source,
682 METAIO_STL::streamoff sourceSize,
683 METAIO_STL::streamoff * compressedDataSize)
684 {
685 unsigned char * compressedData;
686
687 z_stream z;
688 z.zalloc = (alloc_func)0;
689 z.zfree = (free_func)0;
690 z.opaque = (voidpf)0;
691
692 // Compression rate
693 // Choices are Z_BEST_SPEED,Z_BEST_COMPRESSION,Z_DEFAULT_COMPRESSION
694 int compression_rate = Z_DEFAULT_COMPRESSION;
695
696 METAIO_STL::streamoff buffer_size = sourceSize;
697 unsigned char * input_buffer = const_cast<unsigned char *>(source);
698 unsigned char * output_buffer = new unsigned char[buffer_size];
699
700 compressedData = new unsigned char[buffer_size];
701
702 deflateInit(&z, compression_rate);
703
704 z.avail_in = (uInt)buffer_size;
705 z.next_in = input_buffer;
706 z.next_out = output_buffer;
707 z.avail_out = (uInt)buffer_size;
708
709 METAIO_STL::streamoff count;
710 METAIO_STL::streamoff j=0;
711 // Perform the compression
712 for ( ; ; )
713 {
714 if ( z.avail_in == 0 )
715 {
716 deflate( &z, Z_FINISH );
717 count = buffer_size - z.avail_out;
718 if ( count )
719 {
720 // if we don't have enough allocation for the output buffer
721 // when the output is bigger than the input (true for small images)
722 if(j+count>=buffer_size)
723 {
724 unsigned char* compressedDataTemp = new unsigned char[j+count+1];
725 memcpy(compressedDataTemp,compressedData,(size_t)buffer_size);
726 delete [] compressedData;
727 compressedData = compressedDataTemp;
728 }
729
730 memcpy((char*)compressedData+j, (char *)output_buffer, (size_t)count);
731 }
732 break;
733 }
734
735 deflate( &z, Z_NO_FLUSH );
736 count = buffer_size - z.avail_out;
737 if ( count )
738 {
739 if(j+count>=buffer_size)
740 {
741 unsigned char* compressedDataTemp = new unsigned char[j+count+1];
742 memcpy(compressedDataTemp,compressedData,(size_t)buffer_size);
743 delete [] compressedData;
744 compressedData = compressedDataTemp;
745 }
746 memcpy((char*)compressedData+j, (char*)output_buffer, (size_t)count);
747 }
748
749 j += count;
750 z.next_out = output_buffer;
751 z.avail_out = (uInt)buffer_size;
752 }
753
754 delete [] output_buffer;
755
756 *compressedDataSize = z.total_out;
757
758 // Print the result
759 deflateEnd(&z);
760
761 return compressedData;
762 }
763
764 //
765 //
766 //
MET_PerformUncompression(const unsigned char * sourceCompressed,METAIO_STL::streamoff sourceCompressedSize,unsigned char * uncompressedData,METAIO_STL::streamoff uncompressedDataSize)767 bool MET_PerformUncompression(const unsigned char * sourceCompressed,
768 METAIO_STL::streamoff sourceCompressedSize,
769 unsigned char * uncompressedData,
770 METAIO_STL::streamoff uncompressedDataSize)
771 {
772 z_stream d_stream;
773
774 d_stream.zalloc = (alloc_func)0;
775 d_stream.zfree = (free_func)0;
776 d_stream.opaque = (voidpf)0;
777
778 inflateInit2(&d_stream,47); // allow both gzip and zlib compression headers
779 d_stream.next_in = const_cast<unsigned char *>(sourceCompressed);
780 d_stream.avail_in = (uInt)sourceCompressedSize;
781
782 for (;;)
783 {
784 d_stream.next_out = (unsigned char *)uncompressedData;
785 d_stream.avail_out = (uInt)uncompressedDataSize;
786 int err = inflate(&d_stream, Z_NO_FLUSH);
787
788 if((err == Z_STREAM_END)
789 || (err == Z_BUF_ERROR) // Sometimes inflate returns this non fatal.
790 )
791 {
792 break;
793 }
794 else if(err < 0)
795 {
796 METAIO_STREAM::cerr << "Uncompress failed" << METAIO_STREAM::endl;
797 break;
798 }
799 }
800
801 inflateEnd(&d_stream);
802
803 return true;
804 }
805
806 //
807 //
808 //
MET_StringToWordArray(const char * s,int * n,char *** val)809 bool MET_StringToWordArray(const char *s, int *n, char ***val)
810 {
811 ptrdiff_t l = strlen(s);
812
813 ptrdiff_t p = 0;
814 while(p<l && s[p] == ' ')
815 {
816 p++;
817 }
818
819 *n = 0;
820 ptrdiff_t pp = p;
821 bool space = false;
822 while(pp<l)
823 {
824 if(s[pp] == ' ' && !space)
825 {
826 (*n)++;
827 space = true;
828 }
829 else
830 {
831 space = false;
832 }
833 pp++;
834 }
835 pp=l-1;
836 if(s[pp] == ' ')
837 {
838 while(pp>=0 && s[pp] == ' ')
839 {
840 (*n)--;
841 pp--;
842 }
843 }
844 else
845 {
846 (*n)++;
847 }
848
849 *val = new char *[*n];
850
851 ptrdiff_t i, j;
852 for(i=0; i<*n; i++)
853 {
854 if(p == l)
855 {
856 return false;
857 }
858
859 (*val)[i] = new char [80];
860 while(p<l && s[p] == ' ')
861 {
862 p++;
863 }
864 j = 0;
865 while(p<l && s[p] != ' ')
866 {
867 (*val)[i][j++] = s[p++];
868 }
869 (*val)[i][j] = '\0';
870 }
871
872 return true;
873 }
874
875 //
876 //
877 //
MET_GetFilePath(const char * _fName,char * _fPath)878 bool MET_GetFilePath(const char *_fName, char *_fPath)
879 {
880 long i;
881
882 size_t l = strlen(_fName);
883
884 for(i=(long)l-1; i>=0; i--)
885 {
886 if(_fName[i] == '\\' || _fName[i] == '/')
887 break;
888 }
889
890 if(i >= 0 && (_fName[i] == '/' || _fName[i] == '\\'))
891 {
892 strcpy(_fPath, _fName);
893 _fPath[i+1] = '\0';
894 return true;
895 }
896 else
897 {
898 _fPath[0] = '\0';
899 return false;
900 }
901 }
902
903 //
904 //
905 //
MET_GetFileSuffixPtr(const char * _fName,int * i)906 bool MET_GetFileSuffixPtr(const char *_fName, int *i)
907 {
908 *i = static_cast<int>( strlen(_fName) );
909 int j = *i - 5;
910 if(j<0)
911 {
912 j = 0;
913 }
914 while(*i>j)
915 {
916 if(_fName[(*i)-1] == '.')
917 {
918 return true;
919 }
920 else
921 {
922 (*i)--;
923 }
924 }
925 *i = 0;
926 return false;
927 }
928
929 //
930 //
931 //
MET_SetFileSuffix(char * _fName,const char * _suf)932 bool MET_SetFileSuffix(char *_fName, const char *_suf)
933 {
934 int i;
935 MET_GetFileSuffixPtr(_fName, &i);
936 if(i>0)
937 {
938 if(_suf[0] == '.')
939 _fName[i-1] = '\0';
940 else
941 _fName[i] = '\0';
942 strcat(_fName, _suf);
943 return true;
944 }
945 else
946 {
947 strcat(_fName, _suf);
948 return true;
949 }
950 }
951
952 //
953 //
954 //
MET_InitWriteField(MET_FieldRecordType * _mf,const char * _name,MET_ValueEnumType _type,double _v)955 bool MET_InitWriteField(MET_FieldRecordType * _mf,
956 const char *_name,
957 MET_ValueEnumType _type,
958 double _v)
959 {
960 strcpy(_mf->name, _name);
961 _mf->type = _type;
962 _mf->defined = true;
963 _mf->length = 1;
964 _mf->dependsOn = -1;
965 _mf->required = false;
966 _mf->terminateRead = false;
967 _mf->value[0] = _v;
968 return true;
969 }
970
MET_InitReadField(MET_FieldRecordType * _mf,const char * _name,MET_ValueEnumType _type,bool _required,int _dependsOn,size_t _length)971 bool MET_InitReadField(MET_FieldRecordType * _mf,
972 const char *_name,
973 MET_ValueEnumType _type,
974 bool _required,
975 int _dependsOn,
976 size_t _length)
977 {
978 strcpy(_mf->name, _name);
979 _mf->type = _type;
980 _mf->defined = false;
981 _mf->dependsOn = _dependsOn;
982 _mf->required = _required;
983 _mf->terminateRead = false;
984 _mf->length = static_cast<int>(_length);
985 _mf->value[0] = 0;
986 return true;
987 }
988
989 //
990 //
991 //
MET_SkipToVal(METAIO_STREAM::istream & fp)992 static bool MET_SkipToVal(METAIO_STREAM::istream &fp)
993 {
994 int c;
995 if( fp.eof() )
996 {
997 return false;
998 }
999
1000 c = fp.get();
1001
1002 while( !fp.eof() && c != MET_SeperatorChar && c != ':' )
1003 {
1004 c = fp.get();
1005 }
1006
1007 while( !fp.eof() && ( c == MET_SeperatorChar || c == ':' || IsBlank(c) ) )
1008 {
1009 c = fp.get();
1010 }
1011
1012 if( fp.eof() )
1013 {
1014 METAIO_STREAM::cerr << "Incomplete file record definition"
1015 << METAIO_STREAM::endl;
1016 return false;
1017 }
1018
1019 fp.putback(c);
1020
1021 return true;
1022 }
1023
1024 //
1025 //
1026 //
MET_IsComplete(METAIO_STL::vector<MET_FieldRecordType * > * fields)1027 static bool MET_IsComplete(METAIO_STL::vector<MET_FieldRecordType *> * fields)
1028 {
1029 METAIO_STL::vector<MET_FieldRecordType *>::iterator fieldIter;
1030 for(fieldIter=fields->begin(); fieldIter!=fields->end(); fieldIter++)
1031 {
1032 if((*fieldIter)->required && !(*fieldIter)->defined)
1033 {
1034 METAIO_STREAM::cerr << (*fieldIter)->name << " required and not defined."
1035 << METAIO_STREAM::endl;
1036 return false;
1037 }
1038 }
1039 return true;
1040 }
1041
1042 //
MET_Read(METAIO_STREAM::istream & fp,METAIO_STL::vector<MET_FieldRecordType * > * fields,char _MET_SeperatorChar,bool oneLine,bool display_warnings,METAIO_STL::vector<MET_FieldRecordType * > * newFields)1043 bool MET_Read(METAIO_STREAM::istream &fp,
1044 METAIO_STL::vector<MET_FieldRecordType *> * fields,
1045 char _MET_SeperatorChar, bool oneLine, bool display_warnings,
1046 METAIO_STL::vector<MET_FieldRecordType *> * newFields)
1047 {
1048
1049 char s[1024];
1050 int i;
1051 size_t j;
1052
1053 METAIO_STL::vector<MET_FieldRecordType *>::iterator fieldIter;
1054
1055 MET_SeperatorChar = _MET_SeperatorChar;
1056
1057 bool found;
1058
1059 unsigned char c;
1060 while(!fp.eof())
1061 {
1062 i = 0;
1063 c = fp.get();
1064 while(!fp.eof() && c != MET_SeperatorChar && c != ':'
1065 && isspace(c))
1066 {
1067 c = fp.get();
1068 }
1069 // save name up to separator or end of line
1070 while(!fp.eof() && c != MET_SeperatorChar && c != ':' && c != '\r' && c != '\n' && i<500)
1071 {
1072 s[i++] = c;
1073 c = fp.get();
1074 }
1075 if(fp.eof() || i >= 500)
1076 {
1077 break;
1078 }
1079 fp.putback(c);
1080 s[i] = '\0';
1081
1082 // trim white space on name
1083 i--;
1084 while(IsBlank(s[i]) && i>0)
1085 {
1086 s[i--] = '\0';
1087 }
1088
1089 found = false;
1090 for(fieldIter=fields->begin(); fieldIter!=fields->end(); fieldIter++)
1091 {
1092 if(!strcmp((*fieldIter)->name, s))
1093 {
1094 if((*fieldIter)->dependsOn >= 0)
1095 if(!(*fields)[(*fieldIter)->dependsOn]->defined)
1096 {
1097 METAIO_STREAM::cerr << (*fieldIter)->name
1098 << " defined prior to defining ";
1099 METAIO_STREAM::cerr << (*fields)[(*fieldIter)->dependsOn]->name
1100 << METAIO_STREAM::endl;
1101 return false;
1102 }
1103 switch((*fieldIter)->type)
1104 {
1105 case MET_NONE:
1106 fp.getline( s, 500 );
1107 break;
1108 case MET_ASCII_CHAR:
1109 {
1110 MET_SkipToVal(fp);
1111 if(fp.eof())
1112 {
1113 break;
1114 }
1115 c = fp.get();
1116 (*fieldIter)->value[0] = (double)c;
1117 fp.getline( s, 500 );
1118 break;
1119 }
1120 default:
1121 case MET_CHAR:
1122 case MET_UCHAR:
1123 case MET_SHORT:
1124 case MET_USHORT:
1125 case MET_INT:
1126 case MET_UINT:
1127 case MET_LONG:
1128 case MET_ULONG:
1129 case MET_LONG_LONG:
1130 case MET_ULONG_LONG:
1131 case MET_FLOAT:
1132 case MET_DOUBLE:
1133 {
1134 MET_SkipToVal(fp);
1135 if(fp.eof())
1136 {
1137 break;
1138 }
1139 fp >> (*fieldIter)->value[0];
1140 fp.getline( s, 500 );
1141 break;
1142 }
1143 case MET_STRING:
1144 {
1145 MET_SkipToVal(fp);
1146 if(fp.eof())
1147 {
1148 break;
1149 }
1150 MET_CHAR_TYPE * str = (MET_CHAR_TYPE *)((*fieldIter)->value);
1151 fp.getline( str, 500 );
1152 MET_StringStripEnd(str);
1153 (*fieldIter)->length = static_cast<int>( strlen( str ) );
1154 break;
1155 }
1156 case MET_CHAR_ARRAY:
1157 case MET_UCHAR_ARRAY:
1158 case MET_SHORT_ARRAY:
1159 case MET_USHORT_ARRAY:
1160 case MET_INT_ARRAY:
1161 case MET_UINT_ARRAY:
1162 case MET_LONG_ARRAY:
1163 case MET_ULONG_ARRAY:
1164 case MET_LONG_LONG_ARRAY:
1165 case MET_ULONG_LONG_ARRAY:
1166 case MET_FLOAT_ARRAY:
1167 case MET_DOUBLE_ARRAY:
1168 {
1169 MET_SkipToVal(fp);
1170 if(fp.eof())
1171 {
1172 break;
1173 }
1174 if((*fieldIter)->dependsOn >= 0)
1175 {
1176 (*fieldIter)->length =
1177 (int)((*fields)[(*fieldIter)->dependsOn]->value[0]);
1178 for(j=0; j<(size_t)(*fieldIter)->length; j++)
1179 {
1180 fp >> (*fieldIter)->value[j];
1181 }
1182 }
1183 else
1184 {
1185 if((*fieldIter)->length <= 0)
1186 {
1187 METAIO_STREAM::cerr <<
1188 "Arrays must have dependency or pre-specified lengths"
1189 << METAIO_STREAM::endl;
1190 return false;
1191 }
1192 for(j=0; j<(size_t)(*fieldIter)->length; j++)
1193 {
1194 fp >> (*fieldIter)->value[j];
1195 }
1196 }
1197 fp.getline( s, 500 );
1198 break;
1199 }
1200 case MET_FLOAT_MATRIX:
1201 {
1202 MET_SkipToVal(fp);
1203 if(fp.eof())
1204 {
1205 break;
1206 }
1207 if((*fieldIter)->dependsOn >= 0)
1208 {
1209 (*fieldIter)->length =
1210 (int)((*fields)[(*fieldIter)->dependsOn]->value[0]);
1211 for(j=0; j<(size_t)(*fieldIter)->length*(*fieldIter)->length;
1212 j++)
1213 {
1214 fp >> (*fieldIter)->value[j];
1215 }
1216 }
1217 else
1218 {
1219 if((*fieldIter)->length <= 0)
1220 {
1221 METAIO_STREAM::cerr <<
1222 "Arrays must have dependency or pre-specified lengths"
1223 << METAIO_STREAM::endl;
1224 return false;
1225 }
1226 for(j=0; j<(size_t)(*fieldIter)->length*(*fieldIter)->length; j++)
1227 {
1228 fp >> (*fieldIter)->value[j];
1229 }
1230 }
1231 fp.getline( s, 500 );
1232 break;
1233 }
1234 case MET_OTHER:
1235 {
1236 fp.getline( s, 500 );
1237 break;
1238 }
1239 }
1240 found = true;
1241 (*fieldIter)->defined = true;
1242 if((*fieldIter)->terminateRead)
1243 {
1244 return MET_IsComplete(fields);
1245 }
1246 break;
1247 }
1248 }
1249 if(!found)
1250 {
1251 if( newFields != NULL )
1252 {
1253 MET_SkipToVal(fp);
1254 if(fp.eof())
1255 {
1256 break;
1257 }
1258 MET_FieldRecordType * mF = new MET_FieldRecordType;
1259 MET_InitReadField(mF, s, MET_STRING, false);
1260 MET_CHAR_TYPE * str = (MET_CHAR_TYPE *)(mF->value);
1261 fp.getline( str, 500 );
1262 MET_StringStripEnd(str);
1263 mF->length = static_cast<int>( strlen( str ) );
1264 newFields->push_back(mF);
1265 }
1266 else
1267 {
1268 if(display_warnings)
1269 {
1270 METAIO_STREAM::cerr << "Skipping unrecognized field "
1271 << s << METAIO_STREAM::endl;
1272 }
1273 fp.getline( s, 500 );
1274 }
1275 }
1276 if(oneLine)
1277 {
1278 return MET_IsComplete(fields);
1279 }
1280 }
1281
1282 return MET_IsComplete(fields);
1283 }
1284
1285 //
MET_Write(METAIO_STREAM::ostream & fp,METAIO_STL::vector<MET_FieldRecordType * > * fields,char _MET_SeperatorChar)1286 bool MET_Write(METAIO_STREAM::ostream &fp,
1287 METAIO_STL::vector<MET_FieldRecordType *> * fields,
1288 char _MET_SeperatorChar)
1289 {
1290 MET_SeperatorChar = _MET_SeperatorChar;
1291
1292 int j;
1293 METAIO_STL::vector<MET_FieldRecordType *>::iterator fieldIter;
1294 for(fieldIter=fields->begin(); fieldIter!=fields->end(); fieldIter++)
1295 {
1296 switch((*fieldIter)->type)
1297 {
1298 case MET_NONE:
1299 {
1300 fp << (*fieldIter)->name << " " << MET_SeperatorChar << " "
1301 << METAIO_STREAM::endl;
1302 break;
1303 }
1304 case MET_ASCII_CHAR:
1305 {
1306 fp << (*fieldIter)->name << " " << MET_SeperatorChar << " ";
1307 fp << (MET_CHAR_TYPE)(*fieldIter)->value[0] << METAIO_STREAM::endl;
1308 break;
1309 }
1310 case MET_CHAR:
1311 case MET_SHORT:
1312 case MET_LONG:
1313 case MET_INT:
1314 {
1315 fp << (*fieldIter)->name << " " << MET_SeperatorChar << " ";
1316 fp << (MET_LONG_TYPE)((*fieldIter)->value[0]) << METAIO_STREAM::endl;
1317 break;
1318 }
1319 case MET_LONG_LONG:
1320 {
1321 #if defined(_MSC_VER) || defined(__HP_aCC)
1322 // NOTE: you cannot use __int64 in an ostream in MSV6 or HPUX
1323 fp << (double)((MET_LONG_LONG_TYPE)((*fieldIter)->value[0]))
1324 << METAIO_STREAM::endl;
1325 METAIO_STREAM::cerr << "Programs compiled using MSV6 or HPUX cannot"
1326 << " write 64 bit ints" << METAIO_STREAM::endl;
1327 METAIO_STREAM::cerr << " Writing as double instead."
1328 << " Loss of precision results."
1329 << METAIO_STREAM::endl;
1330 #else
1331 fp << (MET_LONG_LONG_TYPE)((*fieldIter)->value[0])
1332 << METAIO_STREAM::endl;
1333 #endif
1334 break;
1335 }
1336 case MET_UCHAR:
1337 case MET_USHORT:
1338 case MET_UINT:
1339 case MET_ULONG:
1340 {
1341 fp << (*fieldIter)->name << " " << MET_SeperatorChar << " ";
1342 fp << (MET_ULONG_TYPE)((*fieldIter)->value[0]) << METAIO_STREAM::endl;
1343 break;
1344 }
1345 case MET_ULONG_LONG:
1346 {
1347 #if defined(_MSC_VER) || defined(__HP_aCC)
1348 // NOTE: you cannot use __int64 in an ostream in MSV6 or HPUX
1349 fp << (double)((MET_LONG_LONG_TYPE)((MET_ULONG_LONG_TYPE)
1350 ((*fieldIter)->value[0])))
1351 << METAIO_STREAM::endl;
1352 METAIO_STREAM::cerr << "Programs compiled using MSV6 or HPUX"
1353 << " cannot write 64 bit ints"
1354 << METAIO_STREAM::endl;
1355 METAIO_STREAM::cerr << " Writing as double instead."
1356 << " Loss of precision results."
1357 << METAIO_STREAM::endl;
1358 #else
1359 fp << (MET_ULONG_LONG_TYPE)((*fieldIter)->value[0])
1360 << METAIO_STREAM::endl;
1361 #endif
1362 break;
1363 }
1364 case MET_FLOAT:
1365 case MET_DOUBLE:
1366 {
1367 fp << (*fieldIter)->name << " " << MET_SeperatorChar << " ";
1368 fp << (MET_DOUBLE_TYPE)(*fieldIter)->value[0] << METAIO_STREAM::endl;
1369 break;
1370 }
1371 case MET_STRING:
1372 {
1373 if ( (*fieldIter)->length == 0 )
1374 {
1375 METAIO_STREAM::cerr << "Warning:";
1376 METAIO_STREAM::cerr << "The field " << (*fieldIter)->name
1377 << "has zero length. "
1378 << "Refusing to write empty string value.";
1379 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1380 }
1381 fp << (*fieldIter)->name << " " << MET_SeperatorChar << " ";
1382 if((*fieldIter)->dependsOn >= 0)
1383 {
1384 if((*fieldIter)->length !=
1385 (*fields)[(*fieldIter)->dependsOn]->value[0])
1386 {
1387 METAIO_STREAM::cerr << "Warning:";
1388 METAIO_STREAM::cerr << "length and dependsOn values not equal"
1389 << " in write";
1390 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1391 }
1392 }
1393 fp.write( (char *)((*fieldIter)->value), (*fieldIter)->length );
1394 fp << METAIO_STREAM::endl;
1395 break;
1396 }
1397 case MET_CHAR_ARRAY:
1398 case MET_SHORT_ARRAY:
1399 case MET_INT_ARRAY:
1400 case MET_LONG_ARRAY:
1401 {
1402 fp << (*fieldIter)->name << " " << MET_SeperatorChar;
1403 if((*fieldIter)->dependsOn >= 0)
1404 {
1405 if((*fieldIter)->length !=
1406 (*fields)[(*fieldIter)->dependsOn]->value[0])
1407 {
1408 METAIO_STREAM::cerr << "Warning: ";
1409 METAIO_STREAM::cerr << "Length and dependsOn values not equal"
1410 << " in write";
1411 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1412 }
1413 }
1414 for(j=0; j<(*fieldIter)->length; j++)
1415 {
1416 fp << " " << (MET_LONG_TYPE)((*fieldIter)->value[j]);
1417 }
1418 fp << METAIO_STREAM::endl;
1419 break;
1420 }
1421 case MET_LONG_LONG_ARRAY:
1422 {
1423 fp << (*fieldIter)->name << " " << MET_SeperatorChar;
1424 if((*fieldIter)->dependsOn >= 0)
1425 {
1426 if((*fieldIter)->length !=
1427 (*fields)[(*fieldIter)->dependsOn]->value[0])
1428 {
1429 METAIO_STREAM::cerr << "Warning: ";
1430 METAIO_STREAM::cerr << "Length and dependsOn values not equal"
1431 << " in write";
1432 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1433 }
1434 }
1435 for(j=0; j<(*fieldIter)->length; j++)
1436 {
1437 #if defined(_MSC_VER) || defined(__HP_aCC)
1438 // NOTE: you cannot use __int64 in an ostream in MSV6 or HPUX
1439 fp << " " << (double)((MET_LONG_LONG_TYPE)((*fieldIter)->value[j]));
1440 METAIO_STREAM::cerr << "Programs compiled using MSV6 cannot"
1441 << " write 64 bit ints"
1442 << METAIO_STREAM::endl;
1443 METAIO_STREAM::cerr << " Writing as double instead."
1444 << " Loss of precision results."
1445 << METAIO_STREAM::endl;
1446 #else
1447 fp << " " << (MET_LONG_LONG_TYPE)((*fieldIter)->value[j]);
1448 #endif
1449 }
1450 fp << METAIO_STREAM::endl;
1451 break;
1452 }
1453
1454 case MET_UCHAR_ARRAY:
1455 case MET_USHORT_ARRAY:
1456 case MET_UINT_ARRAY:
1457 case MET_ULONG_ARRAY:
1458 {
1459 fp << (*fieldIter)->name << " " << MET_SeperatorChar;
1460 if((*fieldIter)->dependsOn >= 0)
1461 {
1462 if((*fieldIter)->length !=
1463 (*fields)[(*fieldIter)->dependsOn]->value[0])
1464 {
1465 METAIO_STREAM::cerr << "Warning: ";
1466 METAIO_STREAM::cerr << "Length and dependsOn values not equal"
1467 << " in write";
1468 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1469 }
1470 }
1471 for(j=0; j<(*fieldIter)->length; j++)
1472 {
1473 fp << " " << (MET_ULONG_TYPE)((*fieldIter)->value[j]);
1474 }
1475 fp << METAIO_STREAM::endl;
1476 break;
1477 }
1478 case MET_ULONG_LONG_ARRAY:
1479 {
1480 fp << (*fieldIter)->name << " " << MET_SeperatorChar;
1481 if((*fieldIter)->dependsOn >= 0)
1482 {
1483 if((*fieldIter)->length !=
1484 (*fields)[(*fieldIter)->dependsOn]->value[0])
1485 {
1486 METAIO_STREAM::cerr << "Warning: ";
1487 METAIO_STREAM::cerr << "Length and dependsOn values not equal"
1488 << " in write";
1489 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1490 }
1491 }
1492 for(j=0; j<(*fieldIter)->length; j++)
1493 {
1494 #if defined(_MSC_VER) || defined(__HP_aCC)
1495 // NOTE: you cannot use __int64 in an ostream in MSV6
1496 fp << " " << (double)((MET_LONG_LONG_TYPE)((MET_ULONG_LONG_TYPE)
1497 ((*fieldIter)->value[j])));
1498 METAIO_STREAM::cerr << "Programs compiled using MSV6 or HPUX"
1499 << " cannot write 64 bit ints"
1500 << METAIO_STREAM::endl;
1501 METAIO_STREAM::cerr << " Writing as double instead."
1502 << " Loss of precision results."
1503 << METAIO_STREAM::endl;
1504 #else
1505 fp << " " << (MET_ULONG_LONG_TYPE)((*fieldIter)->value[j]);
1506 #endif
1507 }
1508 fp << METAIO_STREAM::endl;
1509 break;
1510 }
1511
1512 case MET_FLOAT_ARRAY:
1513 case MET_DOUBLE_ARRAY:
1514 {
1515 fp << (*fieldIter)->name << " " << MET_SeperatorChar;
1516 if((*fieldIter)->dependsOn >= 0)
1517 {
1518 if((*fieldIter)->length !=
1519 (*fields)[(*fieldIter)->dependsOn]->value[0])
1520 {
1521 METAIO_STREAM::cerr << "Warning: ";
1522 METAIO_STREAM::cerr << "length and dependsOn values not equal in write";
1523 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1524 }
1525 }
1526 for(j=0; j<(*fieldIter)->length; j++)
1527 {
1528 fp << " " << (double)(*fieldIter)->value[j];
1529 }
1530 fp << METAIO_STREAM::endl;
1531 break;
1532 }
1533 case MET_FLOAT_MATRIX:
1534 {
1535 fp << (*fieldIter)->name << " " << MET_SeperatorChar;
1536 if((*fieldIter)->dependsOn >= 0)
1537 {
1538 if((*fieldIter)->length !=
1539 (*fields)[(*fieldIter)->dependsOn]->value[0])
1540 {
1541 METAIO_STREAM::cerr << "Warning: ";
1542 METAIO_STREAM::cerr << "length and dependsOn values not equal in write";
1543 METAIO_STREAM::cerr << METAIO_STREAM::endl;
1544 }
1545 }
1546 for(j=0; j<(*fieldIter)->length*(*fieldIter)->length; j++)
1547 {
1548 fp << " " << (double)(*fieldIter)->value[j];
1549 }
1550 fp << METAIO_STREAM::endl;
1551 break;
1552 }
1553 case MET_OTHER:
1554 {
1555 break;
1556 }
1557 }
1558 }
1559 return true;
1560 }
1561
MET_WriteFieldToFile(METAIO_STREAM::ostream & _fp,const char * _fieldName,MET_ValueEnumType _pType,size_t _n,const void * _v)1562 bool MET_WriteFieldToFile(METAIO_STREAM::ostream & _fp, const char *_fieldName,
1563 MET_ValueEnumType _pType, size_t _n, const void *_v)
1564 {
1565 size_t i;
1566 MET_FieldRecordType f;
1567
1568 sprintf(f.name, "%s", _fieldName);
1569 f.defined = false;
1570 f.dependsOn = -1;
1571 f.length = static_cast<int>(_n);
1572 f.required = false;
1573 f.type = _pType;
1574 switch(_pType)
1575 {
1576 case MET_ASCII_CHAR:
1577 case MET_CHAR:
1578 case MET_CHAR_ARRAY:
1579 for(i = 0; i < _n; i++)
1580 {
1581 f.value[i] = (double)(((const MET_CHAR_TYPE *)_v)[i]);
1582 }
1583 break;
1584 case MET_UCHAR:
1585 case MET_UCHAR_ARRAY:
1586 for(i = 0; i < _n; i++)
1587 {
1588 f.value[i] = (double)(((const MET_UCHAR_TYPE *)_v)[i]);
1589 }
1590 break;
1591 case MET_SHORT:
1592 case MET_SHORT_ARRAY:
1593 for(i=0; i<_n; i++)
1594 {
1595 f.value[i] = (double)(((const MET_SHORT_TYPE *)_v)[i]);
1596 }
1597 break;
1598 case MET_USHORT:
1599 case MET_USHORT_ARRAY:
1600 for(i=0; i<_n; i++)
1601 {
1602 f.value[i] = (double)(((const MET_USHORT_TYPE *)_v)[i]);
1603 }
1604 break;
1605 case MET_INT:
1606 case MET_INT_ARRAY:
1607 for(i=0; i<_n; i++)
1608 {
1609 f.value[i] = (double)(((const MET_INT_TYPE *)_v)[i]);
1610 }
1611 break;
1612 case MET_UINT:
1613 case MET_UINT_ARRAY:
1614 for(i=0; i<_n; i++)
1615 {
1616 f.value[i] = (double)(((const MET_UINT_TYPE *)_v)[i]);
1617 }
1618 break;
1619 case MET_LONG:
1620 case MET_LONG_ARRAY:
1621 for(i=0; i<_n; i++)
1622 {
1623 f.value[i] = (double)(((const MET_LONG_TYPE *)_v)[i]);
1624 }
1625 break;
1626 case MET_ULONG:
1627 case MET_ULONG_ARRAY:
1628 for(i=0; i<_n; i++)
1629 {
1630 f.value[i] = (double)(((const MET_ULONG_TYPE *)_v)[i]);
1631 }
1632 break;
1633 case MET_LONG_LONG:
1634 case MET_LONG_LONG_ARRAY:
1635 for(i=0; i<_n; i++)
1636 {
1637 f.value[i] = (double)(((const MET_LONG_LONG_TYPE *)_v)[i]);
1638 }
1639 break;
1640 case MET_ULONG_LONG:
1641 case MET_ULONG_LONG_ARRAY:
1642 for(i=0; i<_n; i++)
1643 {
1644 #if defined(_MSC_VER) || defined(__HP_aCC)
1645 // NOTE: you cannot use __int64 in an ostream in MSV6 or HPUX
1646 f.value[i] = (double)((MET_LONG_LONG_TYPE)
1647 (((const MET_ULONG_LONG_TYPE *)_v)[i]));
1648 #else
1649 f.value[i] = (double)(((const MET_ULONG_LONG_TYPE *)_v)[i]);
1650 #endif
1651 }
1652 break;
1653 case MET_FLOAT:
1654 case MET_FLOAT_ARRAY:
1655 for(i=0; i<_n; i++)
1656 {
1657 f.value[i] = (double)((const MET_FLOAT_TYPE *)_v)[i];
1658 }
1659 break;
1660 case MET_DOUBLE:
1661 case MET_DOUBLE_ARRAY:
1662 for(i=0; i<_n; i++)
1663 {
1664 f.value[i] = (double)(((const MET_DOUBLE_TYPE *)_v)[i]);
1665 }
1666 break;
1667 case MET_STRING:
1668 strcpy((MET_CHAR_TYPE *)(f.value), (const MET_CHAR_TYPE *)_v);
1669 break;
1670 case MET_FLOAT_MATRIX:
1671 for(i=0; i<_n*_n; i++)
1672 {
1673 f.value[i] = (double)((const MET_FLOAT_TYPE *)_v)[i];
1674 }
1675 break;
1676 default:
1677 break;
1678 }
1679
1680 METAIO_STL::vector<MET_FieldRecordType *> l;
1681 l.clear();
1682 l.push_back(&f);
1683 MET_Write(_fp, &l);
1684
1685 return true;
1686 }
1687
MET_WriteFieldToFile(METAIO_STREAM::ostream & _fp,const char * _fieldName,MET_ValueEnumType _pType,double _v)1688 bool MET_WriteFieldToFile(METAIO_STREAM::ostream & _fp, const char *_fieldName,
1689 MET_ValueEnumType _pType, double _v)
1690 {
1691 MET_FieldRecordType f;
1692
1693 sprintf(f.name, "%s", _fieldName);
1694 f.defined = false;
1695 f.dependsOn = -1;
1696 f.length = 1;
1697 f.required = false;
1698 f.type = _pType;
1699 f.value[0] = _v;
1700
1701 METAIO_STL::vector<MET_FieldRecordType *> l;
1702 l.clear();
1703 l.push_back(&f);
1704 MET_Write(_fp, &l);
1705
1706 return true;
1707 }
1708
MET_StringToInterpolationType(const char * _str,MET_InterpolationEnumType * _type)1709 bool MET_StringToInterpolationType(const char * _str,
1710 MET_InterpolationEnumType * _type)
1711 {
1712 int i;
1713
1714 for(i=0; i<MET_NUM_INTERPOLATION_TYPES; i++)
1715 if(!strcmp(MET_InterpolationTypeName[i], _str))
1716 {
1717 *_type = (MET_InterpolationEnumType)i;
1718 return true;
1719 }
1720
1721 *_type = MET_NO_INTERPOLATION;
1722
1723 return false;
1724 }
1725
MET_InterpolationTypeToString(MET_InterpolationEnumType _type,char * _str)1726 bool MET_InterpolationTypeToString(MET_InterpolationEnumType _type,
1727 char * _str)
1728 {
1729 strcpy(_str, MET_InterpolationTypeName[(int)_type]);
1730 return true;
1731 }
1732
1733 /** Make sure that all the byte are read and written as LSB */
MET_SwapByteIfSystemMSB(void * val,MET_ValueEnumType _type)1734 void MET_SwapByteIfSystemMSB(void* val, MET_ValueEnumType _type)
1735 {
1736 if(!MET_SystemByteOrderMSB())
1737 {
1738 return;
1739 }
1740
1741 int eSize;
1742 MET_SizeOfType(_type, &eSize);
1743 switch(eSize)
1744 {
1745 default:
1746 case 0:
1747 case 1:
1748 {
1749 break;
1750 }
1751 case 2:
1752 {
1753 MET_ByteOrderSwap2(val);
1754 break;
1755 }
1756 case 4:
1757 {
1758 MET_ByteOrderSwap4(val);
1759 break;
1760 }
1761 case 8:
1762 {
1763 MET_ByteOrderSwap8(val);
1764 break;
1765 }
1766 }
1767 }
1768
1769 #if (METAIO_USE_NAMESPACE)
1770 };
1771 #endif
1772
1773