Migrated from xerces=2.x
[snark14.git] / src / DIGFile / DIGFile.cpp
1 /*
2
3   This file is part of DIG Library.
4   DIG Library is a free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published
6   by the Free Software Foundation; either version 2 of the License,
7   or (at your option) any later version.
8   DIG Library is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11   General Public License for more details.
12   You should have received a copy of the GNU General Public License
13   along with Foobar; if not, write to the Free Software Foundation,
14   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
16 */
17
18 // DIGFile.cpp,v 1.20 2007/06/14 17:10:50 swr Exp
19
20 //defines added to enable large file support
21 //jklukowska, 06/07/2007
22 #ifndef _LARGEFILE_SOURCE
23         #define _LARGEFILE_SOURCE     /* enable large file support  */
24 #endif
25 #ifndef _FILE_OFFSET_BITS
26         #define _FILE_OFFSET_BITS 64     /* enable large file support  */
27 #endif
28
29 // bug 226 - needed to compile this file on cygwin - swr - 6/14/07
30 #undef __STRICT_ANSI__
31
32 //#include <iostream>
33 #include <cstring>
34 #include <cstdlib>
35 #include <cstdio>
36 #include <cmath>
37
38 #include <xercesc/framework/StdOutFormatTarget.hpp>
39 #include <xercesc/framework/LocalFileFormatTarget.hpp>
40 #include <xercesc/framework/MemBufFormatTarget.hpp>
41
42 //#include <xercesc/util/XMLDouble.hpp>
43
44
45 //#include "DIGFile.h"
46 #include <DIGFile/DIGFile.h>
47
48 #define DIGFILE_DEBUG_LEVEL 0
49         
50
51 const char* DIGEndianStr[DIGEndianSize] = {
52   "little", 
53   "big"
54 };
55
56 const char* DIGValueTypeStr[DIGValueTypeSize] = {
57   "real", 
58   "complex"
59 }; 
60
61 const char* DIGDataTypeStr[DIGDataTypeSize] = {
62   "bool", 
63   "unsigned char", 
64   "char", 
65   "unsigned short", 
66   "short", 
67   "unsigned int", 
68   "int", 
69   "float", 
70   "double"
71 }; 
72
73 const char* DIGDataFormatStr[DIGDataFormatSize] = {
74   "ASCII", 
75   "binary"
76 };
77
78 const char* DIGGridStr[DIGGridSize] = {
79   "SC", 
80   "FCC1", 
81   "FCC2", 
82   "BCC1", 
83   "BCC2", 
84   "BCC3", 
85   "BCC4", 
86   "HEX1", 
87   "HEX2"
88 };
89
90 const char* DIGBasisStr[DIGBasisSize] = {
91   "voronoi", 
92   "blob"
93 };
94
95 const char* DIGUnitStr[DIGUnitSize] = {
96   "unspecified", 
97   "m", 
98   "cm", 
99   "mm", 
100   "nm", 
101   "micron", 
102   "A", 
103   "other"
104 };
105
106 static char DIGEmptyStr[1] = "";
107
108 bool DIGFile::XMLStringsInitialized = false;
109
110 const XMLCh* DIGFile::RootXMLStr;
111
112 const XMLCh* DIGFile::MainHeaderXMLStr;
113
114 const XMLCh* DIGFile::TitleXMLStr;
115 const XMLCh* DIGFile::TypeXMLStr;
116 const XMLCh* DIGFile::ChannelsXMLStr;
117 const XMLCh* DIGFile::NumberOfArraysXMLStr;
118 const XMLCh* DIGFile::NumberOfArraySetsXMLStr;
119 const XMLCh* DIGFile::EndianXMLStr;
120 const XMLCh* DIGFile::ValueTypeXMLStr;
121 const XMLCh* DIGFile::DataTypeXMLStr;
122 const XMLCh* DIGFile::DataFormatXMLStr;
123 const XMLCh* DIGFile::GridTypeXMLStr;
124 const XMLCh* DIGFile::BasisFunctionXMLStr;
125 const XMLCh* DIGFile::UnitXMLStr;
126 const XMLCh* DIGFile::OtherUnitXMLStr;
127 const XMLCh* DIGFile::CommentsXMLStr;
128 const XMLCh* DIGFile::DimensionsXMLStr;
129
130 const XMLCh* DIGFile::DimmensionXXMLStr;
131 const XMLCh* DIGFile::DimmensionYXMLStr;      
132 const XMLCh* DIGFile::DimmensionZXMLStr;
133
134 const XMLCh* DIGFile::SamplingRateXXMLStr;
135 const XMLCh* DIGFile::SamplingRateYXMLStr;
136 const XMLCh* DIGFile::SamplingRateZXMLStr;
137
138 const XMLCh* DIGFile::ArraySetHeaderXMLStr;
139
140 //const XMLCh* DIGFile::TypeXMLStr;
141 //const XMLCh* DIGFile::TitleXMLStr;
142 const XMLCh* DIGFile::ParametersXMLStr;
143
144 const XMLCh* DIGFile::ArrayHeaderXMLStr;
145 const XMLCh* DIGFile::EnumerationNumberXMLStr;
146
147
148 class DOMPrintErrorHandler : public DOMErrorHandler
149 {
150 public:
151
152   DOMPrintErrorHandler(){};
153   ~DOMPrintErrorHandler(){};
154
155   /** @name The error handler interface */
156   bool handleError(const DOMError& domError);
157   void resetErrors(){};
158
159 private :
160   /* Unimplemented constructors and operators */ 
161   DOMPrintErrorHandler(const DOMErrorHandler&);
162   void operator=(const DOMErrorHandler&);
163     
164 };
165
166 bool DOMPrintErrorHandler::handleError(const DOMError &domError)
167 {
168   // Display whatever error message passed from the serializer
169   char *msg = XMLString::transcode(domError.getMessage());
170   std::cout<<msg<<std::endl;
171   delete[] msg;
172
173   // Instructs the serializer to continue serialization if possible.
174   return true;
175 }
176
177
178 DIGFile::DIGFile()
179 {
180 #if DIGFILE_DEBUG_LEVEL > 2\r
181   fprintf(stderr, "DIGFile::DIGFile\n");\r
182 #endif\r
183
184   MainHeaderWritten = false;
185   ArraySetOpen = false;
186   //ArrayCounter = 0;
187
188   NoOfSets = 0;
189   NoOfArrays = 0;
190
191   Dirty = false;
192   File = NULL;
193
194   // ??????????????????????????
195         // Initialization\r
196 \r
197 #if DIGFILE_DEBUG_LEVEL > 1\r
198   printf("Initializing XML parser\n");\r
199 #endif\r
200
201         try {
202                 XMLPlatformUtils::Initialize();
203         }
204         catch(const XMLException &toCatch) {
205                 std::cerr << "Error during Xerces-c Initialization.\n"
206                         << "  Exception message:"
207                         << StrX(toCatch.getMessage()) << std::endl;
208                 //return 1;
209         }
210   
211   if(!XMLStringsInitialized) {
212
213     RootXMLStr               = XMLString::transcode("DIG_DATA");
214
215     MainHeaderXMLStr         = XMLString::transcode("main_header");
216
217     TitleXMLStr              = XMLString::transcode("title");
218     TypeXMLStr               = XMLString::transcode("type");
219     ChannelsXMLStr           = XMLString::transcode("channels");
220     NumberOfArraysXMLStr     = XMLString::transcode("number_of_arrays");
221     NumberOfArraySetsXMLStr  = XMLString::transcode("number_of_array_sets");
222     EndianXMLStr             = XMLString::transcode("endian");
223     ValueTypeXMLStr          = XMLString::transcode("value_type");
224     DataTypeXMLStr           = XMLString::transcode("data_type");
225     DataFormatXMLStr         = XMLString::transcode("data_format");
226     GridTypeXMLStr           = XMLString::transcode("grid_type");
227     BasisFunctionXMLStr      = XMLString::transcode("basis_function");
228     UnitXMLStr               = XMLString::transcode("unit");
229     OtherUnitXMLStr          = XMLString::transcode("other_unit");
230     CommentsXMLStr           = XMLString::transcode("comments");
231     DimensionsXMLStr         = XMLString::transcode("dimensions");
232
233     DimmensionXXMLStr        = XMLString::transcode("x");
234     DimmensionYXMLStr        = XMLString::transcode("y");
235     DimmensionZXMLStr        = XMLString::transcode("z");
236
237     SamplingRateXXMLStr      = XMLString::transcode("sampling_rate_x");
238     SamplingRateYXMLStr      = XMLString::transcode("sampling_rate_y");
239     SamplingRateZXMLStr      = XMLString::transcode("sampling_rate_z");
240
241     ArraySetHeaderXMLStr     = XMLString::transcode("array_set_header");
242
243     // TypeXMLStr               = XMLString::transcode("type");
244     // TitleXMLStr              = XMLString::transcode("title");
245     ParametersXMLStr         = XMLString::transcode("parameters");
246
247     ArrayHeaderXMLStr        = XMLString::transcode("array_header");
248     EnumerationNumberXMLStr  = XMLString::transcode("enumeration_number");
249
250     XMLStringsInitialized = true;
251   }
252 }
253
254 int DIGFile::FindSrting(char* String, FILE* File)
255 {\r
256 #if DIGFILE_DEBUG_LEVEL > 2\r
257   fprintf(stderr, "DIGFile::FindSrting\n");\r
258 #endif\r
259
260   int i;
261   char ch;
262   int offset = 0;
263
264   // get legth of the string
265   int len = strlen(String);
266   
267   // create input buffer
268   char* Buffer = new char[len];
269   int head = 0; 
270   int tail = 0;
271
272   for(;;) {
273     // find match for first character in the string
274     while((ch = getc(File)) != String[0] && (ch != EOF)) {
275       offset++;
276     }
277
278     if(ch == EOF) {
279       return -1; // not found
280     }
281
282     // put first file character into the buffer
283     Buffer[0] = ch;
284     tail = 1;
285     int count = 1;
286
287     do {
288       // fill Buffer with file characters
289       for(i = count; i < len; i++) {
290         if((ch = getc(File)) == EOF) {
291           return -1;
292         }
293         Buffer[tail] = ch;
294         tail = (tail + 1) % len;
295       }
296
297       count = len;
298
299       // compare
300       int ptr = head;
301
302       for(i = 1; i < len; i++) {
303
304         ptr = (ptr + 1) % len;
305
306         if(Buffer[ptr] != String[i]) {
307           break; // found first difference
308         }
309       }
310
311       if(i == len) { // full match
312         return offset;
313       }
314
315       // move head to the next match for first character
316       do {
317         count--;
318         head = (head + 1) % len;
319         offset++;
320
321         if(Buffer[head] == String[0]) {
322           break; // found match for first character in the string
323         }
324       } 
325       while(count > 0);
326     }
327     while(count > 0);
328   }
329 }
330
331
332 int DIGFile::GetXMLHeader(char** XMLBuff)
333 {\r
334 #if DIGFILE_DEBUG_LEVEL > 2\r
335   fprintf(stderr, "DIGFile::GetXMLHeader\n");\r
336 #endif\r
337
338   static char TerminationString[] = "</DIG_DATA>";
339   \r
340 #if DIGFILE_DEBUG_LEVEL > 1\r
341   printf("Searching for XML termnation\n");\r
342 #endif\r
343
344   // search for end of XML
345   if((XMLHeaderLength = FindSrting(TerminationString, File)) == -1) {\r
346 #if DIGFILE_DEBUG_LEVEL > 0\r
347     printf("** Error: missing XML termnation\n");\r
348 #endif
349     return -1; // error missing XML termnation
350   }
351
352   // add length of termnating string and 1 for the following LF
353   XMLHeaderLength += strlen(TerminationString) + 1;
354 \r
355 #if DIGFILE_DEBUG_LEVEL > 1\r
356   printf("Reading XML Header\n");\r
357 #endif\r
358
359   // read XML to memory
360   *XMLBuff = new char[XMLHeaderLength+1];
361
362   rewind(File);
363
364   if(fread((void*) *XMLBuff, 1, XMLHeaderLength, File) != (unsigned int) XMLHeaderLength) {\r
365 \r
366 #if DIGFILE_DEBUG_LEVEL > 0\r
367     printf("** Error: reading file\n");\r
368 #endif\r
369     return -1; // error reading file
370   }
371
372   (*XMLBuff)[XMLHeaderLength] = 0;
373
374   return 0;
375 }
376
377
378 // open existing file
379
380 int DIGFile::Open(const char* FileName)
381 {\r
382 #if DIGFILE_DEBUG_LEVEL > 2\r
383   fprintf(stderr, "DIGFile::Open\n");\r
384 #endif\r
385
386   char* XMLBuffer;
387
388   if(File != NULL) {\r
389 \r
390 #if DIGFILE_DEBUG_LEVEL > 0\r
391     printf("** Error: DIG File already open\n");\r
392 #endif
393     return -1; // DIG File already open
394   }
395 \r
396 #if DIGFILE_DEBUG_LEVEL > 1\r
397   printf("Opening DIG file for reading\n");\r
398 #endif\r
399
400   // try to open DIG File for reading
401   if((File = fopen(FileName, "r+b")) == NULL) {\r
402 \r
403 #if DIGFILE_DEBUG_LEVEL > 0\r
404     printf("** Error: unable to open DIG File\n");\r
405 #endif
406     return -1; // unable to open DIG File
407   }
408 \r
409 #if DIGFILE_DEBUG_LEVEL > 1\r
410     printf("Loading XML header\n");\r
411 #endif\r
412
413   // load XML header
414   if(GetXMLHeader(&XMLBuffer) != 0) {\r
415 #if DIGFILE_DEBUG_LEVEL > 0\r
416     printf("** Error: invalid DIG File (missing XML header\n");\r
417 #endif
418     return -2; // invalid DIG File (missing XML header)
419   }
420 \r
421 #if DIGFILE_DEBUG_LEVEL > 1\r
422   printf("Parsing XML Header\n");\r
423 #endif\r
424
425   // parse XML and load structures
426   if(ParseXML(XMLBuffer) != 0) {\r
427 #if DIGFILE_DEBUG_LEVEL > 0\r
428     printf("** Error: unable to parse XML header\n");\r
429 #endif
430     return -3; // unable to parse XML header
431   }
432
433   NoOfArrayItems = ComputeArrayNoOfItems();
434   ArrayBufferSize = ComputeArrayBufferSize();
435   Dirty = false;
436
437   return 0;
438 }
439
440
441 // open new file
442
443 int DIGFile::Open(
444   const char*           pFileName,
445   const char*           pSchema,
446         const char*           pTitle,
447         const char*           pType,
448         unsigned int          pChannels,
449         //DIGEndian             pEndian,
450         DIGValueType          pValueType,
451         DIGDataType           pDataType,
452         DIGDataFormat         pDataFormat,
453         DIGGrid               pGrid,
454         DIGBasis              pBasis,
455         DIGUnit               pUnit,
456         const DIGDimensions*  pDimensions,
457         const DIGSampling*    pSamplingX,
458         const DIGSampling*    pSamplingY,
459         const DIGSampling*    pSamplingZ,
460         const char*           pComment,
461         const char*           pOtherUnit
462 )
463 {\r
464 #if DIGFILE_DEBUG_LEVEL > 2\r
465   fprintf(stderr, "DIGFile::Open\n");\r
466 #endif\r
467
468   if(File != NULL) {\r
469 #if DIGFILE_DEBUG_LEVEL > 0\r
470     printf("** Error: DIG File already open\n");\r
471 #endif
472     return -1; // DIG File already open
473   }
474
475   if(SchemaName.Set(pSchema) != 0) {\r
476 #if DIGFILE_DEBUG_LEVEL > 0\r
477     printf("** Error: \n");\r
478 #endif
479     return -1; // 
480   }
481
482         // open temp file for data
483   TmpDataFile = tmpfile();
484 \r
485 #if DIGFILE_DEBUG_LEVEL > 1\r
486   printf("Opening DIG File\n");\r
487 #endif\r
488
489   if((File = fopen(pFileName, "w+b")) == NULL) {\r
490 #if DIGFILE_DEBUG_LEVEL > 0\r
491     printf("** Error: unable to open file\n");\r
492 #endif
493     return -1; // unable to open file
494   }     
495
496   MainHeader.Title.Set(pTitle);
497   MainHeader.Type.Set(pType);
498   MainHeader.Channels = pChannels;
499   //MainHeader.number_of_arrays = ;
500   //MainHeader.number_of_sets =;
501   //MainHeader.Endian = pEndian;
502   MainHeader.ValueType = pValueType;
503   MainHeader.DataType = pDataType;
504   MainHeader.DataFormat = pDataFormat;
505   MainHeader.Grid = pGrid;
506   MainHeader.Basis = pBasis;
507   MainHeader.Unit = pUnit;
508         MainHeader.OtherUnit.Set(pOtherUnit);
509   MainHeader.Dimensions.x = pDimensions->x;
510   MainHeader.Dimensions.y = pDimensions->y;
511   MainHeader.Dimensions.z = pDimensions->z;
512   MainHeader.SamplingX.x = pSamplingX->x;
513   MainHeader.SamplingX.y = pSamplingX->y;
514   MainHeader.SamplingX.z = pSamplingX->z;
515   MainHeader.SamplingY.x = pSamplingY->x;
516   MainHeader.SamplingY.y = pSamplingY->y;
517   MainHeader.SamplingY.z = pSamplingY->z;
518   MainHeader.SamplingZ.x = pSamplingZ->x;
519   MainHeader.SamplingZ.y = pSamplingZ->y;
520   MainHeader.SamplingZ.z = pSamplingZ->z;
521
522   MainHeader.Comment.Set(pComment);
523
524   Dirty = true;
525
526   NoOfArrayItems = ComputeArrayNoOfItems();
527   ArrayBufferSize = ComputeArrayBufferSize();
528
529
530   XMLCh tempStr[100];
531
532   XMLString::transcode("Core", tempStr, 99);
533
534   impl =  DOMImplementationRegistry::getDOMImplementation(tempStr);
535
536   return 0;
537 }
538
539
540 int DIGFile::SetComment(const char* pComment)
541 {\r
542 #if DIGFILE_DEBUG_LEVEL > 2\r
543   fprintf(stderr, "DIGFile::SetComment\n");\r
544 #endif\r
545
546   MainHeader.Comment.Set(pComment);
547   return 0;
548 }
549
550
551 int DIGFile::SetTitle(const char* pTitle)
552 {\r
553 #if DIGFILE_DEBUG_LEVEL > 2\r
554   fprintf(stderr, "DIGFile::SetTitle\n");\r
555 #endif\r
556
557   MainHeader.Title.Set(pTitle);
558   return 0;
559 }
560
561
562 int DIGFile::GetTitle(const char** pTitle)
563 {\r
564 #if DIGFILE_DEBUG_LEVEL > 2\r
565   fprintf(stderr, "DIGFile::GetTitle\n");\r
566 #endif\r
567
568   *pTitle = MainHeader.Title.Get();
569   return 0;
570 }
571
572
573 int DIGFile::GetType(const char** pType)
574 {\r
575 #if DIGFILE_DEBUG_LEVEL > 2\r
576   fprintf(stderr, "DIGFile::GetType\n");\r
577 #endif\r
578
579   *pType = MainHeader.Type.Get();
580   return 0;
581 }
582
583
584 int DIGFile::GetChannels(unsigned int* pChannels)
585 {\r
586 #if DIGFILE_DEBUG_LEVEL > 2\r
587   fprintf(stderr, "DIGFile::GetChannels\n");\r
588 #endif\r
589
590   *pChannels = MainHeader.Channels;
591   return 0;
592 }
593
594
595 int DIGFile::GetEndian(DIGEndian* pEndian)
596 {\r
597 #if DIGFILE_DEBUG_LEVEL > 2\r
598   fprintf(stderr, "DIGFile::GetEndian\n");\r
599 #endif\r
600
601   *pEndian = Endian;
602   return 0;
603 }
604
605
606 int DIGFile::GetValueType(DIGValueType* pValueType)
607 {\r
608 #if DIGFILE_DEBUG_LEVEL > 2\r
609   fprintf(stderr, "DIGFile::GetValueType\n");\r
610 #endif\r
611
612   *pValueType = MainHeader.ValueType;
613   return 0;
614 }
615
616
617 int DIGFile::GetDataType(DIGDataType* pDataType)
618 {\r
619 #if DIGFILE_DEBUG_LEVEL > 2\r
620   fprintf(stderr, "DIGFile::GetDataType\n");\r
621 #endif\r
622
623   *pDataType = MainHeader.DataType;
624   return 0;
625 }
626
627
628 int DIGFile::GetDataFormat(DIGDataFormat* pDataFormat)
629 {\r
630 #if DIGFILE_DEBUG_LEVEL > 2\r
631   fprintf(stderr, "DIGFile::GetDataFormat\n");\r
632 #endif\r
633
634   *pDataFormat = MainHeader.DataFormat;
635   return 0;
636 }
637
638
639 int DIGFile::GetGrid(DIGGrid* pGrid)
640 {\r
641 #if DIGFILE_DEBUG_LEVEL > 2\r
642   fprintf(stderr, "DIGFile::GetGrid\n");\r
643 #endif\r
644
645   *pGrid = MainHeader.Grid;
646   return 0;
647 }
648
649
650 int DIGFile::GetBasis(DIGBasis* pBasis)
651 {\r
652 #if DIGFILE_DEBUG_LEVEL > 2\r
653   fprintf(stderr, "DIGFile::GetBasis\n");\r
654 #endif\r
655
656   *pBasis = MainHeader.Basis;
657   return 0;
658 }
659
660
661 int DIGFile::GetUnit(DIGUnit* pUnit)
662 {\r
663 #if DIGFILE_DEBUG_LEVEL > 2\r
664   fprintf(stderr, "DIGFile::GetUnit\n");\r
665 #endif\r
666
667   *pUnit = MainHeader.Unit;
668   return 0;
669 }
670
671
672 int DIGFile::GetOtherUnit(const char** pOtherUnit)
673 {\r
674 #if DIGFILE_DEBUG_LEVEL > 2\r
675   fprintf(stderr, "DIGFile::GetOtherUnit\n");\r
676 #endif\r
677
678   *pOtherUnit = MainHeader.OtherUnit.Get();
679   return 0;
680 }
681
682
683 int DIGFile::GetDimensions(const DIGDimensions** pDimensions)
684 {\r
685 #if DIGFILE_DEBUG_LEVEL > 2\r
686   fprintf(stderr, "DIGFile::GetDimensions\n");\r
687 #endif\r
688
689   *pDimensions = &(MainHeader.Dimensions);
690   return 0;
691 }
692
693
694 int DIGFile::GetSamplingX(const DIGSampling** pSampling)
695 {\r
696 #if DIGFILE_DEBUG_LEVEL > 2\r
697   fprintf(stderr, "DIGFile::GetSamplingX\n");\r
698 #endif\r
699
700   *pSampling = &(MainHeader.SamplingX);
701   return 0;
702 }
703
704
705 int DIGFile::GetSamplingY(const DIGSampling** pSampling)
706 {\r
707 #if DIGFILE_DEBUG_LEVEL > 2\r
708   fprintf(stderr, "DIGFile::GetSamplingY\n");\r
709 #endif\r
710
711   *pSampling = &(MainHeader.SamplingY);
712   return 0;
713 }
714
715
716 int DIGFile::GetSamplingZ(const DIGSampling** pSampling)
717 {\r
718 #if DIGFILE_DEBUG_LEVEL > 2\r
719   fprintf(stderr, "DIGFile::GetSamplingZ\n");\r
720 #endif\r
721
722   *pSampling = &(MainHeader.SamplingZ);
723   return 0;
724 }
725
726
727 int  DIGFile::GetComment(const char** pComment)
728 {\r
729 #if DIGFILE_DEBUG_LEVEL > 2\r
730   fprintf(stderr, "DIGFile::GetComment\n");\r
731 #endif\r
732
733   *pComment = MainHeader.Comment.Get();
734   return 0;
735 }
736
737
738 unsigned int DIGFile::ComputeArrayNoOfItems()
739 {\r
740 #if DIGFILE_DEBUG_LEVEL > 2\r
741   fprintf(stderr, "DIGFile::ComputeArrayNoOfItems\n");\r
742 #endif\r
743
744   int Count = MainHeader.Channels * 
745               MainHeader.Dimensions.x *
746               MainHeader.Dimensions.y *
747               MainHeader.Dimensions.z;
748
749   switch(MainHeader.ValueType) {
750   case DIGValueType_REAL:
751     return Count;
752
753   case DIGValueType_COMPLEX:
754     return Count * 2;
755
756   default:
757     return 0; // error
758   }
759 }
760
761
762 int DIGFile::GetArrayNoOfItems(unsigned int* pArrayNoOfItems)
763 {\r
764 #if DIGFILE_DEBUG_LEVEL > 2\r
765   fprintf(stderr, "DIGFile::GetArrayNoOfItems\n");\r
766 #endif\r
767
768   *pArrayNoOfItems = NoOfArrayItems;
769   return 0;
770 }
771
772
773 unsigned int DIGFile::ComputeArrayBufferSize()
774 {\r
775 #if DIGFILE_DEBUG_LEVEL > 2\r
776   fprintf(stderr, "DIGFile::ComputeArrayBufferSize\n");\r
777 #endif\r
778
779   unsigned int Size = NoOfArrayItems;
780
781   switch(MainHeader.DataType) {
782
783   case DIGDataType_BOOL:
784   case DIGDataType_UCHAR:
785   case DIGDataType_CHAR:
786     return Size;
787
788   case DIGDataType_USHORT:
789   case DIGDataType_SHORT:
790     return Size * sizeof(short);
791
792   case DIGDataType_UINT:
793   case DIGDataType_INT:
794     return Size * sizeof(int);
795
796   case DIGDataType_FLOAT:
797     return Size * sizeof(float);
798
799   case DIGDataType_DOUBLE:
800     return Size * sizeof(double);
801
802   default:
803     return 0; // error
804   }
805 }
806
807
808 int DIGFile::GetArrayBufferSize(unsigned int* pArrayBufferSize)
809 {\r
810 #if DIGFILE_DEBUG_LEVEL > 2\r
811   fprintf(stderr, "DIGFile::GetArrayBufferSize\n");\r
812 #endif\r
813
814   *pArrayBufferSize = ArrayBufferSize;
815   return 0;
816 }
817
818
819 #define DIG_FILE_BUFFER_SIZE 1024
820
821 int DIGFile::Close()
822 {\r
823 #if DIGFILE_DEBUG_LEVEL > 2\r
824   fprintf(stderr, "DIGFile::Close\n");\r
825 #endif\r
826
827   if(Dirty) {
828
829     // Append data to ouput file (Header is already there)
830
831     char DataBuffer[DIG_FILE_BUFFER_SIZE];
832     int  ReadByteCount;
833
834     if(WriteXMLHeader() != 0) {\r
835 \r
836 #if DIGFILE_DEBUG_LEVEL > 0\r
837     printf("** Error: unable to write XML header\n");\r
838 #endif
839       return -1;
840     }
841
842     // copy data from temp file to output file
843     rewind(TmpDataFile);
844     while((ReadByteCount = fread(DataBuffer, 1, DIG_FILE_BUFFER_SIZE, TmpDataFile)) > 0) {
845       if(ferror(TmpDataFile) != 0) {\r
846 \r
847 #if DIGFILE_DEBUG_LEVEL > 0\r
848     printf("** Error: error reading temp file\n");\r
849 #endif
850         return -2; // error reading temp file
851       }
852
853       if(fwrite(DataBuffer, 1, ReadByteCount, File) != (unsigned int) ReadByteCount) {\r
854 \r
855 #if DIGFILE_DEBUG_LEVEL > 0\r
856     printf("** Error: error writing  file\n");\r
857 #endif
858         return -3; // error writing  file
859       }
860     }
861   }
862
863   ArraySets.Release();
864
865   if(File == NULL) {\r
866 \r
867 #if DIGFILE_DEBUG_LEVEL > 0\r
868     printf("** Error: attempt to close unopen file\n");\r
869 #endif
870     return -2; // attempt to close unopen file
871   }
872
873   fclose(File);
874
875   File = NULL;
876
877   return 0;
878 }
879
880
881 int DIGFile::AppendArraySet(const char* pType, const char* pTitle, const char* pParameters, const char* pComments)
882 {\r
883 #if DIGFILE_DEBUG_LEVEL > 2\r
884   fprintf(stderr, "DIGFile::AppendArraySet\n");\r
885 #endif\r
886
887   // create new array set header
888   DIGFileArraySetHeader* SetHeader = new DIGFileArraySetHeader(pType, pTitle, pParameters, pComments);
889
890   // create new array set
891   CurrenArraySet = new ArraySet;
892
893   // attach array set header
894   CurrenArraySet->ArraySetHeader = SetHeader;
895   CurrenArraySet->FirstArrayOffset = NoOfArrays;
896
897   // append array set to array set list
898   ArraySets.Append(CurrenArraySet);
899
900   NoOfSets = ArraySets.getLength();
901
902   Dirty = true;
903
904   return 0;
905 }
906
907
908 int DIGFile::AppendArray(unsigned int pEnumNo, const char* pComment, const void* pBuffer)
909 {\r
910 #if DIGFILE_DEBUG_LEVEL > 2\r
911   fprintf(stderr, "DIGFile::AppendArray\n");\r
912 #endif\r
913
914   if(CurrenArraySet == NULL) {\r
915 \r
916 #if DIGFILE_DEBUG_LEVEL > 0\r
917     printf("** Error: no array set selected\n");\r
918 #endif
919     return -1; // no array set selected
920   }
921
922   DIGFileArrayHeader* ArrayHeader = new DIGFileArrayHeader(pEnumNo, pComment);
923
924   // append to array list
925   CurrenArraySet->Append(ArrayHeader);
926
927   // append data to temp file
928   if(WriteArrayData(TmpDataFile, pBuffer) != 0) {\r
929 \r
930 #if DIGFILE_DEBUG_LEVEL > 0\r
931     printf("** Error: writing data\n");\r
932 #endif
933     return -2;
934   }
935
936   NoOfArrays++;
937
938   Dirty = true;
939
940   return 0;
941 }
942
943
944 // returns number of array sets in DIG file
945
946 int DIGFile::GetNoOfArraySets(unsigned int* pNoOfArraySets)
947 {\r
948 #if DIGFILE_DEBUG_LEVEL > 2\r
949   fprintf(stderr, "DIGFile::GetNoOfArraySets\n");\r
950 #endif\r
951
952   *pNoOfArraySets = ArraySets.getLength();
953   return 0;
954 }
955
956
957 // returns number of arrays in current array set
958
959 int DIGFile::GetNoOfArrays(unsigned int* pNoOfArrays)
960 {\r
961 #if DIGFILE_DEBUG_LEVEL > 2\r
962   fprintf(stderr, "DIGFile::GetNoOfArrays\n");\r
963 #endif\r
964
965   if(CurrenArraySet == NULL) {\r
966 \r
967 #if DIGFILE_DEBUG_LEVEL > 0\r
968     printf("** Error: no array set selected\n");\r
969 #endif
970     return -1; // no array set selected
971   }
972   *pNoOfArrays = CurrenArraySet->getLength();
973   return 0;
974 }
975
976 // returns array set header of selected array set
977 /*
978 int DIGFile::GetArraySetHeader(DIGFileArraySetHeader** SetHeader)
979 {
980   *SetHeader = CurrenArraySet->ArraySetHeader;
981   return 0;
982 }
983 */
984
985 // returns array header of selected array
986
987 /*
988 int DIGFile::GetArrayHeader(DIGFileArrayHeader** ArrayHeader)
989 {
990   *ArrayHeader = CurrentArrayHeader;
991   return 0;
992 }
993 */
994
995 int DIGFile::GetArraySetType(const char** pType)
996 {\r
997 #if DIGFILE_DEBUG_LEVEL > 2\r
998   fprintf(stderr, "DIGFile::GetArraySetType\n");\r
999 #endif\r
1000
1001   if(CurrenArraySet == NULL) {\r
1002 \r
1003 #if DIGFILE_DEBUG_LEVEL > 0\r
1004     printf("** Error: no array set selected\n");\r
1005 #endif
1006     return -1; // no array set selected
1007   }
1008
1009   *pType = CurrenArraySet->ArraySetHeader->Type.Get();
1010   return 0;
1011 }
1012
1013
1014 int DIGFile::GetArraySetTitle(const char** pTitle) 
1015 {\r
1016 #if DIGFILE_DEBUG_LEVEL > 2\r
1017   fprintf(stderr, "DIGFile::GetArraySetTitle\n");\r
1018 #endif\r
1019
1020   if(CurrenArraySet == NULL) {\r
1021 \r
1022 #if DIGFILE_DEBUG_LEVEL > 0\r
1023     printf("** Error: no array set selected\n");\r
1024 #endif
1025     return -1; // no array set selected
1026   }
1027
1028   *pTitle = CurrenArraySet->ArraySetHeader->Title.Get();
1029   return 0;
1030 }
1031
1032
1033 int DIGFile::GetArraySetParameters(const char** pParameters)
1034 {\r
1035 #if DIGFILE_DEBUG_LEVEL > 2\r
1036   fprintf(stderr, "DIGFile::GetArraySetParameters\n");\r
1037 #endif\r
1038
1039   if(CurrenArraySet == NULL) {\r
1040 \r
1041 #if DIGFILE_DEBUG_LEVEL > 0\r
1042     printf("** Error: no array set selected\n");\r
1043 #endif
1044     return -1; // no array set selected
1045   }
1046
1047   *pParameters = CurrenArraySet->ArraySetHeader->Parameters.Get();
1048   return 0;
1049 }
1050
1051
1052 int DIGFile::GetArraySetComment(const char** pComment)
1053 {\r
1054 #if DIGFILE_DEBUG_LEVEL > 2\r
1055   fprintf(stderr, "DIGFile::GetArraySetComment\n");\r
1056 #endif\r
1057
1058   if(CurrenArraySet == NULL) {\r
1059 \r
1060 #if DIGFILE_DEBUG_LEVEL > 0\r
1061     printf("** Error: no array set selected\n");\r
1062 #endif
1063     return -1; // no array set selected
1064   }
1065
1066   *pComment = CurrenArraySet->ArraySetHeader->Comment.Get();
1067   return 0;
1068 }
1069
1070
1071 int DIGFile::GetArrayEnumNo(unsigned int* pEnumNo)
1072 {\r
1073 #if DIGFILE_DEBUG_LEVEL > 2\r
1074   fprintf(stderr, "DIGFile::GetArrayEnumNo\n");\r
1075 #endif\r
1076
1077   if(CurrenArraySet == NULL) {\r
1078 \r
1079 #if DIGFILE_DEBUG_LEVEL > 0\r
1080     printf("** Error: no array set selected\n");\r
1081 #endif
1082     return -1; // no array set selected
1083   }
1084
1085   *pEnumNo = CurrentArrayHeader->EnumNo;
1086   return 0;
1087 }
1088
1089
1090 int DIGFile::GetArrayComment(const char** pComment)
1091 {\r
1092 #if DIGFILE_DEBUG_LEVEL > 2\r
1093   fprintf(stderr, "DIGFile::GetArrayComment\n");\r
1094 #endif\r
1095
1096   if(CurrenArraySet == NULL) {\r
1097 \r
1098 #if DIGFILE_DEBUG_LEVEL > 0\r
1099     printf("** Error: no array set selected\n");\r
1100 #endif
1101     return -1; // no array set selected
1102   }
1103
1104   *pComment = CurrentArrayHeader->Comment.Get();
1105   return 0;
1106 }
1107
1108
1109 // selects array set
1110
1111 int DIGFile::SelectArraySet(unsigned int No)
1112 {\r
1113 #if DIGFILE_DEBUG_LEVEL > 2\r
1114   fprintf(stderr, "DIGFile::SelectArraySet\n");\r
1115 #endif\r
1116
1117   CurrentArrayHeader = NULL;
1118   return ArraySets.getArraySet(&CurrenArraySet, No);
1119 }
1120
1121
1122 // selects array from current array set
1123
1124 int DIGFile::SelectArray(unsigned int No)
1125 {\r
1126 #if DIGFILE_DEBUG_LEVEL > 2\r
1127   fprintf(stderr, "DIGFile::SelectArray\n");\r
1128 #endif\r
1129
1130   if(CurrenArraySet == NULL) {\r
1131 \r
1132 #if DIGFILE_DEBUG_LEVEL > 0\r
1133     printf("** Error: no array set selected\n");\r
1134 #endif
1135     return -1;
1136   }
1137
1138   CurrenArrayIndex = CurrenArraySet->FirstArrayOffset + No;
1139
1140   return CurrenArraySet->getArrayHeader(&CurrentArrayHeader, No);
1141 }
1142
1143
1144 // returns data of selected array
1145
1146 int DIGFile::GetArrayData(void* ArrayData)
1147 {\r
1148 #if DIGFILE_DEBUG_LEVEL > 2\r
1149   fprintf(stderr, "DIGFile::GetArrayData\n");\r
1150 #endif\r
1151
1152   if(CurrenArraySet == NULL) {\r
1153 \r
1154 #if DIGFILE_DEBUG_LEVEL > 0\r
1155     printf("** Error: no array set selected\n");\r
1156 #endif
1157     return -1;
1158   }
1159
1160   //type of CurrentArrayOffset changed from unsigned int to off_t
1161   //to enable large file support (>2GB)
1162   //jklukowska, 06/07/2007
1163   off_t CurrenArrayOffset = static_cast <off_t>(XMLHeaderLength) + 
1164                         static_cast <off_t> (CurrenArrayIndex) * static_cast <off_t>(ArrayBufferSize);
1165   //unsigned int CurrenArrayOffset = XMLHeaderLength + CurrenArrayIndex * ArrayBufferSize;
1166
1167   //fseek() changed to fseeko() to enable large file support (>2GB)
1168   //jklukowska, 06/07/2007
1169   if(fseeko(File, CurrenArrayOffset, SEEK_SET) != 0) {
1170   //if(fseek(File, CurrenArrayOffset, SEEK_SET) != 0) {\r
1171 \r
1172 #if DIGFILE_DEBUG_LEVEL > 0\r
1173     printf("** Error: seek error\n");\r
1174 #endif
1175     return -2;
1176   }
1177
1178   switch(MainHeader.DataFormat) {
1179   case DIGDataFormat_ASCII:\r
1180 \r
1181 #if DIGFILE_DEBUG_LEVEL > 0\r
1182     printf("** Error: Reading ASCII DIGFiles not supported\n");\r
1183 #endif
1184     return -1; // Reading ASCII DIGFiles not supported
1185     /*
1186     switch(MainHeader.DataType) {
1187
1188     case DIGDataType_BOOL:
1189       for(i = 0; i < NoOfArrayItems; i++) {
1190         if(((unsigned char*) ArrayData)[i] == 0) {
1191           if(fprintf(f, " 0") < 0) {
1192             return -1; // error
1193           }
1194         }
1195         else {
1196           if(fprintf(f, " 1") < 0) {
1197             return -1; // error
1198           }
1199         }
1200       }
1201       break;
1202
1203     case DIGDataType_UCHAR:
1204       for(i = 0; i < NoOfArrayItems; i++) {
1205         if(fprintf(f, " %u", ((unsigned char*) ArrayData)[i]) < 0) {
1206           return -1; // error
1207         }
1208       }
1209       break;
1210
1211     case DIGDataType_CHAR:
1212       for(i = 0; i < NoOfArrayItems; i++) {
1213         if(fprintf(f, " %i", ((char*) ArrayData)[i]) < 0) {
1214           return -1; // error
1215         }
1216       }
1217       break;
1218
1219     case DIGDataType_USHORT:
1220       for(i = 0; i < NoOfArrayItems; i++) {
1221         if(fprintf(f, " %u", ((unsigned short*) ArrayData)[i]) < 0) {
1222           return -1; // error
1223         }
1224       }
1225       break;
1226
1227     case DIGDataType_SHORT:
1228       for(i = 0; i < NoOfArrayItems; i++) {
1229         if(fprintf(f, " %i", ((short*) ArrayData)[i]) < 0) {
1230           return -1; // error
1231         }
1232       }
1233       break;
1234
1235     case DIGDataType_UINT:
1236       for(i = 0; i < NoOfArrayItems; i++) {
1237         if(fprintf(f, " %u", ((unsigned int*) ArrayData)[i]) < 0) {
1238           return -1; // error
1239         }
1240       }
1241       break;
1242
1243     case DIGDataType_INT:
1244       for(i = 0; i < NoOfArrayItems; i++) {
1245         if(fprintf(f, " %i", ((int*) ArrayData)[i]) < 0) {
1246           return -1; // error
1247         }
1248       }
1249       break;
1250
1251     case DIGDataType_FLOAT:
1252       for(i = 0; i < NoOfArrayItems; i++) {
1253         if(fprintf(f, " %f", ((double) ((float*) ArrayData)[i])) < 0) {
1254           return -1; // error
1255         }
1256       }
1257       break;
1258
1259     case DIGDataType_DOUBLE:
1260       for(i = 0; i < NoOfArrayItems; i++) {
1261         if(fprintf(f, " %f", ((double*) ArrayData)[i]) < 0) {
1262           return -1; // error
1263         }
1264       }
1265       break;
1266
1267     default:
1268       return -2; // error
1269     }
1270     */
1271     break;
1272
1273   case DIGDataFormat_BINARY:
1274
1275     // read data bytes from the file
1276     if(fread(ArrayData, sizeof(char), ArrayBufferSize, File) != ArrayBufferSize) {\r
1277 \r
1278 #if DIGFILE_DEBUG_LEVEL > 0\r
1279     printf("** Error: Reading binary data\n");\r
1280 #endif
1281       return -3;
1282     }
1283
1284     // if file endian different than current machine flip bytes
1285     if(Endian != DIG_ENDIAN) { 
1286
1287       unsigned int i;
1288
1289       switch(MainHeader.DataType) {
1290
1291       // one byte types
1292       case DIGDataType_BOOL:
1293       case DIGDataType_UCHAR:
1294       case DIGDataType_CHAR:
1295         // bytes formats are in right order
1296         break;
1297
1298       // 2 byte types
1299       case DIGDataType_USHORT:
1300       case DIGDataType_SHORT:
1301         for(i = 0; i < NoOfArrayItems; i++) {
1302           short val;
1303
1304           *((char*) &val)       = ((char*) ArrayData)[2 * i + 1];
1305           *(((char*) &val) + 1) = ((char*) ArrayData)[2 * i];
1306
1307           ((short*) ArrayData)[i] = val;
1308         }
1309         break;
1310
1311       // four byte types
1312       case DIGDataType_UINT:
1313       case DIGDataType_INT:
1314       case DIGDataType_FLOAT:
1315         for(i = 0; i < NoOfArrayItems; i++) {
1316           int val;
1317
1318           *((char*) &val)       = ((char*) ArrayData)[4 * i + 3];
1319           *(((char*) &val) + 1) = ((char*) ArrayData)[4 * i + 2];
1320           *(((char*) &val) + 2) = ((char*) ArrayData)[4 * i + 1];
1321           *(((char*) &val) + 3) = ((char*) ArrayData)[4 * i];
1322
1323           ((int*) ArrayData)[i] = val;
1324         }
1325         break;
1326
1327       // eight byte types
1328       case DIGDataType_DOUBLE:
1329         for(i = 0; i < NoOfArrayItems; i++) {
1330           double val;
1331
1332           *((char*) &val)       = ((char*) ArrayData)[8 * i + 7];
1333           *(((char*) &val) + 1) = ((char*) ArrayData)[8 * i + 6];
1334           *(((char*) &val) + 2) = ((char*) ArrayData)[8 * i + 5];
1335           *(((char*) &val) + 3) = ((char*) ArrayData)[8 * i + 4];
1336           *(((char*) &val) + 4) = ((char*) ArrayData)[8 * i + 3];
1337           *(((char*) &val) + 5) = ((char*) ArrayData)[8 * i + 2];
1338           *(((char*) &val) + 6) = ((char*) ArrayData)[8 * i + 1];
1339           *(((char*) &val) + 7) = ((char*) ArrayData)[8 * i];
1340
1341           ((double*) ArrayData)[i] = val;
1342         }
1343         break;
1344
1345       default:\r
1346 \r
1347 #if DIGFILE_DEBUG_LEVEL > 0\r
1348     printf("** Error: unknown data type\n");\r
1349 #endif
1350         return -2; // error
1351       }
1352     }
1353     break;
1354
1355   default:\r
1356 \r
1357 #if DIGFILE_DEBUG_LEVEL > 0\r
1358     printf("** Error: unknown data format\n");\r
1359 #endif
1360     return -3; // error
1361   }
1362
1363   return 0;
1364 }
1365
1366
1367 int DIGFile::WriteArrayData(FILE* f, const void* ArrayData)
1368 {\r
1369 #if DIGFILE_DEBUG_LEVEL > 2\r
1370   fprintf(stderr, "DIGFile::WriteArrayData\n");\r
1371 #endif\r
1372
1373   unsigned int i;
1374
1375   switch(MainHeader.DataFormat) {
1376   case DIGDataFormat_ASCII:
1377     switch(MainHeader.DataType) {
1378
1379     case DIGDataType_BOOL:
1380       for(i = 0; i < NoOfArrayItems; i++) {
1381         if(((unsigned char*) ArrayData)[i] == 0) {
1382           if(fprintf(f, " 0") < 0) {\r
1383 \r
1384 #if DIGFILE_DEBUG_LEVEL > 0\r
1385             printf("** Error: writing data\n");\r
1386 #endif
1387             return -1; // error
1388           }
1389         }
1390         else {
1391           if(fprintf(f, " 1") < 0) {\r
1392 \r
1393 #if DIGFILE_DEBUG_LEVEL > 0\r
1394             printf("** Error: writing data\n");\r
1395 #endif
1396             return -1; // error
1397           }
1398         }
1399       }
1400       break;
1401
1402     case DIGDataType_UCHAR:
1403       for(i = 0; i < NoOfArrayItems; i++) {
1404         if(fprintf(f, " %u", ((unsigned char*) ArrayData)[i]) < 0) {\r
1405 \r
1406 #if DIGFILE_DEBUG_LEVEL > 0\r
1407             printf("** Error: writing data\n");\r
1408 #endif
1409           return -1; // error
1410         }
1411       }
1412       break;
1413
1414     case DIGDataType_CHAR:
1415       for(i = 0; i < NoOfArrayItems; i++) {
1416         if(fprintf(f, " %i", ((char*) ArrayData)[i]) < 0) {\r
1417 \r
1418 #if DIGFILE_DEBUG_LEVEL > 0\r
1419             printf("** Error: writing data\n");\r
1420 #endif
1421           return -1; // error
1422         }
1423       }
1424       break;
1425
1426     case DIGDataType_USHORT:
1427       for(i = 0; i < NoOfArrayItems; i++) {
1428         if(fprintf(f, " %u", ((unsigned short*) ArrayData)[i]) < 0) {\r
1429 \r
1430 #if DIGFILE_DEBUG_LEVEL > 0\r
1431             printf("** Error: writing data\n");\r
1432 #endif
1433           return -1; // error
1434         }
1435       }
1436       break;
1437
1438     case DIGDataType_SHORT:
1439       for(i = 0; i < NoOfArrayItems; i++) {
1440         if(fprintf(f, " %i", ((short*) ArrayData)[i]) < 0) {\r
1441 \r
1442 #if DIGFILE_DEBUG_LEVEL > 0\r
1443             printf("** Error: writing data\n");\r
1444 #endif
1445           return -1; // error
1446         }
1447       }
1448       break;
1449
1450     case DIGDataType_UINT:
1451       for(i = 0; i < NoOfArrayItems; i++) {
1452         if(fprintf(f, " %u", ((unsigned int*) ArrayData)[i]) < 0) {\r
1453 \r
1454 #if DIGFILE_DEBUG_LEVEL > 0\r
1455             printf("** Error: writing data\n");\r
1456 #endif
1457           return -1; // error
1458         }
1459       }
1460       break;
1461
1462     case DIGDataType_INT:
1463       for(i = 0; i < NoOfArrayItems; i++) {
1464         if(fprintf(f, " %i", ((int*) ArrayData)[i]) < 0) {\r
1465 \r
1466 #if DIGFILE_DEBUG_LEVEL > 0\r
1467             printf("** Error: writing data\n");\r
1468 #endif
1469           return -1; // error
1470         }
1471       }
1472       break;
1473
1474     case DIGDataType_FLOAT:
1475       for(i = 0; i < NoOfArrayItems; i++) {
1476         if(fprintf(f, " %f", ((double) ((float*) ArrayData)[i])) < 0) {\r
1477 \r
1478 #if DIGFILE_DEBUG_LEVEL > 0\r
1479             printf("** Error: writing data\n");\r
1480 #endif
1481           return -1; // error
1482         }
1483       }
1484       break;
1485
1486     case DIGDataType_DOUBLE:
1487       for(i = 0; i < NoOfArrayItems; i++) {
1488         if(fprintf(f, " %f", ((double*) ArrayData)[i]) < 0) {\r
1489 \r
1490 #if DIGFILE_DEBUG_LEVEL > 0\r
1491             printf("** Error: writing data\n");\r
1492 #endif
1493           return -1; // error
1494         }
1495       }
1496       break;
1497
1498     default:\r
1499 \r
1500 #if DIGFILE_DEBUG_LEVEL > 0\r
1501       printf("** Error: unknown data type\n");\r
1502 #endif
1503       return -2; // error
1504     }
1505     break;
1506
1507   case DIGDataFormat_BINARY:
1508     // write data in curent machine endian
1509     if(fwrite(ArrayData, sizeof(char),ArrayBufferSize, f) != ArrayBufferSize) {
1510       return -1; // error
1511     }
1512     /*
1513     switch(MainHeader.DataType) {
1514
1515     case DIGDataType_BOOL:
1516       if(fwrite(ArrayData, sizeof(char), NoOfArrayItems, f) != NoOfArrayItems) {
1517         return -1; // error
1518       }
1519       break;
1520
1521     case DIGDataType_UCHAR:
1522       if(fwrite(ArrayData, sizeof(unsigned char), NoOfArrayItems, f) != NoOfArrayItems) {
1523         return -1; // error
1524       }
1525       break;
1526
1527     case DIGDataType_CHAR:
1528       if(fwrite(ArrayData, sizeof(char), NoOfArrayItems, f) != NoOfArrayItems) {
1529         return -1; // error
1530       }
1531       break;
1532
1533     case DIGDataType_USHORT:
1534       if(fwrite(ArrayData, sizeof(unsigned short), NoOfArrayItems, f) != NoOfArrayItems) {
1535         return -1; // error
1536       }
1537       break;
1538
1539     case DIGDataType_SHORT:
1540       if(fwrite(ArrayData, sizeof(short), NoOfArrayItems, f) != NoOfArrayItems) {
1541         return -1; // error
1542       }
1543       break;
1544
1545     case DIGDataType_UINT:
1546       if(fwrite(ArrayData, sizeof(unsigned int), NoOfArrayItems, f) != NoOfArrayItems) {
1547         return -1; // error
1548       }
1549       break;
1550
1551     case DIGDataType_INT:
1552       if(fwrite(ArrayData, sizeof(int), NoOfArrayItems, f) != NoOfArrayItems) {
1553         return -1; // error
1554       }
1555       break;
1556
1557     case DIGDataType_FLOAT:
1558       if(fwrite(ArrayData, sizeof(float), NoOfArrayItems, f) != NoOfArrayItems) {
1559         return -1; // error
1560       }
1561       break;
1562
1563     case DIGDataType_DOUBLE:
1564       if(fwrite(ArrayData, sizeof(double), NoOfArrayItems, f) != NoOfArrayItems) {
1565         return -1; // error
1566       }
1567       break;
1568
1569     default:
1570       return -2; // error
1571     }
1572     */
1573     break;
1574
1575
1576   default:\r
1577 #if DIGFILE_DEBUG_LEVEL > 0\r
1578     printf("** Error: unknown data format\n");\r
1579 #endif
1580     return -3; // error
1581   }
1582
1583   return 0;
1584 }
1585
1586
1587 //////////////////////////////////////////////////////////////////////////////////////
1588 //
1589 // XML Parsing functions
1590 //
1591 //////////////////////////////////////////////////////////////////////////////////////
1592
1593 int DIGFile::GetUintAttributeValue(DOMElement* Element, const XMLCh* AttributeName, unsigned int* value)
1594 {\r
1595 #if DIGFILE_DEBUG_LEVEL > 2\r
1596   fprintf(stderr, "DIGFile::GetUintAttributeValue\n");\r
1597 #endif\r
1598
1599   const XMLCh* AttributeValueXMLStr;
1600   const char* AttributeValueStr;
1601   AttributeValueXMLStr = Element->getAttribute(AttributeName);
1602
1603   AttributeValueStr = XMLString::transcode(AttributeValueXMLStr);
1604
1605   //delete AttributeValueXMLStr;
1606
1607   if((*value = atoi(AttributeValueStr)) < 0) {\r
1608 \r
1609 #if DIGFILE_DEBUG_LEVEL > 0\r
1610     printf("** Error: invalid unsigned int value\n");\r
1611 #endif
1612     return -1;
1613   }
1614
1615   /* // direct conversion ?
1616
1617   bool XMLString::textToBin(const XMLCh *const toConvert, 
1618                                          unsigned int & toFill ) [static] 
1619   */
1620
1621   return 0; // succes
1622 }
1623
1624 int DIGFile::GetIntAttributeValue(DOMElement* Element, const XMLCh* AttributeName, int* value)
1625 {\r
1626 #if DIGFILE_DEBUG_LEVEL > 2\r
1627   fprintf(stderr, "DIGFile::GetIntAttributeValue\n");\r
1628 #endif\r
1629
1630   const XMLCh* AttributeValueXMLStr;
1631   const char* AttributeValueStr;
1632   AttributeValueXMLStr = Element->getAttribute(AttributeName);
1633
1634   AttributeValueStr = XMLString::transcode(AttributeValueXMLStr);
1635
1636   //delete AttributeValueXMLStr;
1637
1638   *value = atoi(AttributeValueStr);
1639
1640   /* // direct conversion ?
1641
1642   bool XMLString::textToBin(const XMLCh *const toConvert, 
1643                                          unsigned int & toFill ) [static] 
1644   */
1645
1646   return 0; // succes
1647 }
1648
1649 int DIGFile::GetDoubleAttributeValue(DOMElement* Element, const XMLCh* AttributeName, double* value)
1650 {\r
1651 #if DIGFILE_DEBUG_LEVEL > 2\r
1652   fprintf(stderr, "DIGFile::GetDoubleAttributeValue\n");\r
1653 #endif\r
1654
1655   const XMLCh* AttributeValueXMLStr;
1656   const char* AttributeValueStr;
1657   AttributeValueXMLStr = Element->getAttribute(AttributeName);
1658
1659   AttributeValueStr = XMLString::transcode(AttributeValueXMLStr);
1660
1661   //delete AttributeValueXMLStr;
1662
1663   *value = atof(AttributeValueStr);
1664
1665   /* // direct conversion ?
1666
1667   bool XMLString::textToBin(const XMLCh *const toConvert, 
1668                                          unsigned int & toFill ) [static] 
1669   */
1670
1671   return 0; // succes
1672 }
1673
1674
1675 int DIGFile::GetTxtAttributeValue(DOMElement* Element, const XMLCh* AttributeName, char** Text)
1676 {\r
1677 #if DIGFILE_DEBUG_LEVEL > 2\r
1678   fprintf(stderr, "DIGFile::GetTxtAttributeValue\n");\r
1679 #endif\r
1680
1681   const XMLCh* AttributeValueXMLStr;
1682
1683   AttributeValueXMLStr = Element->getAttribute(AttributeName);
1684
1685   *Text = XMLString::transcode(AttributeValueXMLStr);
1686
1687   return 0; // succes
1688 }
1689
1690
1691 int DIGFile::GetElementText(DOMElement* Element, char** Text)
1692 {\r
1693 #if DIGFILE_DEBUG_LEVEL > 2\r
1694   fprintf(stderr, "DIGFile::GetElementText\n");\r
1695 #endif\r
1696
1697   // get children 
1698   DOMNodeList* Children = Element->getChildNodes();
1699
1700   // search for first instance of text node
1701   for(unsigned int i = 0; i < Children->getLength(); i++) {
1702     //const XMLCh* CXMLStr = Children->item(i)->getNodeName();
1703     if(Children->item(i)->getNodeType() == DOMNode::TEXT_NODE) { 
1704       const XMLCh* CXMLStr = Children->item(i)->getNodeValue(); 
1705       *Text = XMLString::transcode(CXMLStr);
1706       return 0;
1707     }
1708   }\r
1709 \r
1710 #if DIGFILE_DEBUG_LEVEL > 0\r
1711     printf("** Error: Parsing - text node  not found\n");\r
1712 #endif
1713   return -1; // text node  not found
1714
1715   /*
1716   DOMNodeList* TextList = CommentsElement->getElementsByTagName(XMLString::transcode("text"));
1717   DOMNode* TextNode = TextList->item(0);
1718   const XMLCh* TextXMLStr = TextNode->getNodeValue();
1719   char* c = XMLString::transcode(TextXMLStr);
1720   */
1721 }
1722
1723
1724 int DIGFile::SymbolToCode(char* Symbol, const char** SymbolTable, int NumberOfSymbols)
1725 {\r
1726 #if DIGFILE_DEBUG_LEVEL > 2\r
1727   fprintf(stderr, "DIGFile::SymbolToCode\n");\r
1728 #endif\r
1729
1730         for (int num = 0; num < NumberOfSymbols; num++) {
1731                 if(strcmp(SymbolTable[num], Symbol) == 0) {
1732                         return num;
1733                 }  
1734         } \r
1735   \r
1736 #if DIGFILE_DEBUG_LEVEL > 0\r
1737     printf("** Error: Parsing - symbol not found\n");\r
1738 #endif
1739   return -1; // symbol not found
1740 }
1741
1742 int DIGFile::InitParser2(const MemBufInputSource& memBufIS)
1743 {\r
1744 #if DIGFILE_DEBUG_LEVEL > 2\r
1745   fprintf(stderr, "DIGFile::InitParser2\n");\r
1746 #endif\r
1747
1748         // Initialization
1749         try {
1750                 XMLPlatformUtils::Initialize();
1751         }  // try
1752         catch(const XMLException &toCatch) {
1753                 std::cerr << "Error during Xerces-c Initialization.\n"
1754                         << "  Exception message:"
1755                         << StrX(toCatch.getMessage()) << std::endl;
1756                 return 1;
1757         }  // catch
1758
1759         //  Create our parser, then attach an error handler to the parser.
1760         //  The parser will call back to methods of the ErrorHandler if it
1761         //  discovers errors during the course of parsing the XML document.
1762         parser = new XercesDOMParser;
1763         parser->setValidationScheme(XercesDOMParser::Val_Auto);
1764         parser->setDoNamespaces(false);
1765         parser->setDoSchema(true);
1766         parser->setValidationSchemaFullChecking(true);
1767         parser->setCreateEntityReferenceNodes(true);
1768         errReporter = new DOMTreeErrorReporter();
1769         parser->setErrorHandler(errReporter);
1770
1771         //  Parse the XML file, catching any XML exceptions that might propogate
1772         //  out of it.
1773         try {
1774                 parser->parse(memBufIS);
1775         }  // try
1776         catch (const XMLException& e) {         
1777                 std::cerr << "An error occurred during parsing\n   Message: "
1778                         << StrX(e.getMessage()) << std::endl;
1779                 return 2;
1780         }  // catch
1781         catch (const DOMException& e) {
1782                 std::cerr << "A DOM error occurred during parsing\n   DOMException code: "
1783                         << e.code << std::endl;
1784                 return 2;
1785         }  // catch
1786         catch (...) {
1787                 std::cerr << "An error occurred during parsing\n " << std::endl;
1788                 return 1;
1789         }  // catch
1790
1791         Document = ((AbstractDOMParser*)parser)->getDocument();
1792
1793   // get root
1794         RootElement = Document->getDocumentElement();
1795
1796   // get main header node
1797   DOMNodeList* MainHeaderList = RootElement->getElementsByTagName(XMLString::transcode("main_header"));
1798   MainHeaderElement = (DOMElement*) MainHeaderList->item(0);
1799
1800   // get application header node
1801   DOMNodeList* ApplicationHeaderList = RootElement->getElementsByTagName(XMLString::transcode("application_header"));
1802   ApplicationHeaderElement = (DOMElement*) ApplicationHeaderList->item(0);
1803
1804   // get array set header nodes
1805   ArraySetHeaderList = RootElement->getElementsByTagName(XMLString::transcode("array_set_header"));
1806   DIGFileArraySetHeader* ArraySetHeader = new DIGFileArraySetHeader();
1807
1808   // select fisrt array set
1809   GetArraySetHeader(ArraySetHeader, 0);
1810
1811   return 0;
1812 }
1813
1814
1815 int DIGFile::GetMainHeader(DIGFileMainHeader* MainHeader)
1816 {\r
1817 #if DIGFILE_DEBUG_LEVEL > 2\r
1818   fprintf(stderr, "DIGFile::InitParser2\n");\r
1819 #endif\r
1820
1821   char* AttrValStr;
1822
1823   // get header attributes
1824
1825   // get type
1826   char* Type;
1827   if(GetTxtAttributeValue(MainHeaderElement, TypeXMLStr, &Type) != 0) {
1828     // error
1829   }
1830
1831   // get title
1832   char* Title;
1833   if(GetTxtAttributeValue(MainHeaderElement, TitleXMLStr, &Title) != 0) {
1834     // error
1835   }
1836
1837   // get channels
1838   int Channels;
1839   if(GetIntAttributeValue(MainHeaderElement, ChannelsXMLStr, &Channels) != 0) {
1840     // error
1841   }
1842
1843   // get Number of Arrays
1844   int NumberOfArrays;
1845   if(GetIntAttributeValue(MainHeaderElement, NumberOfArraysXMLStr, &NumberOfArrays) != 0) {
1846     // error
1847   }
1848
1849   // get Number of Array Sets
1850   int NumberOfSets;
1851   if(GetIntAttributeValue(MainHeaderElement, NumberOfArraySetsXMLStr, &NumberOfSets) != 0) {
1852     // error
1853   }
1854
1855   // get Endian
1856   if(GetTxtAttributeValue(MainHeaderElement, EndianXMLStr, &AttrValStr) != 0) {
1857     // error
1858   }
1859   
1860   if((Endian = (DIGEndian) SymbolToCode(AttrValStr, DIGEndianStr, DIGEndianSize)) < 0) {
1861     // error
1862   }
1863   
1864   // get Value Type
1865   if(GetTxtAttributeValue(MainHeaderElement, ValueTypeXMLStr, &AttrValStr) != 0) {
1866     // error
1867   }
1868
1869
1870   DIGValueType ValueType;
1871   if((ValueType = (DIGValueType) SymbolToCode(AttrValStr, DIGValueTypeStr, DIGValueTypeSize)) < 0) {
1872     // error
1873   }
1874
1875   // get Data Type
1876   if(GetTxtAttributeValue(MainHeaderElement, DataTypeXMLStr, &AttrValStr) != 0) {
1877     // error
1878   }
1879
1880   DIGDataType DataType;
1881   if((DataType = (DIGDataType) SymbolToCode(AttrValStr, DIGDataTypeStr, DIGDataTypeSize)) < 0) {
1882     // error
1883   }
1884
1885   // get Data Format
1886   if(GetTxtAttributeValue(MainHeaderElement, DataFormatXMLStr, &AttrValStr) != 0) {
1887     // error
1888   }
1889
1890   DIGDataFormat DataFormat;
1891   if((DataFormat = (DIGDataFormat) SymbolToCode(AttrValStr, DIGDataFormatStr, DIGDataFormatSize)) < 0) {
1892     // error
1893   }
1894
1895   // get Grid Type
1896   if(GetTxtAttributeValue(MainHeaderElement, GridTypeXMLStr, &AttrValStr) != 0) {
1897     // error
1898   }
1899
1900   DIGGrid Grid;
1901   if((Grid = (DIGGrid) SymbolToCode(AttrValStr, DIGGridStr, DIGGridSize)) < 0) {
1902     // error
1903   }
1904
1905   // get Basis Function
1906   if(GetTxtAttributeValue(MainHeaderElement, BasisFunctionXMLStr, &AttrValStr) != 0) {
1907     // error
1908   }
1909
1910   DIGBasis Basis;
1911   if((Basis = (DIGBasis) SymbolToCode(AttrValStr, DIGBasisStr, DIGBasisSize)) < 0) {
1912     // error
1913   }
1914
1915   // get Unit
1916   if(GetTxtAttributeValue(MainHeaderElement, UnitXMLStr, &AttrValStr) != 0) {
1917     // error
1918   }
1919
1920   DIGUnit Unit;
1921   if((Unit = (DIGUnit) SymbolToCode(AttrValStr, DIGUnitStr, DIGUnitSize)) < 0) {
1922     // error
1923   }
1924
1925   // get Other Unit
1926   char* OtherUnit;
1927   if(GetTxtAttributeValue(MainHeaderElement, OtherUnitXMLStr, &OtherUnit) != 0) {
1928     // error
1929   }
1930
1931   // get other header values
1932   // get comments
1933   // get Comment Element
1934
1935   char* Comment = DIGEmptyStr;
1936
1937   DOMNodeList* CommentsList = MainHeaderElement->getElementsByTagName(CommentsXMLStr);
1938
1939   int tNumC = CommentsList->getLength();
1940   if(tNumC > 0) {
1941
1942     DOMElement* CommentsElement = (DOMElement*) CommentsList->item(0);
1943
1944     // get Comment Text
1945     if(GetElementText(CommentsElement, &Comment) != 0) {
1946       ;// allow empty comments
1947     }
1948   }
1949
1950   DIGDimensions Dimensions;
1951
1952   DOMNodeList* DimensionsList = MainHeaderElement->getElementsByTagName(DimensionsXMLStr);
1953   DOMElement* DimensionsElement = (DOMElement*) DimensionsList->item(0);
1954
1955   // get Dimmension X
1956   if(GetIntAttributeValue(DimensionsElement, DimmensionXXMLStr, &(Dimensions.x)) != 0) {
1957     // error
1958   }
1959
1960   // get Dimmension Y
1961   if(GetIntAttributeValue(DimensionsElement, DimmensionYXMLStr, &(Dimensions.y)) != 0) {
1962     // error
1963   }
1964
1965   // get Dimmension Z
1966   if(GetIntAttributeValue(DimensionsElement, DimmensionZXMLStr, &(Dimensions.z)) != 0) {
1967     // error
1968   }
1969
1970   // get Sampling Rate X
1971   DIGSampling SamplingX;
1972
1973   DOMNodeList* SamplingXList = MainHeaderElement->getElementsByTagName(SamplingRateXXMLStr);
1974   DOMElement* SamplingXElement = (DOMElement*) SamplingXList->item(0);
1975
1976
1977   if(GetDoubleAttributeValue(SamplingXElement, DimmensionXXMLStr, &(SamplingX.x)) != 0) {
1978     // error
1979   }
1980
1981   if(GetDoubleAttributeValue(SamplingXElement, DimmensionYXMLStr, &(SamplingX.y)) != 0) {
1982     // error
1983   }
1984
1985   if(GetDoubleAttributeValue(SamplingXElement, DimmensionZXMLStr, &(SamplingX.z)) != 0) {
1986     // error
1987   }
1988
1989
1990   // get Sampling Rate Y
1991   DIGSampling SamplingY;
1992
1993   DOMNodeList* SamplingYList = MainHeaderElement->getElementsByTagName(SamplingRateYXMLStr);
1994   DOMElement* SamplingYElement = (DOMElement*) SamplingYList->item(0);
1995
1996
1997   if(GetDoubleAttributeValue(SamplingYElement, DimmensionXXMLStr, &(SamplingY.x)) != 0) {
1998     // error
1999   }
2000
2001   if(GetDoubleAttributeValue(SamplingYElement, DimmensionYXMLStr, &(SamplingY.y)) != 0) {
2002     // error
2003   }
2004
2005   if(GetDoubleAttributeValue(SamplingYElement, DimmensionZXMLStr, &(SamplingY.z)) != 0) {
2006     // error
2007   }
2008
2009   // get Sampling Rate Z
2010   DIGSampling SamplingZ;
2011
2012   DOMNodeList* SamplingZList = MainHeaderElement->getElementsByTagName(SamplingRateZXMLStr);
2013   DOMElement* SamplingZElement = (DOMElement*) SamplingZList->item(0);
2014
2015
2016   if(GetDoubleAttributeValue(SamplingZElement, DimmensionXXMLStr, &(SamplingZ.x)) != 0) {
2017     // error
2018   }
2019
2020   if(GetDoubleAttributeValue(SamplingZElement, DimmensionYXMLStr, &(SamplingZ.y)) != 0) {
2021     // error
2022   }
2023
2024   if(GetDoubleAttributeValue(SamplingZElement, DimmensionZXMLStr, &(SamplingZ.z)) != 0) {
2025     // error
2026   }
2027
2028   NoOfArrays = NumberOfArrays;
2029   NoOfSets = NumberOfSets;
2030
2031   MainHeader->Title.Set(Title);
2032   MainHeader->Type.Set(Type);
2033   MainHeader->Channels = Channels;
2034   //MainHeader->Endian = Endian;
2035   MainHeader->ValueType = ValueType;
2036   MainHeader->DataType = DataType;
2037   MainHeader->DataFormat = DataFormat;
2038   MainHeader->Grid = Grid;
2039   MainHeader->Basis = Basis;
2040   MainHeader->Unit = Unit;
2041   MainHeader->OtherUnit.Set(OtherUnit);
2042   MainHeader->Comment.Set(Comment);
2043   MainHeader->Dimensions = Dimensions;
2044   MainHeader->SamplingX = SamplingX;
2045   MainHeader->SamplingY = SamplingY;
2046   MainHeader->SamplingZ = SamplingZ;
2047   return 0;
2048 }
2049
2050
2051 int DIGFile::ParseApplicationHeader() {\r
2052 #if DIGFILE_DEBUG_LEVEL > 2\r
2053   fprintf(stderr, "DIGFile::ParseApplicationHeader\n");\r
2054 #endif
2055   return 0;
2056 }
2057
2058
2059 int DIGFile::GetArraySetHeader(DIGFileArraySetHeader* ArraySetHeader, unsigned int index)
2060 {\r
2061 #if DIGFILE_DEBUG_LEVEL > 2\r
2062   fprintf(stderr, "DIGFile::GetArraySetHeader\n");\r
2063 #endif\r
2064
2065   if(index > ArraySetHeaderList->getLength()) {\r
2066 \r
2067 #if DIGFILE_DEBUG_LEVEL > 0\r
2068     printf("** Error: index out of range\n");\r
2069 #endif
2070     // error index out of range
2071   }
2072
2073   DOMElement* ArraySetHeaderElement = (DOMElement*) ArraySetHeaderList->item(index);
2074
2075   // get Array Set Header Attributes
2076
2077   // get type
2078   char* Type;
2079   if(GetTxtAttributeValue(ArraySetHeaderElement, TypeXMLStr, &Type) != 0) {
2080     // error
2081   }
2082
2083   // get title
2084   char* Title;
2085   if(GetTxtAttributeValue(ArraySetHeaderElement, TitleXMLStr, &Title) != 0) {
2086     // error
2087   }
2088
2089   // get Comment Element
2090   char* Comment = DIGEmptyStr;
2091
2092   DOMNodeList* CommentsList = ArraySetHeaderElement->getElementsByTagName(CommentsXMLStr);
2093
2094   int tNumC = CommentsList->getLength();
2095   if(tNumC > 0) {
2096
2097     DOMElement* CommentsElement = (DOMElement*) CommentsList->item(0);
2098
2099     // get Comment Text
2100     if(GetElementText(CommentsElement, &Comment) != 0) {
2101       ;// allow empty comments
2102     }
2103   }
2104
2105   // get Parameters Element
2106   DOMNodeList* ParametersList = ArraySetHeaderElement->getElementsByTagName(ParametersXMLStr);
2107   DOMElement* ParametersElement = (DOMElement*) ParametersList->item(0);
2108
2109   // get Parameters Text
2110   char* Parameters;
2111   if(GetElementText(ParametersElement, &Parameters) != 0) {
2112     // error
2113     Parameters = DIGEmptyStr;
2114   }
2115
2116   ArraySetHeader->Type.Set(Type);
2117   ArraySetHeader->Title.Set(Title);
2118   ArraySetHeader->Comment.Set(Comment);
2119   ArraySetHeader->Parameters.Set(Parameters);
2120
2121   // load array list
2122   ArrayHeaderList = ArraySetHeaderElement->getElementsByTagName(ArrayHeaderXMLStr);
2123
2124   return 0;
2125 }
2126
2127
2128 int DIGFile::GetArrayHeader(DIGFileArrayHeader* ArrayHeader, unsigned int index)
2129 {\r
2130 #if DIGFILE_DEBUG_LEVEL > 2\r
2131   fprintf(stderr, "DIGFile::GetArrayHeader\n");\r
2132 #endif\r
2133
2134   if(index > ArrayHeaderList->getLength()) {
2135     // error index out of range
2136   }
2137
2138   DOMElement* ArrayHeaderElement = (DOMElement*) ArrayHeaderList->item(index);
2139
2140   // get Array Header Attributes
2141
2142   // get Enumeration Number
2143   int EnumNo;
2144
2145   if(GetIntAttributeValue(ArrayHeaderElement, EnumerationNumberXMLStr, &EnumNo) != 0) {
2146     return -1; // error
2147   }
2148
2149   // get Comment Element
2150   char* Comment = DIGEmptyStr;
2151
2152   DOMNodeList* CommentsList = ArrayHeaderElement->getElementsByTagName(CommentsXMLStr);
2153
2154   int tNumC = CommentsList->getLength();
2155   if(tNumC > 0) {
2156
2157     DOMElement* CommentsElement = (DOMElement*) CommentsList->item(0);
2158
2159     // get Comment Text
2160     if(GetElementText(CommentsElement, &Comment) != 0) {
2161       ;// allow empty comments
2162     }
2163   }
2164
2165   ArrayHeader->EnumNo = EnumNo;
2166   ArrayHeader->Comment.Set(Comment);
2167
2168   return 0;
2169 }
2170
2171
2172 int DIGFile::ResetParser()
2173 {\r
2174 #if DIGFILE_DEBUG_LEVEL > 2\r
2175   fprintf(stderr, "DIGFile::ResetParser\n");\r
2176 #endif\r
2177
2178         //  Clean up the error handler. The parser does not adopt handlers
2179         //  since they could be many objects or one object installed for multiple
2180         //  handlers.
2181         delete errReporter;
2182
2183         //  Delete the parser itself.  Must be done prior to calling Terminate, below.
2184         delete parser;
2185
2186         // And call the termination method
2187         XMLPlatformUtils::Terminate();
2188
2189         return 0; 
2190 }
2191
2192
2193 int DIGFile::ParseXML(const char* MemBuf)
2194 {\r
2195 #if DIGFILE_DEBUG_LEVEL > 2\r
2196   fprintf(stderr, "DIGFile::ParseXML\n");\r
2197 #endif\r
2198
2199   static const char*  gMemBufId = "XMLHeader";
2200
2201   MemBufInputSource* memBufIS = new MemBufInputSource
2202   (
2203     (const XMLByte*)MemBuf,
2204     strlen(MemBuf),
2205     gMemBufId,
2206     false
2207   );
2208
2209   // initialize parser and pharse root
2210   if(InitParser2(*memBufIS) != 0) {\r
2211 \r
2212 #if DIGFILE_DEBUG_LEVEL > 0\r
2213     printf("** Error: initializing parser and gtting doument root\n");\r
2214 #endif\r
2215     return -1; // error
2216   }
2217
2218   // parse main header
2219   if(GetMainHeader(&MainHeader)) {\r
2220 \r
2221 #if DIGFILE_DEBUG_LEVEL > 0\r
2222     printf("** Error: parsing main header\n");\r
2223 #endif
2224     return -1; // error
2225   }
2226
2227   // parse application header
2228   if(ParseApplicationHeader()) {\r
2229 \r
2230 #if DIGFILE_DEBUG_LEVEL > 0\r
2231     printf("** Error: parsing application header\n");\r
2232 #endif
2233     return -1; // error
2234   }
2235
2236   // parse arrayset headers
2237   unsigned int NumberOfArrays = 0;
2238
2239   for(unsigned int i = 0; i < ArraySetHeaderList->getLength(); i++) {
2240
2241     // create new array set
2242     ArraySet* ASet = new ArraySet;
2243     ASet->FirstArrayOffset = NumberOfArrays;
2244
2245     // create new array set header
2246     ASet->ArraySetHeader = new DIGFileArraySetHeader;
2247
2248     // load it with data
2249     if(GetArraySetHeader(ASet->ArraySetHeader, i) != 0) {\r
2250 \r
2251 #if DIGFILE_DEBUG_LEVEL > 0\r
2252     printf("** Error: parsing array set header\n");\r
2253 #endif
2254       return -1; // error
2255     }
2256
2257     // append arrays
2258     for(unsigned int j = 0; j < ArrayHeaderList->getLength(); j++) {
2259
2260       // create new array header
2261       DIGFileArrayHeader* ArrayHeader = new DIGFileArrayHeader;
2262
2263       // load it with data
2264       if(GetArrayHeader(ArrayHeader, j) != 0) {\r
2265 \r
2266 #if DIGFILE_DEBUG_LEVEL > 0\r
2267     printf("** Error: parsing array header\n");\r
2268 #endif
2269         return -1; //error
2270       }
2271
2272       // append to array list
2273       ASet->Append(ArrayHeader);
2274
2275       NumberOfArrays++;
2276     }
2277
2278     // append array set to array set list
2279     ArraySets.Append(ASet);
2280   }
2281
2282   if(NumberOfArrays != NoOfArrays) {\r
2283 \r
2284 #if DIGFILE_DEBUG_LEVEL > 0\r
2285     printf("** Error: invalid number of arrays\n");\r
2286 #endif
2287     return -1; // error
2288   }
2289
2290   ResetParser();
2291    
2292   return 0;
2293 }
2294
2295 //////////////////////////////////////////////////////////////////////////////////////
2296 //
2297 // XML writing functions
2298 //
2299 //////////////////////////////////////////////////////////////////////////////////////
2300
2301 int DIGFile::WriteXMLHeader()
2302 {\r
2303 #if DIGFILE_DEBUG_LEVEL > 2\r
2304   fprintf(stderr, "DIGFile::WriteXMLHeader\n");\r
2305 #endif\r
2306
2307   // create XML buffer
2308   XMLFormatTarget* mymFormTarget = new MemBufFormatTarget(4*1023);
2309
2310
2311   // create DOMDocument
2312   CreateRootElement();
2313
2314   if(CreateMainHeader(&MainHeader) != 0) {\r
2315 \r
2316 #if DIGFILE_DEBUG_LEVEL > 0\r
2317     printf("** Error: creating main header\n");\r
2318 #endif
2319     return -1;
2320   }
2321
2322   if(CreateApplicationHeader() != 0) {\r
2323 \r
2324 #if DIGFILE_DEBUG_LEVEL > 0\r
2325     printf("** Error: creating application header\n");\r
2326 #endif
2327     return -2;
2328   }
2329
2330   // step through array sets
2331   for(unsigned int i = 0; i < ArraySets.getLength(); i++) {
2332
2333     ArraySet* ASet;
2334
2335     // get array set from set list
2336     if(ArraySets.getArraySet(&ASet, i) != 0) {\r
2337 \r
2338 #if DIGFILE_DEBUG_LEVEL > 0\r
2339     printf("** Error: creating array set header\n");\r
2340 #endif
2341       return -3; // error
2342     }
2343
2344     // write array set header
2345     AppendArraySetHeader(ASet->ArraySetHeader); 
2346
2347     // step through arrays
2348     for(unsigned int j = 0; j < ASet->getLength(); j++) {
2349
2350       DIGFileArrayHeader* ArrayHeader;
2351
2352       // get array header
2353       ASet->getArrayHeader(&ArrayHeader, j);
2354
2355       // write array header
2356       AppendArrayHeader(ArrayHeader);
2357     }
2358   }
2359
2360   //WriteSufix();
2361
2362   // serialize 
2363   ///DOMPrintFilter   *myFilter = 0;
2364
2365   try {
2366                 // get a serializer, an instance of DOMWriter (kmr Now DOMLSSerializer)
2367                 XMLCh tempStr[100];
2368                 XMLString::transcode("LS", tempStr, 99);
2369                 DOMImplementation *impl          = DOMImplementationRegistry::getDOMImplementation(tempStr);
2370                 DOMLSSerializer   *theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer();
2371                 DOMConfiguration  *dc            = theSerializer->getDomConfig();
2372                 DOMLSOutput* theOutput = ((DOMImplementationLS*)impl)->createLSOutput();
2373                 theOutput->setByteStream(mymFormTarget);
2374                 
2375                 // set user specified end of line sequence and output encoding
2376                 //theSerializer->setNewLine(gMyEOLSequence);
2377
2378     theSerializer->setNewLine(XMLString::transcode("\x0A"));
2379
2380     static XMLCh* gOutputEncoding = 0;
2381
2382     // kmr theSerializer->setEncoding(gOutputEncoding);
2383     theOutput->setEncoding(gOutputEncoding);
2384     
2385                 // plug in user's own filter
2386     /*
2387                 if(gUseFilter) {
2388                         // even we say to show attribute, but the DOMWriter
2389                         // will not show attribute nodes to the filter as
2390                         // the specs explicitly says that DOMWriter shall
2391                         // NOT show attributes to DOMWriterFilter.
2392                         //
2393                         // so DOMNodeFilter::SHOW_ATTRIBUTE has no effect.
2394                         // same DOMNodeFilter::SHOW_DOCUMENT_TYPE, no effect.
2395                         //
2396                         myFilter = new DOMPrintFilter(DOMNodeFilter::SHOW_ELEMENT   |
2397                                             DOMNodeFilter::SHOW_ATTRIBUTE |
2398                                             DOMNodeFilter::SHOW_DOCUMENT_TYPE
2399                                                                                         );
2400                         theSerializer->setFilter(myFilter);
2401                 }
2402     */
2403
2404                 // plug in user's own error handler
2405                 DOMErrorHandler* myErrorHandler = new DOMPrintErrorHandler();
2406                 dc->setParameter(XMLUni::fgDOMErrorHandler,myErrorHandler);
2407
2408                 // set feature if the serializer supports the feature/mode
2409     
2410     static bool gSplitCdataSections = true;
2411
2412                 if(dc->canSetParameter(XMLUni::fgDOMWRTSplitCdataSections, gSplitCdataSections))
2413                         dc->setParameter(XMLUni::fgDOMWRTSplitCdataSections, gSplitCdataSections);
2414
2415     static bool gDiscardDefaultContent = true;
2416                 
2417                 if(dc->canSetParameter(XMLUni::fgDOMWRTDiscardDefaultContent, gDiscardDefaultContent))
2418                         dc->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, gDiscardDefaultContent);
2419
2420     static bool gFormatPrettyPrint = true;
2421
2422                 if(dc->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, gFormatPrettyPrint))
2423                         dc->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, gFormatPrettyPrint);
2424
2425     //
2426                 // Plug in a format target to receive the resultant
2427                 // XML stream from the serializer.
2428           //
2429                 // StdOutFormatTarget prints the resultant XML stream
2430                 // to stdout once it receives any thing from the serializer.
2431                 //
2432                 
2433     //XMLFormatTarget* myFormTarget = new StdOutFormatTarget();
2434                 //theSerializer->writeNode(myFormTarget, *Document);
2435
2436                 // get the DOM representation
2437                 //DOMNode                     *doc = parser->getDocument();
2438
2439                 //
2440                 // do the serialization through DOMWriter::writeNode();
2441                 //
2442                 //theSerializer->writeNode(myFormTarget, *Document);
2443
2444                 //XMLFormatTarget* myfFormTarget = new LocalFileFormatTarget("xxx");
2445                 //theSerializer->writeNode(myfFormTarget, *Document);
2446
2447     //((LocalFileFormatTarget*) myfFormTarget)->Target.setEscapeFlags();
2448
2449                 //kmr           theSerializer->writeNode(mymFormTarget, *Document);
2450                 theSerializer->write(Document, theOutput);
2451                 delete theOutput;
2452                 delete theSerializer;
2453
2454     //
2455                 // Filter, formatTarget and error handler
2456                 // are NOT owned by the serializer.
2457                 //
2458
2459                 delete myErrorHandler;
2460
2461     /*
2462                 if (gUseFilter)
2463                         delete myFilter; 
2464     */
2465
2466   }
2467   catch(XMLException& e) {
2468     std::cerr << "An error occurred during creation of output transcoder. Msg is:"
2469         << std::endl
2470         << StrX(e.getMessage()) << std::endl;
2471     //retval = 4;
2472   }
2473
2474   const XMLByte* XMLbuf = ((MemBufFormatTarget*) mymFormTarget)->getRawBuffer();
2475
2476   fprintf(File, "%s", XMLbuf);
2477
2478   delete mymFormTarget;
2479
2480   return 0;
2481 }
2482
2483
2484 // Create root element
2485 //void DIGFile::WritePrefix()
2486 void DIGFile::CreateRootElement()
2487 {\r
2488 #if DIGFILE_DEBUG_LEVEL > 2\r
2489   fprintf(stderr, "DIGFile::CreateRootElement\n");\r
2490 #endif\r
2491
2492   Document = impl->createDocument(
2493     0,            // root element namespace URI.
2494     RootXMLStr,   // root element name
2495     0             // document type object (DTD).
2496   );                  
2497
2498   RootElement = Document->getDocumentElement();
2499
2500 /*
2501         fprintf(File, "<?xml version=\"1.0\"?>\n\n");
2502         fprintf(File, "<DIG_DATA\n");
2503         fprintf(File, " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
2504         fprintf(File, " xsd:noNamespcadSchemaLocation=\"%s DIGschema.xsd\"\n", SchemaName);
2505         fprintf (File, ">\n");
2506   */
2507 }
2508
2509
2510 // Create Main Header
2511 int DIGFile::CreateMainHeader(DIGFileMainHeader* header)
2512 {\r
2513 #if DIGFILE_DEBUG_LEVEL > 2\r
2514   fprintf(stderr, "DIGFile::CreateMainHeader\n");\r
2515 #endif\r
2516
2517   XMLCh* tmpXMLStr;
2518
2519   // create main header node
2520   MainHeaderElement = Document->createElement(MainHeaderXMLStr);
2521
2522   // attributes
2523
2524   // define type
2525   tmpXMLStr = XMLString::transcode(header->Type.Get());
2526   MainHeaderElement->setAttribute(TypeXMLStr, tmpXMLStr);
2527   //delete tmpXMLStr;
2528
2529   // define title
2530   tmpXMLStr = XMLString::transcode(header->Title.Get());
2531   MainHeaderElement->setAttribute(TitleXMLStr, tmpXMLStr);
2532   //delete tmpXMLStr;
2533
2534   // define channels
2535   //tmpXMLStr = new XMLCh[5];
2536   //XMLString::binToText(header->Channels, tmpXMLStr, 4, 10);
2537   unsigned int maxchars = 1;
2538   if (header->Channels != 0)
2539     maxchars += static_cast<unsigned int>(log10(static_cast<double>(header->Channels)));
2540   tmpXMLStr = new XMLCh[maxchars+1];
2541   XMLString::binToText(header->Channels, tmpXMLStr, maxchars, 10);
2542   MainHeaderElement->setAttribute(ChannelsXMLStr, tmpXMLStr);
2543   delete tmpXMLStr;
2544
2545   // define number of arrays
2546   //tmpXMLStr = new XMLCh[5];
2547   //XMLString::binToText(NoOfArrays, tmpXMLStr, 4, 10);
2548   maxchars = 1;
2549   if (NoOfArrays != 0)
2550     maxchars += static_cast<unsigned int>(log10(static_cast<double>(NoOfArrays)));
2551   tmpXMLStr = new XMLCh[maxchars+1];
2552   XMLString::binToText(NoOfArrays, tmpXMLStr, maxchars, 10);
2553   MainHeaderElement->setAttribute(NumberOfArraysXMLStr, tmpXMLStr);
2554   delete tmpXMLStr;
2555
2556   // define number of array sets
2557   //tmpXMLStr = new XMLCh[5];
2558   //XMLString::binToText(NoOfSets, tmpXMLStr, 4, 10);
2559   maxchars = 1;
2560   if (NoOfSets != 0)
2561     maxchars += static_cast<unsigned int>(log10(static_cast<double>(NoOfSets)));
2562   tmpXMLStr = new XMLCh[maxchars+1];
2563   XMLString::binToText(NoOfSets, tmpXMLStr, maxchars, 10);
2564   MainHeaderElement->setAttribute(NumberOfArraySetsXMLStr, tmpXMLStr);
2565   delete tmpXMLStr;
2566
2567   // define endian according to curent machine type
2568   tmpXMLStr = XMLString::transcode(DIGEndianStr[static_cast<int>(DIG_ENDIAN)]);
2569   MainHeaderElement->setAttribute(EndianXMLStr, tmpXMLStr);
2570   //delete tmpXMLStr;
2571
2572   // define value type
2573   tmpXMLStr = XMLString::transcode(DIGValueTypeStr[header->ValueType]);
2574   MainHeaderElement->setAttribute(ValueTypeXMLStr, tmpXMLStr);
2575   //delete tmpXMLStr;
2576
2577   // define data type
2578   tmpXMLStr = XMLString::transcode(DIGDataTypeStr[header->DataType]);
2579   MainHeaderElement->setAttribute(DataTypeXMLStr, tmpXMLStr);
2580   //delete tmpXMLStr;
2581
2582   // define data format
2583   tmpXMLStr = XMLString::transcode(DIGDataFormatStr[header->DataFormat]);
2584   MainHeaderElement->setAttribute(DataFormatXMLStr, tmpXMLStr);
2585   //delete tmpXMLStr;
2586
2587   // define grid type
2588   tmpXMLStr = XMLString::transcode(DIGGridStr[header->Grid]);
2589   MainHeaderElement->setAttribute(GridTypeXMLStr, tmpXMLStr);
2590   //delete tmpXMLStr;
2591
2592   // define basis function
2593   tmpXMLStr = XMLString::transcode(DIGBasisStr[header->Basis]);
2594   MainHeaderElement->setAttribute(BasisFunctionXMLStr, tmpXMLStr);
2595   //delete tmpXMLStr;
2596
2597   // define unit
2598   tmpXMLStr = XMLString::transcode(DIGUnitStr[header->Unit]);
2599   MainHeaderElement->setAttribute(UnitXMLStr, tmpXMLStr);
2600   //delete tmpXMLStr;
2601
2602   // define other unit
2603         if(header->OtherUnit.Get() != NULL) {
2604     MainHeaderElement->setAttribute(OtherUnitXMLStr, XMLString::transcode(header->OtherUnit.Get()));
2605         }
2606
2607   // children
2608
2609
2610   // define comments
2611         if(header->Comment.Get() != NULL) {
2612     
2613     // create comments node
2614     DOMElement* Comments = Document->createElement(CommentsXMLStr);
2615
2616     // create comments text node
2617     tmpXMLStr = XMLString::transcode(header->Comment.Get());
2618     DOMText* CommentText = Document->createTextNode(tmpXMLStr);
2619     //delete tmpXMLStr;
2620     Comments->appendChild(CommentText);
2621
2622     // append comments to main header
2623     MainHeaderElement->appendChild(Comments);
2624   }
2625
2626
2627   // create dimensions node
2628   DOMElement* Dimensions = Document->createElement(DimensionsXMLStr);
2629
2630         const DIGDimensions* dim = &(header->Dimensions);
2631
2632   // set dimension attributes
2633   //tmpXMLStr = new XMLCh[5];
2634   //XMLString::binToText(dim->x, tmpXMLStr, 4, 10);
2635   maxchars = 1;
2636   if(dim->x != 0) {
2637     maxchars += static_cast<unsigned int>(log10(static_cast<double>(dim->x)));\r
2638   }
2639   tmpXMLStr = new XMLCh[maxchars+1];
2640   XMLString::binToText(dim->x, tmpXMLStr, maxchars, 10);
2641   Dimensions->setAttribute(DimmensionXXMLStr, tmpXMLStr);
2642   delete tmpXMLStr;
2643
2644   //XMLString::binToText(dim->y, tmpXMLStr, 4, 10);
2645   maxchars = 1;
2646   if(dim->y != 0) {
2647     maxchars += static_cast<unsigned int>(log10(static_cast<double>(dim->y)));\r
2648   }
2649   tmpXMLStr = new XMLCh[maxchars+1];
2650   XMLString::binToText(dim->y, tmpXMLStr, maxchars, 10);
2651   Dimensions->setAttribute(DimmensionYXMLStr, tmpXMLStr);
2652   delete tmpXMLStr;
2653
2654   //XMLString::binToText(dim->z, tmpXMLStr, 4, 10);
2655   maxchars = 1;
2656   if(dim->z != 0) {
2657     maxchars += static_cast<unsigned int>(log10(static_cast<double>(dim->z)));\r
2658   }
2659   tmpXMLStr = new XMLCh[maxchars+1];
2660   XMLString::binToText(dim->z, tmpXMLStr, maxchars, 10);
2661   Dimensions->setAttribute(DimmensionZXMLStr, tmpXMLStr);
2662   delete tmpXMLStr;
2663
2664   // append dimensions to main header
2665   MainHeaderElement->appendChild(Dimensions);
2666
2667
2668   // create sampling rate X node
2669   DOMElement* SamplingRateX = Document->createElement(SamplingRateXXMLStr);
2670
2671         DIGSampling* sampX = &(header->SamplingX);
2672
2673   // set sampling rate X attributes
2674   char valStr[20];
2675
2676   sprintf(valStr, "%f", sampX->x);
2677   tmpXMLStr = XMLString::transcode(valStr);
2678   SamplingRateX->setAttribute(DimmensionXXMLStr, tmpXMLStr);
2679   //delete tmpXMLStr;
2680
2681   sprintf(valStr, "%f", sampX->y);
2682   tmpXMLStr = XMLString::transcode(valStr);
2683   SamplingRateX->setAttribute(DimmensionYXMLStr, tmpXMLStr);
2684   //delete tmpXMLStr;
2685
2686   sprintf(valStr, "%f", sampX->z);
2687   tmpXMLStr = XMLString::transcode(valStr);
2688   SamplingRateX->setAttribute(DimmensionZXMLStr, tmpXMLStr);
2689   //delete tmpXMLStr;
2690
2691   // append sampling rate X to main header
2692   MainHeaderElement->appendChild(SamplingRateX);
2693
2694
2695   // create sampling rate Y node
2696   DOMElement* SamplingRateY = Document->createElement(SamplingRateYXMLStr);
2697
2698         DIGSampling* sampY = &(header->SamplingY);
2699
2700   // set sampling rate Y attributes
2701   sprintf(valStr, "%f", sampY->x);
2702   tmpXMLStr = XMLString::transcode(valStr);
2703   SamplingRateY->setAttribute(DimmensionXXMLStr, tmpXMLStr);
2704   //delete tmpXMLStr;
2705
2706   sprintf(valStr, "%f", sampY->y);
2707   tmpXMLStr = XMLString::transcode(valStr);
2708   SamplingRateY->setAttribute(DimmensionYXMLStr, tmpXMLStr);
2709   //delete tmpXMLStr;
2710
2711   sprintf(valStr, "%f", sampY->z);
2712   tmpXMLStr = XMLString::transcode(valStr);
2713   SamplingRateY->setAttribute(DimmensionZXMLStr, tmpXMLStr);
2714   //delete tmpXMLStr;
2715
2716   // append sampling rate Y to main header
2717   MainHeaderElement->appendChild(SamplingRateY);
2718
2719
2720   // create sampling rate Z node
2721   DOMElement* SamplingRateZ = Document->createElement(SamplingRateZXMLStr);
2722
2723         DIGSampling* sampZ = &(header->SamplingZ);
2724
2725   // set sampling rate Z attributes
2726   sprintf(valStr, "%f", sampZ->x);
2727   tmpXMLStr = XMLString::transcode(valStr);
2728   SamplingRateZ->setAttribute(DimmensionXXMLStr, tmpXMLStr);
2729   //delete tmpXMLStr;
2730
2731   sprintf(valStr, "%f", sampZ->y);
2732   tmpXMLStr = XMLString::transcode(valStr);
2733   SamplingRateZ->setAttribute(DimmensionYXMLStr, tmpXMLStr);
2734   //delete tmpXMLStr;
2735
2736   sprintf(valStr, "%f", sampZ->z);
2737   tmpXMLStr = XMLString::transcode(valStr);
2738   SamplingRateZ->setAttribute(DimmensionZXMLStr, tmpXMLStr);
2739   //delete tmpXMLStr;
2740
2741   // append sampling rate Z to main header
2742   MainHeaderElement->appendChild(SamplingRateZ);
2743
2744
2745   // append main header to document root
2746   RootElement->appendChild(MainHeaderElement);
2747
2748   /*
2749   if(MainHeaderWritten) {
2750     return -1; // main header already in file
2751   }
2752
2753         fprintf(File, "  <main_header\n");
2754         fprintf(File, "    type=\"%s\"\n", header->GetType());
2755         fprintf(File, "    title=\"%s\"\n", header->GetTitle());
2756         fprintf(File, "    channels=\"%d\"\n", header->GetChannels());
2757         fprintf(File, "    number_of_arrays=\"%d\"\n", header->GetNumberOfArrays());
2758         fprintf(File, "    number_of_array_sets=\"%d\"\n", header->GetNumberOfSets());
2759         fprintf(File, "    endian=\"%s\"\n", header->GetEndianStr());
2760         fprintf(File, "    value_type=\"%s\"\n", header->GetValueTypeStr());
2761         fprintf(File, "    data_type=\"%s\"\n", header->GetDataTypeStr());
2762         fprintf(File, "    data_format=\"%s\"\n", header->GetDataFormatStr());
2763         fprintf(File, "    grid_type=\"%s\"\n", header->GetGridStr());
2764         fprintf(File, "    basis_function=\"%s\"\n", header->GetBasisStr());
2765         fprintf(File, "    unit=\"%s\"\n", header->GetUnitStr());
2766
2767
2768         if(header->GetOtherUnit() != NULL) {
2769                 fprintf(File, "    other_unit=\"%s\"\n", header->GetOtherUnit());       
2770         }
2771
2772         fprintf(File, "  >\n"); 
2773
2774         if(header->GetComment() != NULL){
2775                 fprintf (File, "    <comments>\n");
2776                 fprintf (File, "    %s\n", header->GetComment());
2777                 fprintf (File, "    </comments>\n");
2778   }
2779
2780         DIGDimensions *dim = header->GetDimensions();
2781         fprintf(File, "    <dimensions x=\"%d\" y=\"%d\" z=\"%d\"/>\n", dim->x, dim->y, dim->z);
2782
2783         DIGSampling *sampX = header->GetSamplingX();
2784         fprintf(File, "    <sampling_rate_x x=\"%6.3f\" y=\"%6.3f\" z=\"%6.3f\"/>\n", sampX->x, sampX->y, sampX->z);
2785
2786         DIGSampling *sampY = header->GetSamplingY();
2787         fprintf(File, "    <sampling_rate_y x=\"%6.3f\" y=\"%6.3f\" z=\"%6.3f\"/>\n", sampY->x, sampY->y, sampY->z);
2788
2789         DIGSampling *sampZ = header->GetSamplingZ();
2790         fprintf(File, "    <sampling_rate_z x=\"%6.3f\" y=\"%6.3f\" z=\"%6.3f\"/>\n", sampZ->x, sampZ->y, sampZ->z);
2791
2792         fprintf(File, "  </main_header>\n\n");
2793         //fprintf(File, "  <!-- origin is %d %d %d -->\n", (dim->x-1)/2, (dim->y-1)/2, (dim->z-1)/2);
2794         
2795
2796   MainHeaderWritten = true;
2797   */
2798         return 0;
2799 }
2800
2801 int DIGFile::CreateApplicationHeader()
2802 {\r
2803 \r
2804 #if DIGFILE_DEBUG_LEVEL > 2\r
2805   fprintf(stderr, "DIGFile::CreateApplicationHeader\n");\r
2806 #endif\r
2807
2808         return 0;
2809 }
2810
2811
2812
2813 int DIGFile::AppendArraySetHeader(DIGFileArraySetHeader* SetHeader)
2814 {\r
2815 #if DIGFILE_DEBUG_LEVEL > 2\r
2816   fprintf(stderr, "DIGFile::AppendArraySetHeader\n");\r
2817 #endif\r
2818
2819   XMLCh* tmpXMLStr;
2820
2821   // create array set header node
2822   ArraySetHeaderElement = Document->createElement(ArraySetHeaderXMLStr);
2823
2824   // attributes
2825
2826   // define type
2827   tmpXMLStr = XMLString::transcode(SetHeader->Type.Get());
2828   ArraySetHeaderElement->setAttribute(TypeXMLStr, tmpXMLStr);
2829   //delete tmpXMLStr;
2830
2831   // define title
2832   tmpXMLStr = XMLString::transcode(SetHeader->Title.Get());
2833   ArraySetHeaderElement->setAttribute(TitleXMLStr, tmpXMLStr);
2834   //delete tmpXMLStr;
2835
2836
2837   // children
2838
2839
2840   // define comments
2841   const char* Com = SetHeader->Comment.Get();
2842
2843   if(Com != NULL) {
2844     
2845     // create comments node
2846     DOMElement* Comments = Document->createElement(CommentsXMLStr);
2847
2848     // create comments text node
2849     tmpXMLStr = XMLString::transcode(Com);
2850     DOMText* CommentText = Document->createTextNode(tmpXMLStr);
2851     //delete tmpXMLStr;
2852     Comments->appendChild(CommentText);
2853
2854     // append comments to array set header
2855     ArraySetHeaderElement->appendChild(Comments);
2856   }
2857
2858   // create parameters node
2859   DOMElement* Parameter = Document->createElement(ParametersXMLStr);
2860
2861   // create parameters text node
2862   tmpXMLStr = XMLString::transcode(SetHeader->Parameters.Get());
2863   DOMText* ParameterText = Document->createTextNode(tmpXMLStr);
2864   //delete tmpXMLStr;
2865   Parameter->appendChild(ParameterText);
2866
2867   // append parameters to array set header
2868   ArraySetHeaderElement->appendChild(Parameter);
2869
2870
2871   // append array set header to main header
2872   RootElement->appendChild(ArraySetHeaderElement);
2873
2874   /*
2875   // check if main header written
2876   if(!MainHeaderWritten) {
2877     return -1; // error: no main header in file
2878   }
2879
2880   // close previous array set
2881   if(ArraySetOpen) {
2882     fprintf(File, "  </array_set_header>\n\n");
2883   }
2884   else {
2885     ArraySetOpen = true;
2886   }
2887 //  ArrayCounter = 0;
2888
2889         fprintf(File, "\n  <array_set_header\n");
2890         fprintf(File, "    type=\"%s\"\n", SetHeader->GetType());
2891         fprintf(File, "    title=\"%s\"\n", SetHeader->GetTitle());
2892         fprintf(File, "  >\n");
2893
2894   char* Comments = SetHeader->GetComments();
2895
2896   if(Comments != NULL) {
2897                 fprintf(File, "    <comments>\n");
2898                 fprintf(File, "      %s\n", Comments);
2899                 fprintf(File, "    </comments>\n");
2900         }
2901   
2902         fprintf(File, "    <parameters>\n");
2903         fprintf(File, "      %s\n", SetHeader->GetParameters());
2904         fprintf(File, "    </parameters>\n");
2905 */
2906
2907         return 0;
2908 }
2909
2910
2911
2912 int DIGFile::AppendArrayHeader(DIGFileArrayHeader* ArrayHeader)
2913 {\r
2914 #if DIGFILE_DEBUG_LEVEL > 2\r
2915   fprintf(stderr, "DIGFile::AppendArrayHeader\n");\r
2916 #endif\r
2917
2918   XMLCh* tmpXMLStr;
2919
2920   // create array set header node
2921   ArrayHeaderElement = Document->createElement(ArrayHeaderXMLStr);
2922
2923   // attributes
2924
2925   // define type
2926   //tmpXMLStr = new XMLCh[5];
2927   //XMLString::binToText(ArrayHeader->EnumNo, tmpXMLStr, 4, 10);
2928   unsigned int maxchars = 1;
2929   if(ArrayHeader->EnumNo != 0) {
2930     maxchars += static_cast<unsigned int>(log10(static_cast<double>(ArrayHeader->EnumNo)));\r
2931   }
2932   tmpXMLStr = new XMLCh[maxchars+1];
2933   XMLString::binToText(ArrayHeader->EnumNo, tmpXMLStr, maxchars, 10);
2934   ArrayHeaderElement->setAttribute(EnumerationNumberXMLStr, tmpXMLStr);
2935   delete tmpXMLStr;
2936
2937
2938   // children
2939
2940
2941   // define comments
2942   const char* Com = ArrayHeader->Comment.Get();
2943
2944   if(Com != NULL) {
2945     
2946     // create comments node
2947     DOMElement* Comments = Document->createElement(CommentsXMLStr);
2948
2949     // create comments text node
2950     tmpXMLStr = XMLString::transcode(Com);
2951     DOMText* CommentText = Document->createTextNode(tmpXMLStr);
2952     //delete tmpXMLStr;
2953     Comments->appendChild(CommentText);
2954
2955     // append comments to array header
2956     ArrayHeaderElement->appendChild(Comments);
2957   }
2958
2959
2960   // append array header to active array set header
2961   ArraySetHeaderElement->appendChild(ArrayHeaderElement);
2962
2963   /*
2964   fprintf(File, "\n    <array_header\n");
2965
2966         //fprintf(File, "      enumeration_number=\"%d\">\n", array_enumeration[sets*size+arrays]);
2967   //fprintf(File, "      enumeration_number=\"%d\"\n", ArrayCounter);
2968   fprintf(File, "      enumeration_number=\"%d\"\n", ArrayHeader->GetEnumeration());
2969   fprintf(File, "    >\n");
2970
2971   
2972   char* comment = ArrayHeader->GetComment();
2973
2974   if(comment != NULL) {
2975                 fprintf(File, "      <comments>\n");
2976                 fprintf(File, "        %s\n", comment);
2977     fprintf(File, "      </comments>\n");
2978         }
2979
2980         fprintf(File, "    </array_header>\n");
2981 */
2982         return 0;
2983 }