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