Salome HOME
PR: merge from branch BR_UnitTests tag mergeto_trunk_17oct05
[modules/kernel.git] / src / HDFPersist / HDFascii.cc
1 //  File      : SALOMEDS_Tool.cxx
2 //  Created   : Mon Oct 21 16:24:34 2002
3 //  Author    : Sergey RUIN
4
5 //  Project   : SALOME
6 //  Module    : SALOMEDS
7 //  Copyright : Open CASCADE
8
9 #include "HDFOI.hxx"
10
11 #include <OSD_Path.hxx>
12 #include <OSD_File.hxx>
13 #include <OSD_Protection.hxx>
14 #include <OSD_Directory.hxx>
15 #include <TCollection_AsciiString.hxx> 
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <fcntl.h>
20 #include <stdio.h>
21
22 #ifdef WNT
23 #include <io.h>
24 #include <time.h>
25 #endif
26
27 using namespace std;
28
29 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
30 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
31 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
32
33 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
34 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
35 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
36
37 char* GetTmpDir();
38 char* makeName(char* name);
39 char* restoreName(char* name);
40 void write_float64(FILE* fp, hdf_float64* value);
41 void read_float64(FILE* fp, hdf_float64* value);
42
43 #define MAX_STRING_SIZE   65535
44 #define MAX_ID_SIZE       20
45 #define NB_FLOAT_IN_ROW   3
46 #define NB_INTEGER_IN_ROW 9
47
48 #define ASCIIHDF_ID  "ASCIIHDF"
49 #define ATTRIBUTE_ID "ATTRIBUTE"
50 #define DATASET_ID   "DATASET"
51 #define GROUP_ID     "GROUP"
52
53 #define ASCIIHDF_ID_END  "ASCIIHDF_END"
54 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
55 #define DATASET_ID_END   "DATASET_END"
56 #define GROUP_ID_END     "GROUP_END"
57
58
59 //============================================================================
60 // function : isASCII
61 // purpose  : Returns True if the file is a converted to ASCII HDF file
62 //============================================================================
63 bool HDFascii::isASCII(const char* thePath) {
64   int fd;
65   if(!(fd = open(thePath, O_RDONLY))) return false;
66   char* aBuffer = new char[9];
67   aBuffer[8] = (char)0;
68   read(fd, aBuffer, 8); 
69   close(fd);
70
71   if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
72
73   return false;
74 }
75
76 //############################## HDF => ASCII ################################
77
78 //============================================================================
79 // function : ConvertFromHDFToASCII
80 // purpose  : Converts a file pointed by thePath to ASCII format
81 //            If isReplace is true the newly created file will replace the existent one.
82 //            If isReplace is false theExtension will be added to a created file name 
83 //            Returns the file name of ASCII file
84 //============================================================================
85 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
86                                       bool isReplace,
87                                       const char* theExtension)
88 {
89   TCollection_AsciiString aPath((char*)thePath);
90   if(!isReplace) { 
91     if(theExtension == NULL) aPath += ".asc";    
92     else aPath += (char*)theExtension;
93   }
94
95   TCollection_AsciiString aFileName(aPath);
96   if(isReplace) aFileName=aPath+".ascii_tmp";
97  
98   HDFfile *hdf_file = new HDFfile((char*)thePath); 
99   hdf_file->OpenOnDisk(HDF_RDONLY);
100
101   char name[HDF_NAME_MAX_LEN+1];
102   int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes(); 
103
104   FILE* fp = fopen(aFileName.ToCString(), "w");
105   fprintf(fp, "%s\n", ASCIIHDF_ID);
106   fprintf(fp, "%i\n", nbsons+nbAttr);
107
108   for(unsigned j=0; j<nbAttr; j++) {
109     char* attr_name = hdf_file->GetAttributeName(j);
110     HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
111     delete attr_name;
112     SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
113     hdf_attribute = 0;
114   }
115
116   for (Standard_Integer i=0; i<nbsons; i++) {
117     hdf_file->InternalObjectIndentify(i,name);
118     if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
119
120     hdf_object_type type = hdf_file->InternalObjectType(name);
121
122     if(type == HDF_DATASET) { 
123       HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
124       SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
125       hdf_dataset = 0; 
126     } else if(type == HDF_GROUP) {
127       HDFgroup *hdf_group = new HDFgroup(name, hdf_file); 
128       SaveGroupInASCIIfile(hdf_group, fp, 0);
129       hdf_group = 0;
130     }
131   }
132
133   fprintf(fp, "%s", ASCIIHDF_ID_END);
134
135   fclose(fp);
136
137   hdf_file->CloseOnDisk();
138   delete hdf_file;
139
140   if(isReplace) {
141     OSD_Path anOSDPath(aFileName);
142     OSD_File anOSDFile(anOSDPath);
143     if(anOSDFile.Exists())
144       anOSDFile.Move(aPath);
145     else 
146       return NULL;
147   }
148
149   int length = strlen(aPath.ToCString());
150   char *new_str = new char[ 1+length ];
151   strcpy(new_str , aPath.ToCString()) ;
152
153   return new_str;
154 }
155
156
157 //============================================================================
158 // function : SaveGroupInASCIIfile
159 // purpose  : 
160 //============================================================================
161 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
162 {
163   hdf_group->OpenOnDisk();
164
165   TCollection_AsciiString anIdent(ident, '\t');
166   int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes(); 
167
168   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID);*/
169   fprintf(fp, "%s\n", GROUP_ID);
170
171   char* name = makeName(hdf_group->GetName());
172
173   /*fprintf(fp, "%s%s %i\n", anIdent.ToCString(), name, nbsons+nbAttr);*/
174   fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
175   delete name;
176
177   for(unsigned j=0; j<nbAttr; j++) {
178     name = hdf_group->GetAttributeName(j);
179     HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
180     delete name;
181     SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
182     hdf_attribute = 0;
183   }
184
185   char objName[HDF_NAME_MAX_LEN+1];
186  
187   for (int i=0; i<nbsons; i++) {
188     hdf_group->InternalObjectIndentify(i, objName);
189
190     if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0)  continue;
191
192     hdf_object_type type = hdf_group->InternalObjectType(objName);
193
194     if  (type == HDF_DATASET) {
195       HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
196       SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
197       hdf_dataset = 0;
198     } else if (type == HDF_GROUP)   {      
199       HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
200       SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
201       hdf_subgroup = 0;
202     } 
203   }
204
205   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID_END);*/
206   fprintf(fp, "%s\n", GROUP_ID_END);
207
208   hdf_group->CloseOnDisk();  
209 }
210
211 //============================================================================
212 // function : SaveDatasetInASCIIfile
213 // purpose  : 
214 //============================================================================
215 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
216 {
217   hdf_dataset->OpenOnDisk();
218
219   long size =  hdf_dataset->GetSize();
220   long ndim = hdf_dataset->nDim(); //Get number of dimesions
221   hdf_size *dim = new hdf_size[ndim];
222   hdf_type type = hdf_dataset->GetType();
223   int nbAttr = hdf_dataset->nAttributes(), j; 
224
225   TCollection_AsciiString anIdent(ident, '\t');
226   TCollection_AsciiString anIdentChild(ident+1, '\t');
227
228   char* name = makeName(hdf_dataset->GetName());
229
230   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID);*/
231   fprintf(fp, "%s\n", DATASET_ID);
232   /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, nbAttr);*/
233   fprintf(fp, "%s %i %i\n", name, type, nbAttr);
234   delete name;
235
236   hdf_dataset->GetDim(dim);
237   /*fprintf(fp, "%s %i\n", anIdentChild.ToCString(), ndim);*/
238   fprintf(fp, " %i\n", ndim);
239
240   for(int i = 0;i < ndim;i++) {
241     /*fprintf(fp, "%s%i",  anIdentChild.ToCString(), dim[i]);*/
242     fprintf(fp, " %i", dim[i]);
243   }
244
245   /*fprintf(fp, "%s\n", anIdentChild.ToCString());*/
246   fprintf(fp, "\n");
247   delete dim;
248
249   /*fprintf(fp, "%s%li:", anIdentChild.ToCString(), size);*/
250   fprintf(fp, "%li:", size);
251
252   if (type == HDF_STRING) {     
253     char* val = new char[size];
254     hdf_dataset->ReadFromDisk(val);
255     fwrite(val, 1, size, fp);
256     delete val;
257   } else if (type == HDF_FLOAT64) {
258     hdf_float64* val = new hdf_float64[size];
259     hdf_dataset->ReadFromDisk(val);
260     fprintf(fp, "\n");
261     for (int i = 0, j = 0; i < size; i++) {
262       write_float64(fp, &val[i]);
263       if(++j == NB_FLOAT_IN_ROW) {
264         fprintf(fp, "\n");
265         j = 0;
266       }
267       else fprintf(fp,"  ");
268     }
269     delete val;
270   } else if(type == HDF_INT64) {
271     hdf_int64* val = new hdf_int64[size];
272     hdf_dataset->ReadFromDisk(val);
273     fprintf(fp, "\n");
274     for (int i = 0, j = 0; i < size; i++) {
275       fprintf(fp, " %li", val[i]);
276       if(++j == NB_INTEGER_IN_ROW) {
277         fprintf(fp, "\n");
278         j = 0;
279       }
280     }
281     delete val;
282   } else if(type == HDF_INT32) {
283     hdf_int32* val = new hdf_int32[size];
284     hdf_dataset->ReadFromDisk(val);
285     fprintf(fp, "\n");
286     for (int i = 0, j = 0; i < size; i++) {
287       fprintf(fp, " %i", val[i]);
288       if(++j == NB_INTEGER_IN_ROW) {
289         fprintf(fp, "\n");
290         j = 0;
291       }
292     }
293     delete val;
294   }
295   
296   fprintf(fp, "\n");
297
298 #ifndef WNT
299   for(unsigned j=0; j<nbAttr; j++) {
300 #else
301   for(j=0; j<nbAttr; j++) {
302 #endif
303     name = hdf_dataset->GetAttributeName(j);
304     HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
305     delete name;
306     SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
307     hdf_attribute = 0;
308   }
309
310   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID_END); */
311   fprintf(fp, "%s\n", DATASET_ID_END);
312
313   hdf_dataset->CloseOnDisk(); 
314 }
315
316
317 //============================================================================
318 // function : SaveAttributeInASCIIfile
319 // purpose  : 
320 //============================================================================
321 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
322 {
323   hdf_attribute->OpenOnDisk();
324
325   hdf_type type = hdf_attribute->GetType();
326
327   TCollection_AsciiString anIdent(ident, '\t');
328   TCollection_AsciiString anIdentChild(ident+1, '\t');
329
330   char* name = makeName(hdf_attribute->GetName());
331   int size = hdf_attribute->GetSize();
332
333   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID);*/
334   fprintf(fp, "%s\n", ATTRIBUTE_ID);
335   /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, size);*/
336   fprintf(fp, "%s %i %i\n", name, type, size);
337
338   delete name;
339
340   if (type == HDF_STRING) {    
341     char* val = new char[size+1];
342     hdf_attribute->ReadFromDisk(val);
343     /*fprintf(fp, "%s:", anIdentChild.ToCString());*/
344     fprintf(fp, ":");
345     fwrite(val, 1, size, fp);
346     fprintf(fp, "\n");
347     delete val;
348   } else if (type == HDF_FLOAT64) {
349     hdf_float64 val;
350     hdf_attribute->ReadFromDisk(&val);
351     /*fprintf(fp, "%s",  anIdentChild.ToCString());*/
352     write_float64(fp, &val);
353     fprintf(fp, "\n");
354   } else if(type == HDF_INT64) {
355     hdf_int64 val;
356     hdf_attribute->ReadFromDisk(&val);
357     /*fprintf(fp, "%s%li \n", anIdentChild.ToCString(), val);*/
358     fprintf(fp, "%li \n", val);
359   } else if(type == HDF_INT32) {
360     hdf_int32 val;
361     hdf_attribute->ReadFromDisk(&val);
362     /*fprintf(fp, "%s%i \n", anIdentChild.ToCString(), val);*/
363     fprintf(fp, "%i \n", val);
364   }
365
366   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID_END);*/
367   fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
368
369   hdf_attribute->CloseOnDisk();  
370 }
371
372 //############################## ASCII => HDF ################################
373
374 //============================================================================
375 // function : ConvertFromASCIIToHDF
376 // purpose  : Converts a file pointed by thePath to HDF format
377 //            Returns a name of directory where a created HDF file is placed
378 //            The created file is named "hdf_from_ascii.hdf"
379 //============================================================================
380 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
381 {
382   // Get a temporary directory to store a file
383   TCollection_AsciiString aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
384   // Build a full file name of temporary file
385   TCollection_AsciiString aFullName = aTmpDir + aFileName;
386
387   HDFfile *hdf_file = new HDFfile(aFullName.ToCString()); 
388   hdf_file->CreateOnDisk();
389   
390   FILE *fp = fopen(thePath, "r");
391   if(!fp) return NULL;
392
393   char type[9];
394   int nbsons, i;
395   fscanf(fp, "%s", type);
396   fscanf(fp, "%i",&nbsons);
397
398   if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
399
400   for(i = 0; i < nbsons; i++) {
401     char id_of_begin[MAX_ID_SIZE];
402     fscanf(fp, "%s\n", id_of_begin);
403
404     if(strcmp(id_of_begin, GROUP_ID) == 0) {
405       if(!CreateGroupFromASCII(hdf_file, fp)) {
406         cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
407         return NULL;
408       }
409     }
410     else if(strcmp(id_of_begin, DATASET_ID) == 0) {
411       if(!CreateDatasetFromASCII(hdf_file, fp)) {
412         cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
413         return NULL;
414       }
415     }
416     else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
417       if(!CreateAttributeFromASCII(hdf_file, fp)) {
418         cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
419         return NULL;
420       }
421     }
422     else 
423       cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl; 
424   }
425
426   char id_of_end[MAX_ID_SIZE];
427   fscanf(fp, "%s", id_of_end);
428   if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
429     cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
430     return false;  
431   }
432
433   hdf_file->CloseOnDisk();
434   delete hdf_file;
435
436   int length = strlen(aTmpDir.ToCString());
437   char *new_str = new char[ 1+length ];
438   strcpy(new_str , aTmpDir.ToCString()) ;
439
440   return new_str;
441 }
442
443
444 //============================================================================
445 // function : CreateGroupFromASCII
446 // purpose  : Creates a HDF group from a set attributes situated under theLabel
447 //============================================================================
448 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
449 {
450   char name[HDF_NAME_MAX_LEN+1];
451   int nbsons, i;
452   fscanf(fp, "%s %i\n", name, &nbsons);  
453
454   char* new_name = restoreName(name);
455
456   HDFgroup* hdf_group = new HDFgroup(new_name, father);
457
458   delete new_name;
459
460   hdf_group->CreateOnDisk();
461
462   for(i = 0; i < nbsons; i++) {
463     char id_of_begin[MAX_ID_SIZE];
464     fscanf(fp, "%s\n", id_of_begin);
465     
466     if(strcmp(id_of_begin, GROUP_ID) == 0) {
467       if(!CreateGroupFromASCII(hdf_group, fp)) {
468         cout << "Can not create subgroup " << i << " for group " << name << endl;
469         return false;
470       }
471     }
472     else if(strcmp(id_of_begin, DATASET_ID) == 0) {
473       if(!CreateDatasetFromASCII(hdf_group, fp)) {
474         cout << "Can not create dataset " << i << " for group " << name << endl;
475         return false;
476       }
477     }
478     else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
479       if(!CreateAttributeFromASCII(hdf_group, fp)) {
480         cout << "Can not create attribute " << i << " for group " << name << endl;
481         return false;
482       }
483     }
484     else 
485       cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl; 
486   }
487   
488   hdf_group->CloseOnDisk();
489   hdf_group = 0; //will be deleted by father destructor
490
491   char id_of_end[MAX_ID_SIZE];
492   fscanf(fp, "%s\n", id_of_end);
493   if(strcmp(id_of_end, GROUP_ID_END) != 0) {
494     cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
495     return false;
496   }
497
498   return true;
499 }
500
501
502 //============================================================================
503 // function : CreateDatasetFromASCII
504 // purpose  : Creates a HDF dataset from a set attributes situated under theLabel
505 //============================================================================
506 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
507 {
508   char name[HDF_NAME_MAX_LEN+1];
509   hdf_type type;
510   int nbDim, nbAttr;
511   long i, size;
512
513   fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
514   char* new_name = restoreName(name);
515
516   fscanf(fp, "%i\n", &nbDim);
517
518   hdf_size* sizeArray = new hdf_size[nbDim];
519   int dim = 0;
520   for(i = 0; i<nbDim; i++) {
521     fscanf(fp, "%i\n", &dim);
522     sizeArray[i] = dim;
523   }
524  
525   HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim);
526   delete new_name;
527   delete sizeArray;
528
529   hdf_dataset->CreateOnDisk();
530
531   char tmp;
532   fscanf(fp, "%li%c", &size, &tmp);
533
534   if (type == HDF_STRING) {     
535     char *val = new char[size+1];
536     fread(val, 1, size, fp);
537     hdf_dataset->WriteOnDisk(val);
538     delete val;
539   } else if (type == HDF_FLOAT64) {
540     hdf_float64* val = new hdf_float64[size];
541     for(i=0; i<size; i++) {
542       read_float64(fp, &(val[i]));
543     }
544     hdf_dataset->WriteOnDisk(val);
545     delete val;
546   } else if(type == HDF_INT64) {
547     hdf_int64* val = new hdf_int64[size];
548     for(i=0; i<size; i++) {
549       fscanf(fp, " %li", &(val[i]));
550     }
551     hdf_dataset->WriteOnDisk(val);
552     delete val;
553   } else if(type == HDF_INT32) {
554     hdf_int32* val = new hdf_int32[size];
555     for(i=0; i<size; i++) {
556       fscanf(fp, " %i", &(val[i]));
557     }
558     hdf_dataset->WriteOnDisk(val);
559     delete val;
560   }
561
562   char token[MAX_ID_SIZE];
563
564   for(i = 0; i < nbAttr; i++) {
565     fscanf(fp, "%s\n", token);
566     
567     if(strcmp(token, ATTRIBUTE_ID) == 0) {
568       if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
569         cout << "Can not create attribute " << i << " for dataset " << name << endl;
570         return false;
571       }
572     }
573     else {
574       cout << "CreateGroupFromASCII : Unrecognized type " << token << endl; 
575       return false;
576     }
577   }
578   
579   fscanf(fp, "%s\n", token);
580   if(strcmp(token, DATASET_ID_END) != 0) {
581     cout << "CreateDatasetFromASCII : Invalid end token : " << token << endl;
582     return false;
583   }
584
585   hdf_dataset->CloseOnDisk();
586   hdf_dataset = 0; //will be deleted by father destructor
587
588   return true;
589 }
590
591
592 //============================================================================
593 // function : CreateAttributeFromASCII
594 // purpose  : Creates a HDF attribute from a set attributes situated under theLabel
595 //============================================================================
596 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
597 {
598   char name[HDF_NAME_MAX_LEN+1];
599
600   hdf_type type;
601   int size;
602   fscanf(fp, "%s %i %i\n", name, &type, &size);
603   char* new_name = restoreName(name);
604   HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
605
606   hdf_attribute->CreateOnDisk();
607
608   delete new_name;
609   
610   if (type == HDF_STRING) {     
611     char tmp;
612     fscanf(fp, "%c", &tmp);
613     char *val = new char[size+1];
614     val[size] = (char)0;
615     fread(val, 1, size, fp);
616     hdf_attribute->WriteOnDisk(val);
617     delete val;
618   } else if (type == HDF_FLOAT64) {
619     hdf_float64 val;
620     read_float64(fp, &val);
621     hdf_attribute->WriteOnDisk(&val);
622   } else if(type == HDF_INT64) {
623     hdf_int64 val;
624     fscanf(fp, "%li", &val);
625     hdf_attribute->WriteOnDisk(&val);
626   } else if(type == HDF_INT32) {
627     hdf_int32 val;
628     fscanf(fp, "%i", &val);
629     hdf_attribute->WriteOnDisk(&val);
630   }
631   
632   hdf_attribute->CloseOnDisk();
633   hdf_attribute = 0; //will be deleted by father destructor
634
635
636   char id_of_end[MAX_ID_SIZE];
637   fscanf(fp, "%s\n", id_of_end);
638   if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
639     cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << endl;
640     return false;
641   }
642
643   return true;
644 }
645
646
647 //============================================================================
648 // function : GetTempDir
649 // purpose  : Return a temp directory to store created files like "/tmp/sub_dir/" 
650 //============================================================================ 
651 char* GetTmpDir()
652 {
653   //Find a temporary directory to store a file
654
655   TCollection_AsciiString aTmpDir;
656
657 #ifdef WNT
658   char *aTmp;
659   aTmp = getenv("TMP");
660   if(aTmp != NULL)
661         aTmpDir = TCollection_AsciiString(aTmp);
662   else
663         aTmpDir = TCollection_AsciiString("C:\\");
664 #else
665   aTmpDir = TCollection_AsciiString("/tmp/");
666 #endif
667
668   srand((unsigned int)time(NULL));
669
670   int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
671   TCollection_AsciiString aSubDir(aRND);
672   if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
673
674   aTmpDir += aSubDir; //Get RND sub directory
675
676 #ifdef WIN32
677   if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
678 #else
679   if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
680 #endif
681
682   OSD_Path aPath(aTmpDir);
683   OSD_Directory aDir(aPath);
684
685   for(aRND = 0; aDir.Exists(); aRND++) {
686     aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND));  //Build a unique directory name
687     aPath = OSD_Path(aTmpDir);
688     aDir = OSD_Directory(aPath);
689   }
690
691   OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
692   aDir.Build(aProtection);
693
694   int length = strlen(aTmpDir.ToCString());
695   char *new_str = new char[ 1+length ];
696   strcpy(new_str , aTmpDir.ToCString());
697
698   return new_str;
699 }
700
701 char* makeName(char* name)
702 {
703   TCollection_AsciiString aName(name), aNewName;
704   Standard_Integer i, length = aName.Length();
705   char replace = (char)19;
706
707   for(i=1; i<=length; i++) {
708     if(aName.Value(i) == ' ') aNewName+=replace;
709     else aNewName += aName.Value(i);
710   }
711
712   length = strlen(aNewName.ToCString());
713   char *new_str = new char[ 1+length ];
714   strcpy(new_str , aNewName.ToCString()) ;
715   return new_str;
716 }
717
718 char* restoreName(char* name)
719 {
720   TCollection_AsciiString aName(name), aNewName;
721   Standard_Integer i, length = aName.Length();
722   char replace = (char)19;
723
724   for(i=1; i<=length; i++) {
725     if(aName.Value(i) == replace) aNewName+=' ';
726     else aNewName += aName.Value(i);
727   }
728
729   length = strlen(aNewName.ToCString());
730   char *new_str = new char[ 1+length ];
731   strcpy(new_str , aNewName.ToCString()) ;
732   return new_str;
733 }
734
735 void write_float64(FILE* fp, hdf_float64* value)
736 {
737   unsigned char* array = (unsigned char*)value;
738   for(int i = 0; i < sizeof(hdf_float64); i++) {
739     unsigned tmp = (unsigned short)array[i];
740     fprintf(fp, " %2x", tmp);
741   }
742 }
743
744 void read_float64(FILE* fp, hdf_float64* value)
745 {
746   unsigned char* array = (unsigned char*)value;
747   for(int i = 0; i < sizeof(hdf_float64); i++) {
748     unsigned tmp;
749     fscanf(fp, " %x", &tmp); 
750     array[i] = (unsigned char)tmp;
751   }
752 }