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