Salome HOME
merge from branch BR_V5_DEV
[modules/kernel.git] / src / HDFPersist / HDFascii.cc
1 //  Copyright (C) 2007-2008  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 //  File      : SALOMEDS_Tool.cxx
23 //  Created   : Mon Oct 21 16:24:34 2002
24 //  Author    : Sergey RUIN
25 //  Project   : SALOME
26 //  Module    : SALOMEDS
27 //
28 #include "HDFOI.hxx"
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <stdio.h>
34 #include <string>
35
36 #ifdef WIN32
37 #include <io.h>
38 #include <time.h>
39 #include <windows.h>
40 #define dir_separator '\\'
41 #else
42 #define dir_separator '/'
43 #endif
44
45 using namespace std;
46
47 void Move(const string& fName, const string& fNameDst);
48 bool Exists(const string thePath); 
49 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
50 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
51 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
52
53 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
54 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
55 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
56
57 string GetTmpDir();
58 char* makeName(char* name);
59 char* restoreName(char* name);
60 void write_float64(FILE* fp, hdf_float64* value);
61 void read_float64(FILE* fp, hdf_float64* value);
62
63 #define MAX_STRING_SIZE   65535
64 #define MAX_ID_SIZE       20
65 #define NB_FLOAT_IN_ROW   3
66 #define NB_INTEGER_IN_ROW 9
67
68 #define ASCIIHDF_ID  "ASCIIHDF"
69 #define ATTRIBUTE_ID "ATTRIBUTE"
70 #define DATASET_ID   "DATASET"
71 #define GROUP_ID     "GROUP"
72
73 #define ASCIIHDF_ID_END  "ASCIIHDF_END"
74 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
75 #define DATASET_ID_END   "DATASET_END"
76 #define GROUP_ID_END     "GROUP_END"
77
78
79 //============================================================================
80 // function : isASCII
81 // purpose  : Returns True if the file is a converted to ASCII HDF file
82 //============================================================================
83 bool HDFascii::isASCII(const char* thePath) {
84   int fd;
85   if(!(fd = open(thePath, O_RDONLY))) return false;
86   char* aBuffer = new char[9];
87   aBuffer[8] = (char)0;
88   read(fd, aBuffer, 8); 
89   close(fd);
90
91   if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
92
93   return false;
94 }
95
96 //############################## HDF => ASCII ################################
97
98 //============================================================================
99 // function : ConvertFromHDFToASCII
100 // purpose  : Converts a file pointed by thePath to ASCII format
101 //            If isReplace is true the newly created file will replace the existent one.
102 //            If isReplace is false theExtension will be added to a created file name 
103 //            Returns the file name of ASCII file
104 //============================================================================
105 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
106                                       bool isReplace,
107                                       const char* theExtension)
108 {
109   string aPath(thePath);
110   if(!isReplace) { 
111     if(theExtension == NULL) aPath += ".asc";    
112     else aPath += (char*)theExtension;
113   }
114
115   string aFileName(aPath);
116   if(isReplace) aFileName=aPath+".ascii_tmp";
117  
118   HDFfile *hdf_file = new HDFfile((char*)thePath); 
119   hdf_file->OpenOnDisk(HDF_RDONLY);
120
121   char name[HDF_NAME_MAX_LEN+1];
122   int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes(); 
123
124   FILE* fp = fopen(aFileName.c_str(), "w");
125   fprintf(fp, "%s\n", ASCIIHDF_ID);
126   fprintf(fp, "%i\n", nbsons+nbAttr);
127
128   for(unsigned j=0; j<nbAttr; j++) {
129     char* attr_name = hdf_file->GetAttributeName(j);
130     HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
131     delete attr_name;
132     SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
133     hdf_attribute = 0;
134   }
135
136   for (int i=0; i<nbsons; i++) {
137     hdf_file->InternalObjectIndentify(i,name);
138     if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
139
140     hdf_object_type type = hdf_file->InternalObjectType(name);
141
142     if(type == HDF_DATASET) { 
143       HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
144       SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
145       hdf_dataset = 0; 
146     } else if(type == HDF_GROUP) {
147       HDFgroup *hdf_group = new HDFgroup(name, hdf_file); 
148       SaveGroupInASCIIfile(hdf_group, fp, 0);
149       hdf_group = 0;
150     }
151   }
152
153   fprintf(fp, "%s", ASCIIHDF_ID_END);
154
155   fclose(fp);
156
157   hdf_file->CloseOnDisk();
158   delete hdf_file;
159
160   if(isReplace) {
161     if(Exists(aFileName))
162       Move(aFileName, aPath);
163     else 
164       return NULL;
165   }
166
167   int length = strlen(aPath.c_str());
168   char *new_str = new char[ 1+length ];
169   strcpy(new_str , aPath.c_str()) ;
170
171   return new_str;
172 }
173
174
175 //============================================================================
176 // function : SaveGroupInASCIIfile
177 // purpose  : 
178 //============================================================================
179 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
180 {
181   hdf_group->OpenOnDisk();
182
183   int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes(); 
184
185   fprintf(fp, "%s\n", GROUP_ID);
186
187   char* name = makeName(hdf_group->GetName());
188
189   fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
190   delete name;
191
192   for(unsigned j=0; j<nbAttr; j++) {
193     name = hdf_group->GetAttributeName(j);
194     HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
195     delete name;
196     SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
197     hdf_attribute = 0;
198   }
199
200   char objName[HDF_NAME_MAX_LEN+1];
201  
202   for (int i=0; i<nbsons; i++) {
203     hdf_group->InternalObjectIndentify(i, objName);
204
205     if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0)  continue;
206
207     hdf_object_type type = hdf_group->InternalObjectType(objName);
208
209     if  (type == HDF_DATASET) {
210       HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
211       SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
212       hdf_dataset = 0;
213     } else if (type == HDF_GROUP)   {      
214       HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
215       SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
216       hdf_subgroup = 0;
217     } 
218   }
219
220   fprintf(fp, "%s\n", GROUP_ID_END);
221
222   hdf_group->CloseOnDisk();  
223 }
224
225 //============================================================================
226 // function : SaveDatasetInASCIIfile
227 // purpose  : 
228 //============================================================================
229 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
230 {
231   hdf_dataset->OpenOnDisk();
232
233   long size =  hdf_dataset->GetSize();
234   long ndim = hdf_dataset->nDim(); //Get number of dimesions
235   hdf_size *dim = new hdf_size[ndim];
236   hdf_type type = hdf_dataset->GetType();
237   hdf_byte_order order = hdf_dataset->GetOrder();
238   int nbAttr = hdf_dataset->nAttributes(); 
239
240   char* name = makeName(hdf_dataset->GetName());
241
242   fprintf(fp, "%s\n", DATASET_ID);
243   fprintf(fp, "%s %i %i\n", name, type, nbAttr);
244   delete name;
245
246   hdf_dataset->GetDim(dim);
247   fprintf(fp, " %i\n", ndim);
248
249   for(int i = 0;i < ndim;i++) {
250     fprintf(fp, " %i", dim[i]);
251   }
252
253   fprintf(fp, "\n");
254   delete dim;
255
256   fprintf(fp, "%li %i:", size, order);
257
258   if (type == HDF_STRING) {     
259     char* val = new char[size];
260     hdf_dataset->ReadFromDisk(val);
261     fwrite(val, 1, size, fp);
262     delete val;
263   } else if (type == HDF_FLOAT64) {
264     hdf_float64* val = new hdf_float64[size];
265     hdf_dataset->ReadFromDisk(val);
266     fprintf(fp, "\n");
267     for (int i = 0, j = 0; i < size; i++) {
268       write_float64(fp, &val[i]);
269       if(++j == NB_FLOAT_IN_ROW) {
270         fprintf(fp, "\n");
271         j = 0;
272       }
273       else fprintf(fp,"  ");
274     }
275     delete val;
276   } else if(type == HDF_INT64) {
277     hdf_int64* val = new hdf_int64[size];
278     hdf_dataset->ReadFromDisk(val);
279     fprintf(fp, "\n");
280     for (int i = 0, j = 0; i < size; i++) {
281       fprintf(fp, " %li", val[i]);
282       if(++j == NB_INTEGER_IN_ROW) {
283         fprintf(fp, "\n");
284         j = 0;
285       }
286     }
287     delete val;
288   } else if(type == HDF_INT32) {
289     hdf_int32* val = new hdf_int32[size];
290     hdf_dataset->ReadFromDisk(val);
291     fprintf(fp, "\n");
292     for (int i = 0, j = 0; i < size; i++) {
293       fprintf(fp, " %i", val[i]);
294       if(++j == NB_INTEGER_IN_ROW) {
295         fprintf(fp, "\n");
296         j = 0;
297       }
298     }
299     delete val;
300   }
301   
302   fprintf(fp, "\n");
303
304   for ( unsigned j=0; j<nbAttr; j++ )
305   {
306     name = hdf_dataset->GetAttributeName(j);
307     HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
308     delete name;
309     SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
310     hdf_attribute = 0;
311   }
312
313   fprintf(fp, "%s\n", DATASET_ID_END);
314
315   hdf_dataset->CloseOnDisk(); 
316 }
317
318
319 //============================================================================
320 // function : SaveAttributeInASCIIfile
321 // purpose  : 
322 //============================================================================
323 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
324 {
325   hdf_attribute->OpenOnDisk();
326
327   hdf_type type = hdf_attribute->GetType();
328
329   char* name = makeName(hdf_attribute->GetName());
330   int size = hdf_attribute->GetSize();
331
332   fprintf(fp, "%s\n", ATTRIBUTE_ID);
333   fprintf(fp, "%s %i %i\n", name, type, size);
334
335   delete name;
336
337   if (type == HDF_STRING) {    
338     char* val = new char[size+1];
339     hdf_attribute->ReadFromDisk(val);
340     fprintf(fp, ":");
341     fwrite(val, 1, size, fp);
342     fprintf(fp, "\n");
343     delete val;
344   } else if (type == HDF_FLOAT64) {
345     hdf_float64 val;
346     hdf_attribute->ReadFromDisk(&val);
347     write_float64(fp, &val);
348     fprintf(fp, "\n");
349   } else if(type == HDF_INT64) {
350     hdf_int64 val;
351     hdf_attribute->ReadFromDisk(&val);
352     fprintf(fp, "%li \n", val);
353   } else if(type == HDF_INT32) {
354     hdf_int32 val;
355     hdf_attribute->ReadFromDisk(&val);
356     fprintf(fp, "%i \n", val);
357   }
358
359   fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
360
361   hdf_attribute->CloseOnDisk();  
362 }
363
364 //############################## ASCII => HDF ################################
365
366 //============================================================================
367 // function : ConvertFromASCIIToHDF
368 // purpose  : Converts a file pointed by thePath to HDF format
369 //            Returns a name of directory where a created HDF file is placed
370 //            The created file is named "hdf_from_ascii.hdf"
371 //============================================================================
372 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
373 {
374   // Get a temporary directory to store a file
375   string aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
376   // Build a full file name of temporary file
377   string aFullName = aTmpDir + aFileName;
378
379   HDFfile *hdf_file = new HDFfile((char*)aFullName.c_str()); 
380   hdf_file->CreateOnDisk();
381   
382   FILE *fp = fopen(thePath, "r");
383   if(!fp) return NULL;
384
385   char type[9];
386   int nbsons, i;
387   fscanf(fp, "%s", type);
388   fscanf(fp, "%i",&nbsons);
389
390   if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
391
392   for(i = 0; i < nbsons; i++) {
393     char id_of_begin[MAX_ID_SIZE];
394     fscanf(fp, "%s\n", id_of_begin);
395
396     if(strcmp(id_of_begin, GROUP_ID) == 0) {
397       if(!CreateGroupFromASCII(hdf_file, fp)) {
398         cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
399         return NULL;
400       }
401     }
402     else if(strcmp(id_of_begin, DATASET_ID) == 0) {
403       if(!CreateDatasetFromASCII(hdf_file, fp)) {
404         cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
405         return NULL;
406       }
407     }
408     else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
409       if(!CreateAttributeFromASCII(hdf_file, fp)) {
410         cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
411         return NULL;
412       }
413     }
414     else 
415       cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl; 
416   }
417
418   char id_of_end[MAX_ID_SIZE];
419   fscanf(fp, "%s", id_of_end);
420   if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
421     cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
422     return false;  
423   }
424
425   hdf_file->CloseOnDisk();
426   delete hdf_file;
427
428   int length = strlen(aTmpDir.c_str());
429   char *new_str = new char[ 1+length ];
430   strcpy(new_str , aTmpDir.c_str()) ;
431
432   return new_str;
433 }
434
435
436 //============================================================================
437 // function : CreateGroupFromASCII
438 // purpose  : Creates a HDF group from a set attributes situated under theLabel
439 //============================================================================
440 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
441 {
442   char name[HDF_NAME_MAX_LEN+1];
443   int nbsons, i;
444   fscanf(fp, "%s %i\n", name, &nbsons);  
445
446   char* new_name = restoreName(name);
447
448   HDFgroup* hdf_group = new HDFgroup(new_name, father);
449
450   delete new_name;
451
452   hdf_group->CreateOnDisk();
453
454   for(i = 0; i < nbsons; i++) {
455     char id_of_begin[MAX_ID_SIZE];
456     fscanf(fp, "%s\n", id_of_begin);
457     
458     if(strcmp(id_of_begin, GROUP_ID) == 0) {
459       if(!CreateGroupFromASCII(hdf_group, fp)) {
460         cout << "Can not create subgroup " << i << " for group " << name << endl;
461         return false;
462       }
463     }
464     else if(strcmp(id_of_begin, DATASET_ID) == 0) {
465       if(!CreateDatasetFromASCII(hdf_group, fp)) {
466         cout << "Can not create dataset " << i << " for group " << name << endl;
467         return false;
468       }
469     }
470     else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
471       if(!CreateAttributeFromASCII(hdf_group, fp)) {
472         cout << "Can not create attribute " << i << " for group " << name << endl;
473         return false;
474       }
475     }
476     else 
477       cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl; 
478   }
479   
480   hdf_group->CloseOnDisk();
481   hdf_group = 0; //will be deleted by father destructor
482
483   char id_of_end[MAX_ID_SIZE];
484   fscanf(fp, "%s\n", id_of_end);
485   if(strcmp(id_of_end, GROUP_ID_END) != 0) {
486     cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
487     return false;
488   }
489
490   return true;
491 }
492
493
494 //============================================================================
495 // function : CreateDatasetFromASCII
496 // purpose  : Creates a HDF dataset from a set attributes situated under theLabel
497 //============================================================================
498 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
499 {
500   char name[HDF_NAME_MAX_LEN+1];
501   hdf_type type;
502   hdf_byte_order order;
503   int nbDim, nbAttr;
504   long i, size;
505
506   fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
507   char* new_name = restoreName(name);
508
509   fscanf(fp, "%i\n", &nbDim);
510
511   hdf_size* sizeArray = new hdf_size[nbDim];
512   int dim = 0;
513   for(i = 0; i<nbDim; i++) {
514     fscanf(fp, "%i\n", &dim);
515     sizeArray[i] = dim;
516   }
517  
518   // order (2-d member) was not written in earlier versions
519   char tmp;
520   int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
521   if ( nbRead < 2 ) { // fscanf stops before ":"
522     fscanf(fp, "%c", &tmp);
523     order = H5T_ORDER_NONE;
524   }
525   if ( type != HDF_FLOAT64 )  // use order only for FLOAT64
526     order = H5T_ORDER_NONE;
527
528   HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
529   delete new_name;
530   delete sizeArray;
531
532   hdf_dataset->CreateOnDisk();
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 string GetTmpDir()
652 {
653
654  //Find a temporary directory to store a file
655
656   string aTmpDir;
657
658   char *Tmp_dir = getenv("SALOME_TMP_DIR");
659   if(Tmp_dir != NULL) {
660     aTmpDir = string(Tmp_dir);
661     if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
662 /*#ifdef WIN32
663     if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
664 #else
665     if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
666 #endif*/
667   }
668   else {
669 #ifdef WIN32
670     aTmpDir = string("C:\\");
671 #else
672     aTmpDir = string("/tmp/");
673 #endif
674   }
675
676   srand((unsigned int)time(NULL));
677   int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
678   char buffer[127];
679   sprintf(buffer, "%d", aRND);
680   string aSubDir(buffer);
681   if(aSubDir.size() <= 1) aSubDir = string("123409876");
682
683   aTmpDir += aSubDir; //Get RND sub directory
684
685   if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
686 /*
687 #ifdef WIN32
688   if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
689 #else
690   if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
691 #endif
692   */
693
694   string aDir = aTmpDir;
695   
696   for(aRND = 0; Exists(aDir); aRND++) {
697     sprintf(buffer, "%d", aRND);
698     aDir = aTmpDir+buffer;  //Build a unique directory name
699   }
700
701 #ifdef WIN32
702   //fuction CreateDirectory create only final directory, but not intermediate
703   CreateDirectory(aTmpDir.c_str(), NULL);
704   CreateDirectory(aDir.c_str(), NULL);
705 #else
706   mkdir(aDir.c_str(), 0x1ff); 
707 #endif
708
709   return aDir + dir_separator;
710 }
711
712 char* makeName(char* name)
713 {
714   string aName(name), aNewName;
715   int i, length = aName.size();
716   char replace = (char)19;
717
718   for(i=0; i<length; i++) {
719     if(aName[i] == ' ') aNewName+=replace;
720     else aNewName += aName[i];
721   }
722
723   length = strlen(aNewName.c_str());
724   char *new_str = new char[ 1+length ];
725   strcpy(new_str , aNewName.c_str()) ;
726   return new_str;
727 }
728
729 char* restoreName(char* name)
730 {
731   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] == replace) aNewName+=' ';
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 void write_float64(FILE* fp, hdf_float64* value)
747 {
748   unsigned char* array = (unsigned char*)value;
749   for(int i = 0; i < sizeof(hdf_float64); i++) {
750     unsigned tmp = (unsigned short)array[i];
751     fprintf(fp, " %2x", tmp);
752   }
753 }
754
755 void read_float64(FILE* fp, hdf_float64* value)
756 {
757   unsigned char* array = (unsigned char*)value;
758   for(int i = 0; i < sizeof(hdf_float64); i++) {
759     unsigned tmp;
760     fscanf(fp, " %x", &tmp); 
761     array[i] = (unsigned char)tmp;
762   }
763 }
764
765 bool Exists(const string thePath) 
766 {
767 #ifdef WIN32 
768   if (  GetFileAttributes (  thePath.c_str()  ) == 0xFFFFFFFF  ) { 
769     if (  GetLastError () != ERROR_FILE_NOT_FOUND  ) {
770       return false;
771     }
772   }
773 #else 
774   int status = access ( thePath.c_str() , F_OK ); 
775   if (status != 0) return false;
776 #endif
777   return true;
778 }
779
780 void Move(const string& fName, const string& fNameDst)
781
782 #ifdef WIN32
783   MoveFileEx (fName.c_str(), fNameDst.c_str(),MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
784 #else
785   rename(fName.c_str(), fNameDst.c_str());
786 #endif
787 }
788