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 #include "metaArray.h"
13 
14 #ifdef _MSC_VER
15 #pragma warning(disable:4702)
16 #pragma warning(disable:4996)
17 #endif
18 
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <string>
22 #include <string.h> // for memcpy
23 #include <math.h>
24 
25 #if (METAIO_USE_NAMESPACE)
26 namespace METAIO_NAMESPACE {
27 #endif
28 
29 
30 //
31 // MetaArray Constructors
32 //
33 MetaArray::
MetaArray()34 MetaArray()
35 :MetaForm()
36   {
37   if(META_DEBUG)
38     {
39     METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
40     }
41 
42   m_ElementData = NULL;
43   m_AutoFreeElementData = false;
44 
45   m_CompressedElementDataSize = 0;
46 
47   strcpy(m_ElementDataFileName, "");
48 
49   MetaArray::Clear();
50   }
51 
52 //
53 MetaArray::
MetaArray(const char * _headerName)54 MetaArray(const char *_headerName)
55 :MetaForm()
56   {
57   if(META_DEBUG)
58     {
59     METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
60     }
61 
62   m_ElementData = NULL;
63   m_AutoFreeElementData = false;
64 
65   m_CompressedElementDataSize = 0;
66 
67   strcpy(m_ElementDataFileName, "");
68 
69   MetaArray::Clear();
70 
71   MetaArray::Read(_headerName);
72   }
73 
74 //
75 MetaArray::
MetaArray(MetaArray * _vector,bool _allocateElementData,bool _autoFreeElementData)76 MetaArray(MetaArray *_vector,
77           bool _allocateElementData,
78           bool _autoFreeElementData)
79 :MetaForm()
80   {
81   if(META_DEBUG)
82    {
83    METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
84    }
85 
86   m_ElementData = NULL;
87   m_AutoFreeElementData = false;
88 
89   m_CompressedElementDataSize = 0;
90 
91   strcpy(m_ElementDataFileName, "");
92 
93   MetaArray::Clear();
94 
95   InitializeEssential(_vector->Length(),
96                       _vector->ElementType(),
97                       _vector->ElementNumberOfChannels(),
98                       _vector->ElementData(),
99                       _allocateElementData,
100                       _autoFreeElementData);
101 
102   CopyInfo(_vector);
103   }
104 
105 //
106 MetaArray::
MetaArray(int _length,MET_ValueEnumType _elementType,int _elementNumberOfChannels,void * _elementData,bool _allocateElementData,bool _autoFreeElementData)107 MetaArray(int _length,
108           MET_ValueEnumType _elementType,
109           int _elementNumberOfChannels,
110           void *_elementData,
111           bool _allocateElementData,
112           bool _autoFreeElementData)
113 :MetaForm()
114   {
115   if(META_DEBUG)
116    {
117    METAIO_STREAM::cout << "MetaArray()" << METAIO_STREAM::endl;
118    }
119 
120   m_ElementData = NULL;
121   m_AutoFreeElementData = false;
122 
123   m_CompressedElementDataSize = 0;
124 
125   strcpy(m_ElementDataFileName, "");
126 
127   MetaArray::Clear();
128 
129   InitializeEssential(_length,
130                       _elementType,
131                       _elementNumberOfChannels,
132                       _elementData,
133                       _allocateElementData,
134                       _autoFreeElementData);
135   }
136 
137 //
138 MetaArray::
~MetaArray()139 ~MetaArray()
140   {
141   M_Destroy();
142   }
143 
144 //
145 void MetaArray::
PrintInfo() const146 PrintInfo() const
147   {
148   MetaForm::PrintInfo();
149 
150   METAIO_STREAM::cout << "Length = " << (int)m_Length << METAIO_STREAM::endl;
151 
152   METAIO_STREAM::cout << "BinaryData = "
153                       << ((m_BinaryData)?"True":"False")
154                       << METAIO_STREAM::endl;
155 
156   METAIO_STREAM::cout << "BinaryDataByteOrderMSB = "
157                       << ((m_BinaryDataByteOrderMSB)?"True":"False")
158                       << METAIO_STREAM::endl;
159 
160   char str[255];
161   MET_TypeToString(m_ElementType, str);
162   METAIO_STREAM::cout << "ElementType = " << str << METAIO_STREAM::endl;
163 
164   METAIO_STREAM::cout << "ElementNumberOfChannels = "
165                       << m_ElementNumberOfChannels
166                       << METAIO_STREAM::endl;
167 
168   METAIO_STREAM::cout << "AutoFreeElementData = "
169                       << ((m_AutoFreeElementData)?"True":"False")
170                       << METAIO_STREAM::endl;
171 
172   METAIO_STREAM::cout << "CompressedElementDataSize = "
173                       << m_CompressedElementDataSize
174                       << METAIO_STREAM::endl;
175 
176   METAIO_STREAM::cout << "ElementDataFileName = " << m_ElementDataFileName
177                       << METAIO_STREAM::endl;
178 
179   METAIO_STREAM::cout << "ElementData = "
180                       << ((m_ElementData==NULL)?"NULL":"Valid")
181                       << METAIO_STREAM::endl;
182   }
183 
184 void MetaArray::
CopyInfo(const MetaForm * _form)185 CopyInfo(const MetaForm * _form)
186   {
187   MetaForm::CopyInfo(_form);
188   }
189 
190 void MetaArray::
Clear(void)191 Clear(void)
192   {
193   if(META_DEBUG)
194     {
195     METAIO_STREAM::cout << "MetaArray: Clear" << METAIO_STREAM::endl;
196     }
197 
198   m_Length = 0;
199 
200   m_ElementType = MET_NONE;
201 
202   m_ElementNumberOfChannels = 1;
203 
204   m_CompressedElementDataSize = 0;
205 
206   strcpy(m_ElementDataFileName, "");
207 
208   if(m_AutoFreeElementData)
209     {
210     if(m_ElementData != NULL)
211       {
212       delete [] (char *)m_ElementData;
213       }
214     }
215   m_ElementData = NULL;
216   m_AutoFreeElementData = true;
217 
218   MetaForm::Clear();
219   }
220 
221 bool MetaArray::
InitializeEssential(int _length,MET_ValueEnumType _elementType,int _elementNumberOfChannels,void * _elementData,bool _allocateElementData,bool _autoFreeElementData)222 InitializeEssential(int _length,
223                     MET_ValueEnumType _elementType,
224                     int _elementNumberOfChannels,
225                     void * _elementData,
226                     bool _allocateElementData,
227                     bool _autoFreeElementData)
228   {
229   if(META_DEBUG)
230     {
231     METAIO_STREAM::cout << "MetaArray: Initialize" << METAIO_STREAM::endl;
232     }
233 
234   MetaForm::InitializeEssential();
235 
236   bool result = true;
237 
238   if(m_Length != _length ||
239      m_ElementType != _elementType ||
240      m_ElementNumberOfChannels != _elementNumberOfChannels ||
241      _elementData != NULL ||
242      _allocateElementData == true)
243     {
244     if(m_AutoFreeElementData)
245       {
246       if(m_ElementData != NULL)
247         {
248         delete [] (char *)m_ElementData;
249         }
250       }
251     m_ElementData = NULL;
252 
253     m_Length = _length;
254     m_ElementType = _elementType;
255     m_ElementNumberOfChannels = _elementNumberOfChannels;
256 
257     if(_elementData != NULL)
258       {
259       m_ElementData = (void *)_elementData;
260       }
261     else
262       {
263       if(_allocateElementData)
264         {
265         result = AllocateElementData(_autoFreeElementData);
266         }
267       else
268         {
269         m_ElementData = NULL;
270         }
271       }
272 
273     m_AutoFreeElementData = _autoFreeElementData;
274     }
275 
276   return result;
277   }
278 
279 bool MetaArray::
AllocateElementData(bool _autoFreeElementData)280 AllocateElementData(bool _autoFreeElementData)
281   {
282   if(m_AutoFreeElementData)
283     {
284     if(m_ElementData != NULL)
285       {
286       delete [] (char *)m_ElementData;
287       }
288     }
289   m_ElementData = NULL;
290 
291   m_AutoFreeElementData = _autoFreeElementData;
292 
293   int eSize;
294   MET_SizeOfType(m_ElementType, &eSize);
295   m_ElementData = new char[m_Length*m_ElementNumberOfChannels*eSize];
296 
297   if(m_ElementData != NULL)
298     {
299     return true;
300     }
301   else
302     {
303     return false;
304     }
305   }
306 
307 int MetaArray::
Length(void) const308 Length(void) const
309   {
310   return m_Length;
311   }
312 
313 void MetaArray::
Length(int _length)314 Length(int _length)
315   {
316   if(m_Length != _length)
317     {
318     InitializeEssential(_length, m_ElementType, m_ElementNumberOfChannels);
319     }
320   }
321 
322 int MetaArray::
NDims(void) const323 NDims(void) const
324   {
325   return Length();
326   }
327 
328 void MetaArray::
NDims(int _length)329 NDims(int _length)
330   {
331   Length(_length);
332   }
333 
334 MET_ValueEnumType MetaArray::
ElementType(void) const335 ElementType(void) const
336   {
337   return m_ElementType;
338   }
339 
340 void MetaArray::
ElementType(MET_ValueEnumType _elementType)341 ElementType(MET_ValueEnumType _elementType)
342   {
343   if(m_ElementType != _elementType)
344     {
345     InitializeEssential(m_Length, _elementType, m_ElementNumberOfChannels);
346     }
347   }
348 
349 int MetaArray::
ElementNumberOfChannels(void) const350 ElementNumberOfChannels(void) const
351   {
352   return m_ElementNumberOfChannels;
353   }
354 
355 void MetaArray::
ElementNumberOfChannels(int _elementNumberOfChannels)356 ElementNumberOfChannels(int _elementNumberOfChannels)
357   {
358   if(m_ElementNumberOfChannels != _elementNumberOfChannels)
359     {
360     InitializeEssential(m_Length, m_ElementType, _elementNumberOfChannels);
361     }
362   }
363 
364 void MetaArray::
ElementByteOrderSwap(void)365 ElementByteOrderSwap(void)
366   {
367   if(META_DEBUG)
368     {
369     METAIO_STREAM::cout << "MetaArray: ElementByteOrderSwap"
370                         << METAIO_STREAM::endl;
371     }
372 
373   int eSize;
374   MET_SizeOfType(m_ElementType, &eSize);
375   switch(eSize)
376     {
377     default:
378     case 0:
379     case 1:
380       {
381       break;
382       }
383     case 2:
384       {
385       int i;
386       for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
387         {
388         ((MET_USHORT_TYPE *)m_ElementData)[i] =
389               MET_ByteOrderSwapShort(((MET_USHORT_TYPE *)m_ElementData)[i]);
390         }
391       break;
392       }
393     case 4:
394       {
395       int i;
396       for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
397         {
398         ((MET_UINT_TYPE *)m_ElementData)[i] =
399               MET_ByteOrderSwapLong(((MET_UINT_TYPE *)m_ElementData)[i]);
400         }
401       break;
402       }
403     case 8:
404       {
405       int i;
406       char* data = (char*)m_ElementData;
407       for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
408         {
409         MET_ByteOrderSwap8(data);
410         data += 8;
411         }
412       break;
413       }
414     }
415   m_BinaryDataByteOrderMSB = !m_BinaryDataByteOrderMSB;
416   }
417 
418 bool MetaArray::
ElementByteOrderFix(void)419 ElementByteOrderFix(void)
420   {
421   if(m_BinaryDataByteOrderMSB != MET_SystemByteOrderMSB())
422     {
423     ElementByteOrderSwap();
424     return true;
425     }
426   return true;
427   }
428 
429 bool MetaArray::
ConvertElementDataTo(MET_ValueEnumType _toElementType,double _fromMin,double _fromMax,double _toMin,double _toMax)430 ConvertElementDataTo(MET_ValueEnumType _toElementType,
431                      double _fromMin, double _fromMax,
432                      double _toMin, double _toMax)
433   {
434   if(m_ElementData == NULL)
435     {
436     return false;
437     }
438 
439   ElementByteOrderFix();
440 
441   void *            curBuffer              = m_ElementData;
442   MET_ValueEnumType curElementType         = m_ElementType;
443   bool              curAutoFreeElementData = m_AutoFreeElementData;
444 
445   if(m_ElementType != _toElementType)
446     {
447     m_ElementData = NULL;
448     m_ElementType = _toElementType;
449     }
450 
451   ImportBufferToElementData(curBuffer, curElementType,
452                             _fromMin, _fromMax,
453                             _toMin, _toMax );
454 
455   if(m_ElementType != _toElementType)
456     {
457     if(curAutoFreeElementData)
458       {
459       delete [] (char *)curBuffer;
460       }
461     }
462 
463   return true;
464   }
465 
466 bool MetaArray::
ImportBufferToElementData(const void * _fromBuffer,MET_ValueEnumType _fromElementType,double _fromMin,double _fromMax,double _toMin,double _toMax)467 ImportBufferToElementData(const void * _fromBuffer,
468                           MET_ValueEnumType _fromElementType,
469                           double _fromMin, double _fromMax,
470                           double _toMin, double _toMax)
471   {
472   if(m_ElementData == NULL)
473     {
474     AllocateElementData(true);
475     }
476 
477   if(_fromMin == 0 && _fromMax == 0)
478     {
479     MET_ValueToDouble(_fromElementType, _fromBuffer, 0, &_fromMin);
480     _fromMax = _fromMin;
481 
482     int i;
483     for(i=0; i<m_Length*m_ElementNumberOfChannels; i++)
484       {
485       double tf;
486       MET_ValueToDouble(_fromElementType, _fromBuffer, i, &tf);
487       if(tf < _fromMin)
488         {
489         _fromMin = tf;
490         }
491       else if(tf > _fromMax)
492         {
493         _fromMax = tf;
494         }
495       }
496     }
497 
498   if(_toMin == 0 && _toMax == 0)
499     {
500     _toMin = _fromMin;
501     _toMax = _fromMax;
502     }
503 
504   for(int i=0; i<m_Length*m_ElementNumberOfChannels; i++)
505     {
506     MET_ValueToValue(_fromElementType, _fromBuffer, i,
507                      m_ElementType, m_ElementData,
508                      _fromMin, _fromMax,
509                      _toMin, _toMax);
510     }
511 
512   return true;
513   }
514 
515 
516 //
517 //
518 //
519 bool MetaArray::
AutoFreeElementData(void) const520 AutoFreeElementData(void) const
521   {
522   return m_AutoFreeElementData;
523   }
524 
525 void MetaArray::
AutoFreeElementData(bool _autoFreeElementData)526 AutoFreeElementData(bool _autoFreeElementData)
527   {
528   m_AutoFreeElementData = _autoFreeElementData;
529   }
530 
531 
532 //
533 //
534 //
535 const char * MetaArray::
ElementDataFileName(void) const536 ElementDataFileName(void) const
537   {
538   return m_ElementDataFileName;
539   }
540 
541 void MetaArray::
ElementDataFileName(const char * _elementDataFileName)542 ElementDataFileName(const char * _elementDataFileName)
543   {
544   strcpy(m_ElementDataFileName, _elementDataFileName);
545   }
546 
547 
548 //
549 //
550 //
551 void * MetaArray::
ElementData(void)552 ElementData(void)
553   {
554   return m_ElementData;
555   }
556 
557 double MetaArray::
ElementData(int _i) const558 ElementData(int _i) const
559   {
560   double tf = 0;
561   MET_ValueToDouble(m_ElementType, m_ElementData, _i, &tf);
562 
563   return tf;
564   }
565 
566 void MetaArray::
ElementData(void * _elementData,bool _arrayControlsElementData)567 ElementData(void * _elementData, bool _arrayControlsElementData)
568   {
569   if(m_AutoFreeElementData)
570     {
571     delete [] (char *)m_ElementData;
572     }
573   m_ElementData = _elementData;
574   m_AutoFreeElementData = _arrayControlsElementData;
575   }
576 
577 bool MetaArray::
ElementData(int _i,double _v)578 ElementData(int _i, double _v)
579   {
580   if(_i<m_Length*m_ElementNumberOfChannels)
581     {
582     MET_DoubleToValue(_v, m_ElementType, m_ElementData, _i);
583     return true;
584     }
585   return false;
586   }
587 
588 
589 //
590 //
591 //
592 bool MetaArray::
CanRead(const char * _headerName) const593 CanRead(const char *_headerName) const
594   {
595   // First check the extension
596   METAIO_STL::string fname = _headerName;
597   if( fname == "" )
598     {
599     return false;
600     }
601 
602   bool extensionFound = false;
603 
604   METAIO_STL::string::size_type stringPos = fname.rfind(".mva");
605   if ((stringPos != METAIO_STL::string::npos)
606       && (stringPos == fname.length() - 4))
607     {
608     extensionFound = true;
609     }
610 
611   stringPos = fname.rfind(".mvh");
612   if ((stringPos != METAIO_STL::string::npos)
613       && (stringPos == fname.length() - 4))
614     {
615     extensionFound = true;
616     }
617 
618   if( !extensionFound )
619     {
620     return false;
621     }
622 
623   // Now check the file content
624   METAIO_STREAM::ifstream inputStream;
625 
626 #ifdef __sgi
627   inputStream.open( _headerName, METAIO_STREAM::ios::in );
628 #else
629   inputStream.open( _headerName, METAIO_STREAM::ios::in |
630                                  METAIO_STREAM::ios::binary );
631 #endif
632 
633   if( !inputStream.rdbuf()->is_open() )
634     {
635     return false;
636     }
637 
638   bool result = !strncmp(MET_ReadForm(inputStream).c_str(), "Array", 5);
639 
640   inputStream.close();
641 
642   return result;
643   }
644 
645 
646 bool MetaArray::
Read(const char * _headerName,bool _readElements,void * _elementDataBuffer,bool _autoFreeElementData)647 Read(const char *_headerName, bool _readElements,
648      void * _elementDataBuffer, bool _autoFreeElementData)
649   {
650   if(_headerName != NULL)
651     {
652     strcpy(m_FileName, _headerName);
653     }
654 
655   METAIO_STREAM::ifstream * tmpStream = new METAIO_STREAM::ifstream;
656 
657 #ifdef __sgi
658   tmpStream->open(m_FileName, METAIO_STREAM::ios::in );
659 #else
660   tmpStream->open(m_FileName, METAIO_STREAM::ios::in |
661                               METAIO_STREAM::ios::binary);
662 #endif
663 
664   if(!tmpStream->rdbuf()->is_open())
665     {
666     METAIO_STREAM::cout << "MetaArray: Read: Cannot open file _"
667                         << m_FileName << "_" << METAIO_STREAM::endl;
668     delete tmpStream;
669     return false;
670     }
671 
672   bool result = ReadStream(tmpStream, _readElements,
673                            _elementDataBuffer, _autoFreeElementData);
674 
675   if(_headerName != NULL)
676     {
677     strcpy(m_FileName, _headerName);
678     }
679 
680   tmpStream->close();
681 
682   delete tmpStream;
683 
684   return result;
685   }
686 
687 
688 bool MetaArray::
CanReadStream(METAIO_STREAM::ifstream * _stream) const689 CanReadStream(METAIO_STREAM::ifstream * _stream) const
690   {
691   if(!strncmp(MET_ReadForm(*_stream).c_str(), "Array", 5))
692     {
693     return true;
694     }
695   return false;
696   }
697 
698 bool MetaArray::
ReadStream(METAIO_STREAM::ifstream * _stream,bool _readElements,void * _elementDataBuffer,bool _autoFreeElementData)699 ReadStream(METAIO_STREAM::ifstream * _stream, bool _readElements,
700            void * _elementDataBuffer, bool _autoFreeElementData)
701   {
702   if(META_DEBUG)
703     {
704     METAIO_STREAM::cout << "MetaArray: ReadStream" << METAIO_STREAM::endl;
705     }
706 
707   M_Destroy();
708 
709   Clear();
710 
711   M_SetupReadFields();
712 
713   if(m_ReadStream)
714     {
715     METAIO_STREAM::cout << "MetaArray: ReadStream: two files open?"
716                         << METAIO_STREAM::endl;
717     delete m_ReadStream;
718     }
719 
720   m_ReadStream = _stream;
721 
722   if(!M_Read())
723     {
724     METAIO_STREAM::cout << "MetaArray: Read: Cannot parse file"
725                         << METAIO_STREAM::endl;
726     m_ReadStream = NULL;
727     return false;
728     }
729 
730   InitializeEssential(m_Length,
731                       m_ElementType,
732                       m_ElementNumberOfChannels,
733                       _elementDataBuffer,
734                       true,
735                       _autoFreeElementData);
736 
737   bool usePath;
738   char pathName[255];
739   char fName[255];
740   usePath = MET_GetFilePath(m_FileName, pathName);
741 
742   if(_readElements)
743     {
744     if(!strcmp("Local", m_ElementDataFileName) ||
745        !strcmp("LOCAL", m_ElementDataFileName) ||
746        !strcmp("local", m_ElementDataFileName))
747       {
748       M_ReadElements(m_ReadStream, m_ElementData, m_Length);
749       }
750     else
751       {
752       if(usePath)
753         {
754         sprintf(fName, "%s%s", pathName, m_ElementDataFileName);
755         }
756       else
757         {
758         strcpy(fName, m_ElementDataFileName);
759         }
760       METAIO_STREAM::ifstream* readStreamTemp = new METAIO_STREAM::ifstream;
761 
762 #ifdef __sgi
763       readStreamTemp->open(fName, METAIO_STREAM::ios::in);
764 #else
765       readStreamTemp->open(fName, METAIO_STREAM::ios::binary |
766                                   METAIO_STREAM::ios::in);
767 #endif
768       if(!readStreamTemp->rdbuf()->is_open())
769         {
770         METAIO_STREAM::cout << "MetaArray: Read: Cannot open data file"
771                             << METAIO_STREAM::endl;
772         m_ReadStream = NULL;
773         return false;
774         }
775       if(_readElements)
776         {
777         M_ReadElements(readStreamTemp, m_ElementData, m_Length);
778         }
779       readStreamTemp->close();
780       delete readStreamTemp;
781       }
782     }
783 
784   m_ReadStream = NULL;
785 
786   return true;
787   }
788 
789 //
790 //
791 //
792 //
793 
794 bool MetaArray::
Write(const char * _headName,const char * _dataName,bool _writeElements,const void * _constElementData)795 Write(const char *_headName, const char *_dataName, bool _writeElements,
796       const void *_constElementData)
797   {
798   if(_headName != NULL && strlen(_headName)>1)
799     {
800     FileName(_headName);
801     }
802 
803   bool tmpDataFileName = false;
804   if( _dataName != NULL &&
805       strlen(_dataName) > 1 )
806     {
807     tmpDataFileName = true;
808     ElementDataFileName(_dataName);
809     }
810   else
811     {
812     if( strlen(m_ElementDataFileName) == 0 )
813       {
814       tmpDataFileName = true;
815       }
816     }
817 
818   int sPtr = 0;
819   MET_GetFileSuffixPtr(m_FileName, &sPtr);
820   if( !strcmp(&(m_FileName[sPtr]), "mvh") )
821     {
822     MET_SetFileSuffix(m_FileName, "mvh");
823     if( strlen(m_ElementDataFileName) == 0 ||
824         !strcmp(m_ElementDataFileName, "LOCAL") )
825       {
826       ElementDataFileName(m_FileName);
827       }
828     if(m_CompressedData)
829       {
830       MET_SetFileSuffix(m_ElementDataFileName, "zmvd");
831       }
832     else
833       {
834       MET_SetFileSuffix(m_ElementDataFileName, "mvd");
835       }
836     }
837   else
838     {
839     MET_SetFileSuffix(m_FileName, "mva");
840     ElementDataFileName("LOCAL");
841     }
842 
843   char pathName[255];
844   bool usePath = MET_GetFilePath(m_FileName, pathName);
845   if(usePath)
846     {
847     char elementPathName[255];
848     MET_GetFilePath(m_ElementDataFileName, elementPathName);
849     if(!strcmp(pathName, elementPathName))
850       {
851       strcpy(elementPathName, &m_ElementDataFileName[strlen(pathName)]);
852       strcpy(m_ElementDataFileName, elementPathName);
853       }
854     }
855 
856   METAIO_STREAM::ofstream * tmpWriteStream = new METAIO_STREAM::ofstream;
857 
858 // Some older sgi compilers have a error in the ofstream constructor
859 // that requires a file to exist for output
860 #ifdef __sgi
861   {
862   METAIO_STREAM::ofstream tFile(m_FileName, METAIO_STREAM::ios::out);
863   tFile.close();
864   }
865   tmpWriteStream->open(m_FileName, METAIO_STREAM::ios::out);
866 #else
867   tmpWriteStream->open(m_FileName, METAIO_STREAM::ios::binary |
868                                    METAIO_STREAM::ios::out);
869 #endif
870 
871   if(!tmpWriteStream->rdbuf()->is_open())
872     {
873     if(tmpDataFileName)
874       {
875       ElementDataFileName("");
876       }
877     delete tmpWriteStream;
878     return false;
879     }
880 
881   bool result = WriteStream(tmpWriteStream, _writeElements, _constElementData);
882 
883   if(tmpDataFileName)
884     {
885     ElementDataFileName("");
886     }
887 
888   tmpWriteStream->close();
889 
890   delete tmpWriteStream;
891 
892   return result;
893   }
894 
895 bool MetaArray::
WriteStream(METAIO_STREAM::ofstream * _stream,bool _writeElements,const void * _constElementData)896 WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements,
897             const void *_constElementData)
898   {
899   if(m_WriteStream != NULL)
900     {
901     METAIO_STREAM::cout << "MetaArray: WriteStream: two files open?"
902                         << METAIO_STREAM::endl;
903     delete m_WriteStream;
904     }
905 
906   m_WriteStream = _stream;
907 
908   unsigned char * compressedElementData = NULL;
909   if(m_CompressedData)
910     {
911     int elementSize;
912     MET_SizeOfType(m_ElementType, &elementSize);
913     int elementNumberOfBytes = elementSize*m_ElementNumberOfChannels;
914 
915     if(_constElementData == NULL)
916       {
917       compressedElementData = MET_PerformCompression(
918                                     (const unsigned char *)m_ElementData,
919                                     m_Length * elementNumberOfBytes,
920                                     & m_CompressedElementDataSize);
921       }
922     else
923       {
924       compressedElementData = MET_PerformCompression(
925                                     (const unsigned char *)_constElementData,
926                                     m_Length * elementNumberOfBytes,
927                                     & m_CompressedElementDataSize);
928       }
929     }
930 
931   M_SetupWriteFields();
932 
933   M_Write();
934 
935   if(_writeElements)
936     {
937     if(m_CompressedData)
938       {
939       M_WriteElements(m_WriteStream,
940                       compressedElementData,
941                       m_CompressedElementDataSize);
942 
943       delete [] compressedElementData;
944       }
945     else
946       {
947       int elementSize;
948       MET_SizeOfType(m_ElementType, &elementSize);
949       int elementNumberOfBytes = elementSize*m_ElementNumberOfChannels;
950 
951       if(_constElementData != NULL)
952         {
953         M_WriteElements(m_WriteStream,
954                         _constElementData,
955                         elementNumberOfBytes * m_Length);
956         }
957       else
958         {
959         M_WriteElements(m_WriteStream,
960                         m_ElementData,
961                         elementNumberOfBytes * m_Length);
962         }
963       }
964     }
965 
966   m_WriteStream->flush();
967 
968   m_WriteStream = NULL;
969 
970   return true;
971   }
972 
973 void MetaArray::
M_Destroy(void)974 M_Destroy(void)
975   {
976   if(m_AutoFreeElementData && m_ElementData != NULL)
977     {
978     delete [] (char *)m_ElementData;
979     }
980   m_ElementData = NULL;
981 
982   MetaForm::M_Destroy();
983   }
984 
985 void MetaArray::
M_SetupReadFields(void)986 M_SetupReadFields(void)
987   {
988   if(META_DEBUG)
989     {
990     METAIO_STREAM::cout << "MetaArray: M_SetupReadFields"
991                         << METAIO_STREAM::endl;
992     }
993 
994   MetaForm::M_SetupReadFields();
995 
996   MET_FieldRecordType * mF;
997 
998   mF = new MET_FieldRecordType;
999   MET_InitReadField(mF, "Length", MET_INT, false);
1000   m_Fields.push_back(mF);
1001 
1002   mF = new MET_FieldRecordType;
1003   MET_InitReadField(mF, "NDims", MET_INT, false);
1004   m_Fields.push_back(mF);
1005 
1006   mF = new MET_FieldRecordType;
1007   MET_InitReadField(mF, "ElementNumberOfChannels", MET_INT, false);
1008   m_Fields.push_back(mF);
1009 
1010   mF = new MET_FieldRecordType;
1011   MET_InitReadField(mF, "ElementType", MET_STRING, true);
1012   mF->required = true;
1013   m_Fields.push_back(mF);
1014 
1015   mF = new MET_FieldRecordType;
1016   MET_InitReadField(mF, "ElementDataFile", MET_STRING, true);
1017   mF->required = true;
1018   mF->terminateRead = true;
1019   m_Fields.push_back(mF);
1020   }
1021 
1022 void MetaArray::
M_SetupWriteFields(void)1023 M_SetupWriteFields(void)
1024   {
1025   strcpy(m_FormTypeName, "Array");
1026   MetaForm::M_SetupWriteFields();
1027 
1028   MET_FieldRecordType * mF;
1029 
1030   mF = new MET_FieldRecordType;
1031   MET_InitWriteField(mF, "Length", MET_INT, m_Length);
1032   m_Fields.push_back(mF);
1033 
1034   if(m_ElementNumberOfChannels>1)
1035     {
1036     mF = new MET_FieldRecordType;
1037     MET_InitWriteField(mF, "ElementNumberOfChannels", MET_INT,
1038                        m_ElementNumberOfChannels);
1039     m_Fields.push_back(mF);
1040     }
1041 
1042   char s[80];
1043   mF = new MET_FieldRecordType;
1044   MET_TypeToString(m_ElementType, s);
1045   MET_InitWriteField(mF, "ElementType", MET_STRING, strlen(s), s);
1046   m_Fields.push_back(mF);
1047 
1048   mF = new MET_FieldRecordType;
1049   MET_InitWriteField(mF, "ElementDataFile", MET_STRING,
1050                      strlen(m_ElementDataFileName),
1051                      m_ElementDataFileName);
1052   mF->terminateRead = true;
1053   m_Fields.push_back(mF);
1054   }
1055 
1056 
1057 bool MetaArray::
M_Read(void)1058 M_Read(void)
1059   {
1060   if(META_DEBUG)
1061     {
1062     METAIO_STREAM::cout << "MetaArray: M_Read: Loading Header"
1063                         << METAIO_STREAM::endl;
1064     }
1065   if(!MetaForm::M_Read())
1066     {
1067     METAIO_STREAM::cout << "MetaArray: M_Read: Error parsing file"
1068                         << METAIO_STREAM::endl;
1069     return false;
1070     }
1071 
1072   if(META_DEBUG)
1073     {
1074     METAIO_STREAM::cout << "MetaArray: M_Read: Parsing Header"
1075                         << METAIO_STREAM::endl;
1076     }
1077   MET_FieldRecordType * mF;
1078 
1079   mF = MET_GetFieldRecord("Length", &m_Fields);
1080   if(mF && mF->defined)
1081     {
1082     m_Length = (int)mF->value[0];
1083     }
1084   else
1085     {
1086     mF = MET_GetFieldRecord("NDims", &m_Fields);
1087     if(mF && mF->defined)
1088       {
1089       m_Length = (int)mF->value[0];
1090       }
1091     else
1092       {
1093       METAIO_STREAM::cout << "MetaArray: M_Read: Error: Length required"
1094                           << METAIO_STREAM::endl;
1095       return false;
1096       }
1097     }
1098 
1099   mF = MET_GetFieldRecord("ElementNumberOfChannels", &m_Fields);
1100   if(mF && mF->defined)
1101     {
1102     m_ElementNumberOfChannels = (int)mF->value[0];
1103     }
1104 
1105   mF = MET_GetFieldRecord("ElementType", &m_Fields);
1106   if(mF && mF->defined)
1107     {
1108     MET_StringToType((char *)(mF->value), &m_ElementType);
1109     }
1110 
1111   mF = MET_GetFieldRecord("ElementDataFile", &m_Fields);
1112   if(mF && mF->defined)
1113     {
1114     strcpy(m_ElementDataFileName, (char *)(mF->value));
1115     }
1116 
1117   return true;
1118   }
1119 
1120 //
1121 //
1122 //
1123 bool MetaArray::
M_ReadElements(METAIO_STREAM::ifstream * _fstream,void * _data,int _dataQuantity)1124 M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data,
1125                int _dataQuantity)
1126   {
1127   if(META_DEBUG)
1128     {
1129     METAIO_STREAM::cout << "MetaArray: M_ReadElements" << METAIO_STREAM::endl;
1130     }
1131 
1132   int elementSize;
1133   MET_SizeOfType(m_ElementType, &elementSize);
1134   int readSize = _dataQuantity*m_ElementNumberOfChannels*elementSize;
1135   if(META_DEBUG)
1136     {
1137     METAIO_STREAM::cout << "MetaArray: M_ReadElements: ReadSize = "
1138                         << readSize << METAIO_STREAM::endl;
1139     }
1140 
1141   // If compressed we inflate
1142   if(m_CompressedData)
1143     {
1144     // if m_CompressedElementDataSize is not defined we assume the size of the
1145     // file is the size of the compressed data
1146     if(m_CompressedElementDataSize==0)
1147       {
1148       _fstream->seekg(0, METAIO_STREAM::ios::end);
1149       m_CompressedElementDataSize = _fstream->tellg();
1150       _fstream->seekg(0, METAIO_STREAM::ios::beg);
1151       }
1152 
1153     unsigned char* compr = new unsigned char[m_CompressedElementDataSize];
1154     _fstream->read((char *)compr, (size_t)m_CompressedElementDataSize);
1155 
1156     MET_PerformUncompression(compr, m_CompressedElementDataSize,
1157                              (unsigned char *)_data, readSize);
1158     }
1159   else // if not compressed
1160     {
1161     if(!m_BinaryData)
1162       {
1163       double tf;
1164       for(int i=0; i<_dataQuantity*m_ElementNumberOfChannels; i++)
1165         {
1166         *_fstream >> tf;
1167         MET_DoubleToValue(tf, m_ElementType, _data, i);
1168         _fstream->get();
1169         }
1170       }
1171     else
1172       {
1173       _fstream->read((char *)_data, readSize);
1174       int gc = _fstream->gcount();
1175       if(gc != readSize)
1176         {
1177         METAIO_STREAM::cout
1178                   << "MetaArray: M_ReadElements: data not read completely"
1179                   << METAIO_STREAM::endl;
1180         METAIO_STREAM::cout << "   ideal = " << readSize
1181                             << " : actual = " << gc
1182                             << METAIO_STREAM::endl;
1183         return false;
1184         }
1185       }
1186     }
1187 
1188   return true;
1189   }
1190 
1191 //
1192 //
1193 //
1194 bool MetaArray::
M_WriteElements(METAIO_STREAM::ofstream * _fstream,const void * _data,METAIO_STL::streamoff _dataQuantity)1195 M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data,
1196                METAIO_STL::streamoff _dataQuantity)
1197   {
1198   bool localData = false;
1199   METAIO_STREAM::ofstream* tmpWriteStream;
1200   if(!strcmp(m_ElementDataFileName, "LOCAL"))
1201     {
1202     localData = true;
1203     tmpWriteStream = _fstream;
1204     }
1205   else
1206     {
1207     localData = false;
1208     tmpWriteStream = new METAIO_STREAM::ofstream;
1209 
1210     char dataFileName[255];
1211     char pathName[255];
1212     bool usePath = MET_GetFilePath(m_FileName, pathName);
1213     if(usePath)
1214       {
1215       sprintf(dataFileName, "%s%s", pathName, m_ElementDataFileName);
1216       }
1217     else
1218       {
1219       strcpy(dataFileName, m_ElementDataFileName);
1220       }
1221 
1222 // Some older sgi compilers have a error in the ofstream constructor
1223 // that requires a file to exist for output
1224 #ifdef __sgi
1225     {
1226     METAIO_STREAM::ofstream tFile(dataFileName, METAIO_STREAM::ios::out);
1227     tFile.close();
1228     }
1229     tmpWriteStream->open(dataFileName, METAIO_STREAM::ios::out);
1230 #else
1231     tmpWriteStream->open(dataFileName, METAIO_STREAM::ios::binary |
1232                                        METAIO_STREAM::ios::out);
1233 #endif
1234     }
1235 
1236   if(!m_BinaryData)
1237     {
1238     double tf;
1239     for(int i=0; i<m_Length*m_ElementNumberOfChannels; i++)
1240       {
1241       MET_ValueToDouble(m_ElementType, _data, i, &tf);
1242       if((i+1)/10 == (double)(i+1.0)/10.0)
1243         {
1244         (*tmpWriteStream) << tf << METAIO_STREAM::endl;
1245         }
1246       else
1247         {
1248         (*tmpWriteStream) << tf << " ";
1249         }
1250       }
1251     }
1252    else
1253     {
1254     tmpWriteStream->write( (const char *)_data, (size_t)_dataQuantity );
1255     }
1256 
1257   if(!localData)
1258     {
1259     tmpWriteStream->close();
1260     delete tmpWriteStream;
1261     }
1262 
1263   return true;
1264   }
1265 
1266 
1267 #if (METAIO_USE_NAMESPACE)
1268 };
1269 #endif
1270 
1271