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