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