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