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