Salome HOME
Porting KERNEL on new XML reader.
[modules/kernel.git] / src / HDFPersist / HDFascii.cc
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File      : SALOMEDS_Tool.cxx
21 //  Created   : Mon Oct 21 16:24:34 2002
22 //  Author    : Sergey RUIN
23
24 //  Project   : SALOME
25 //  Module    : SALOMEDS
26
27 #include "HDFOI.hxx"
28
29 //#include <OSD_Path.hxx>
30 //#include <OSD_File.hxx>
31 //#include <OSD_Protection.hxx>
32 //#include <OSD_Directory.hxx>
33 //#include <TCollection_AsciiString.hxx> 
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <fcntl.h>
38 #include <stdio.h>
39 #include <sys/stat.h>
40 #include <dirent.h>
41 #include <sstream>
42 #include <fstream>
43
44 #ifdef WNT
45 #include <io.h>
46 #include <time.h>
47 #endif
48
49 using namespace std;
50
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 char* 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 bool directoryExists(const char* dir);
65 bool createDirectory(const char* dir);
66 bool is_readable( const std::string & file );
67
68 #define MAX_STRING_SIZE   65535
69 #define MAX_ID_SIZE       20
70 #define NB_FLOAT_IN_ROW   3
71 #define NB_INTEGER_IN_ROW 9
72
73 #define ASCIIHDF_ID  "ASCIIHDF"
74 #define ATTRIBUTE_ID "ATTRIBUTE"
75 #define DATASET_ID   "DATASET"
76 #define GROUP_ID     "GROUP"
77
78 #define ASCIIHDF_ID_END  "ASCIIHDF_END"
79 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
80 #define DATASET_ID_END   "DATASET_END"
81 #define GROUP_ID_END     "GROUP_END"
82
83
84 //============================================================================
85 // function : isASCII
86 // purpose  : Returns True if the file is a converted to ASCII HDF file
87 //============================================================================
88 bool HDFascii::isASCII(const char* thePath) {
89   int fd;
90   if(!(fd = open(thePath, O_RDONLY))) return false;
91   char* aBuffer = new char[9];
92   aBuffer[8] = (char)0;
93   read(fd, aBuffer, 8); 
94   close(fd);
95
96   if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
97
98   return false;
99 }
100
101 //############################## HDF => ASCII ################################
102
103 //============================================================================
104 // function : ConvertFromHDFToASCII
105 // purpose  : Converts a file pointed by thePath to ASCII format
106 //            If isReplace is true the newly created file will replace the existent one.
107 //            If isReplace is false theExtension will be added to a created file name 
108 //            Returns the file name of ASCII file
109 //============================================================================
110 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
111                                       bool isReplace,
112                                       const char* theExtension)
113 {
114   //TCollection_AsciiString aPath((char*)thePath);
115   std::string aPath((char*)thePath);
116   if(!isReplace) { 
117     if(theExtension == NULL) aPath += ".asc";    
118     else aPath += (char*)theExtension;
119   }
120
121   //TCollection_AsciiString aFileName(aPath);
122   std::string aFileName(aPath);
123   if(isReplace) aFileName=aPath+".ascii_tmp";
124  
125   HDFfile *hdf_file = new HDFfile((char*)thePath); 
126   hdf_file->OpenOnDisk(HDF_RDONLY);
127
128   char name[HDF_NAME_MAX_LEN+1];
129   int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes(); 
130
131   //FILE* fp = fopen(aFileName.ToCString(), "w");
132   FILE* fp = fopen(aFileName.c_str(), "w");
133   fprintf(fp, "%s\n", ASCIIHDF_ID);
134   fprintf(fp, "%i\n", nbsons+nbAttr);
135
136   for(unsigned j=0; j<nbAttr; j++) {
137     char* attr_name = hdf_file->GetAttributeName(j);
138     HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
139     delete attr_name;
140     SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
141     hdf_attribute = 0;
142   }
143
144   //for (Standard_Integer i=0; i<nbsons; i++) {
145   for (int i=0; i<nbsons; i++) {
146     hdf_file->InternalObjectIndentify(i,name);
147     if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
148
149     hdf_object_type type = hdf_file->InternalObjectType(name);
150
151     if(type == HDF_DATASET) { 
152       HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
153       SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
154       hdf_dataset = 0; 
155     } else if(type == HDF_GROUP) {
156       HDFgroup *hdf_group = new HDFgroup(name, hdf_file); 
157       SaveGroupInASCIIfile(hdf_group, fp, 0);
158       hdf_group = 0;
159     }
160   }
161
162   fprintf(fp, "%s", ASCIIHDF_ID_END);
163
164   fclose(fp);
165
166   hdf_file->CloseOnDisk();
167   delete hdf_file;
168
169   if(isReplace) {
170 //    OSD_Path anOSDPath(aFileName);
171 //    OSD_File anOSDFile(anOSDPath);
172 //    if(anOSDFile.Exists())
173 //      anOSDFile.Move(aPath);
174 //    else 
175 //      return NULL;
176     if(access (aFileName.c_str() , F_OK ) == 0) {
177       rename(aFileName.c_str(), aPath.c_str());
178     }
179     else
180       return NULL;
181   }
182
183   //int length = strlen(aPath.ToCString());
184   int length = strlen(aPath.c_str());
185   char *new_str = new char[ 1+length ];
186   //strcpy(new_str , aPath.ToCString()) ;
187   strcpy(new_str , aPath.c_str()) ;
188
189   return new_str;
190 }
191
192
193 //============================================================================
194 // function : SaveGroupInASCIIfile
195 // purpose  : 
196 //============================================================================
197 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
198 {
199   hdf_group->OpenOnDisk();
200
201   //TCollection_AsciiString anIdent(ident, '\t');
202   std::ostringstream oss;
203   oss << ident;
204   std::string anIdent(oss.str());
205   int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes(); 
206
207   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID);*/
208   fprintf(fp, "%s\n", GROUP_ID);
209
210   char* name = makeName(hdf_group->GetName());
211
212   /*fprintf(fp, "%s%s %i\n", anIdent.ToCString(), name, nbsons+nbAttr);*/
213   fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
214   delete name;
215
216   for(unsigned j=0; j<nbAttr; j++) {
217     name = hdf_group->GetAttributeName(j);
218     HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
219     delete name;
220     SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
221     hdf_attribute = 0;
222   }
223
224   char objName[HDF_NAME_MAX_LEN+1];
225  
226   for (int i=0; i<nbsons; i++) {
227     hdf_group->InternalObjectIndentify(i, objName);
228
229     if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0)  continue;
230
231     hdf_object_type type = hdf_group->InternalObjectType(objName);
232
233     if  (type == HDF_DATASET) {
234       HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
235       SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
236       hdf_dataset = 0;
237     } else if (type == HDF_GROUP)   {      
238       HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
239       SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
240       hdf_subgroup = 0;
241     } 
242   }
243
244   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID_END);*/
245   fprintf(fp, "%s\n", GROUP_ID_END);
246
247   hdf_group->CloseOnDisk();  
248 }
249
250 //============================================================================
251 // function : SaveDatasetInASCIIfile
252 // purpose  : 
253 //============================================================================
254 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
255 {
256   hdf_dataset->OpenOnDisk();
257
258   long size =  hdf_dataset->GetSize();
259   long ndim = hdf_dataset->nDim(); //Get number of dimesions
260   hdf_size *dim = new hdf_size[ndim];
261   hdf_type type = hdf_dataset->GetType();
262   hdf_byte_order order = hdf_dataset->GetOrder();
263   int nbAttr = hdf_dataset->nAttributes(); 
264
265 //  TCollection_AsciiString anIdent(ident, '\t');
266 //  TCollection_AsciiString anIdentChild(ident+1, '\t');
267   std::ostringstream oss;
268   std::ostringstream oss2;
269   oss << ident;
270   oss2 << ident+1;
271   std::string anIdent(oss.str());
272   std::string anIdentChild(oss2.str());
273
274   char* name = makeName(hdf_dataset->GetName());
275
276   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID);*/
277   fprintf(fp, "%s\n", DATASET_ID);
278   /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, nbAttr);*/
279   fprintf(fp, "%s %i %i\n", name, type, nbAttr);
280   delete name;
281
282   hdf_dataset->GetDim(dim);
283   /*fprintf(fp, "%s %i\n", anIdentChild.ToCString(), ndim);*/
284   fprintf(fp, " %i\n", ndim);
285
286   for(int i = 0;i < ndim;i++) {
287     /*fprintf(fp, "%s%i",  anIdentChild.ToCString(), dim[i]);*/
288     fprintf(fp, " %i", dim[i]);
289   }
290
291   /*fprintf(fp, "%s\n", anIdentChild.ToCString());*/
292   fprintf(fp, "\n");
293   delete dim;
294
295   /*fprintf(fp, "%s%li:", anIdentChild.ToCString(), size);*/
296 //   fprintf(fp, "%li:", size);
297   fprintf(fp, "%li %i:", size, order);
298
299   if (type == HDF_STRING) {     
300     char* val = new char[size];
301     hdf_dataset->ReadFromDisk(val);
302     fwrite(val, 1, size, fp);
303     delete val;
304   } else if (type == HDF_FLOAT64) {
305     hdf_float64* val = new hdf_float64[size];
306     hdf_dataset->ReadFromDisk(val);
307     fprintf(fp, "\n");
308     for (int i = 0, j = 0; i < size; i++) {
309       write_float64(fp, &val[i]);
310       if(++j == NB_FLOAT_IN_ROW) {
311         fprintf(fp, "\n");
312         j = 0;
313       }
314       else fprintf(fp,"  ");
315     }
316     delete val;
317   } else if(type == HDF_INT64) {
318     hdf_int64* val = new hdf_int64[size];
319     hdf_dataset->ReadFromDisk(val);
320     fprintf(fp, "\n");
321     for (int i = 0, j = 0; i < size; i++) {
322       fprintf(fp, " %li", val[i]);
323       if(++j == NB_INTEGER_IN_ROW) {
324         fprintf(fp, "\n");
325         j = 0;
326       }
327     }
328     delete val;
329   } else if(type == HDF_INT32) {
330     hdf_int32* val = new hdf_int32[size];
331     hdf_dataset->ReadFromDisk(val);
332     fprintf(fp, "\n");
333     for (int i = 0, j = 0; i < size; i++) {
334       fprintf(fp, " %i", val[i]);
335       if(++j == NB_INTEGER_IN_ROW) {
336         fprintf(fp, "\n");
337         j = 0;
338       }
339     }
340     delete val;
341   }
342   
343   fprintf(fp, "\n");
344
345   for ( unsigned j=0; j<nbAttr; j++ )
346   {
347     name = hdf_dataset->GetAttributeName(j);
348     HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
349     delete name;
350     SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
351     hdf_attribute = 0;
352   }
353
354   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID_END); */
355   fprintf(fp, "%s\n", DATASET_ID_END);
356
357   hdf_dataset->CloseOnDisk(); 
358 }
359
360
361 //============================================================================
362 // function : SaveAttributeInASCIIfile
363 // purpose  : 
364 //============================================================================
365 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
366 {
367   hdf_attribute->OpenOnDisk();
368
369   hdf_type type = hdf_attribute->GetType();
370
371   //TCollection_AsciiString anIdent(ident, '\t');
372   //TCollection_AsciiString anIdentChild(ident+1, '\t');
373   std::ostringstream oss;
374   std::ostringstream oss2;
375   oss << ident;
376   oss2 << ident+1;
377   std::string anIdent(oss.str());
378   std::string anIdentChild(oss2.str());
379
380   char* name = makeName(hdf_attribute->GetName());
381   int size = hdf_attribute->GetSize();
382
383   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID);*/
384   fprintf(fp, "%s\n", ATTRIBUTE_ID);
385   /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, size);*/
386   fprintf(fp, "%s %i %i\n", name, type, size);
387
388   delete name;
389
390   if (type == HDF_STRING) {    
391     char* val = new char[size+1];
392     hdf_attribute->ReadFromDisk(val);
393     /*fprintf(fp, "%s:", anIdentChild.ToCString());*/
394     fprintf(fp, ":");
395     fwrite(val, 1, size, fp);
396     fprintf(fp, "\n");
397     delete val;
398   } else if (type == HDF_FLOAT64) {
399     hdf_float64 val;
400     hdf_attribute->ReadFromDisk(&val);
401     /*fprintf(fp, "%s",  anIdentChild.ToCString());*/
402     write_float64(fp, &val);
403     fprintf(fp, "\n");
404   } else if(type == HDF_INT64) {
405     hdf_int64 val;
406     hdf_attribute->ReadFromDisk(&val);
407     /*fprintf(fp, "%s%li \n", anIdentChild.ToCString(), val);*/
408     fprintf(fp, "%li \n", val);
409   } else if(type == HDF_INT32) {
410     hdf_int32 val;
411     hdf_attribute->ReadFromDisk(&val);
412     /*fprintf(fp, "%s%i \n", anIdentChild.ToCString(), val);*/
413     fprintf(fp, "%i \n", val);
414   }
415
416   /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID_END);*/
417   fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
418
419   hdf_attribute->CloseOnDisk();  
420 }
421
422 //############################## ASCII => HDF ################################
423
424 //============================================================================
425 // function : ConvertFromASCIIToHDF
426 // purpose  : Converts a file pointed by thePath to HDF format
427 //            Returns a name of directory where a created HDF file is placed
428 //            The created file is named "hdf_from_ascii.hdf"
429 //============================================================================
430 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
431 {
432   // Get a temporary directory to store a file
433   //TCollection_AsciiString aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
434   std::string aTmpDir = GetTmpDir();
435   std::string aFileName("hdf_from_ascii.hdf");
436   // Build a full file name of temporary file
437   //TCollection_AsciiString aFullName = aTmpDir + aFileName;
438   std::string aFullName = aTmpDir + aFileName;
439
440   //HDFfile *hdf_file = new HDFfile(aFullName.ToCString()); 
441   HDFfile *hdf_file = new HDFfile((char *) aFullName.c_str()); 
442   hdf_file->CreateOnDisk();
443   
444   FILE *fp = fopen(thePath, "r");
445   if(!fp) return NULL;
446
447   char type[9];
448   int nbsons, i;
449   fscanf(fp, "%s", type);
450   fscanf(fp, "%i",&nbsons);
451
452   if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
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_file, fp)) {
460         cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
461         return NULL;
462       }
463     }
464     else if(strcmp(id_of_begin, DATASET_ID) == 0) {
465       if(!CreateDatasetFromASCII(hdf_file, fp)) {
466         cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
467         return NULL;
468       }
469     }
470     else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
471       if(!CreateAttributeFromASCII(hdf_file, fp)) {
472         cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
473         return NULL;
474       }
475     }
476     else 
477       cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl; 
478   }
479
480   char id_of_end[MAX_ID_SIZE];
481   fscanf(fp, "%s", id_of_end);
482   if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
483     cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
484     return false;  
485   }
486
487   hdf_file->CloseOnDisk();
488   delete hdf_file;
489
490   //int length = strlen(aTmpDir.ToCString());
491   int length = strlen(aTmpDir.c_str());
492   cerr << "length : " << length << endl;
493   char *new_str = new char[ 1+length ];
494   //strcpy(new_str , aTmpDir.ToCString()) ;
495   strcpy(new_str , aTmpDir.c_str()) ;
496
497   cerr << "test ::: " <<  aTmpDir << endl;
498   cerr << "test ::: " << new_str << endl;
499
500   return new_str;
501 }
502
503
504 //============================================================================
505 // function : CreateGroupFromASCII
506 // purpose  : Creates a HDF group from a set attributes situated under theLabel
507 //============================================================================
508 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
509 {
510   char name[HDF_NAME_MAX_LEN+1];
511   int nbsons, i;
512   fscanf(fp, "%s %i\n", name, &nbsons);  
513
514   char* new_name = restoreName(name);
515
516   HDFgroup* hdf_group = new HDFgroup(new_name, father);
517
518   delete new_name;
519
520   hdf_group->CreateOnDisk();
521
522   for(i = 0; i < nbsons; i++) {
523     char id_of_begin[MAX_ID_SIZE];
524     fscanf(fp, "%s\n", id_of_begin);
525     
526     if(strcmp(id_of_begin, GROUP_ID) == 0) {
527       if(!CreateGroupFromASCII(hdf_group, fp)) {
528         cout << "Can not create subgroup " << i << " for group " << name << endl;
529         return false;
530       }
531     }
532     else if(strcmp(id_of_begin, DATASET_ID) == 0) {
533       if(!CreateDatasetFromASCII(hdf_group, fp)) {
534         cout << "Can not create dataset " << i << " for group " << name << endl;
535         return false;
536       }
537     }
538     else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
539       if(!CreateAttributeFromASCII(hdf_group, fp)) {
540         cout << "Can not create attribute " << i << " for group " << name << endl;
541         return false;
542       }
543     }
544     else 
545       cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl; 
546   }
547   
548   hdf_group->CloseOnDisk();
549   hdf_group = 0; //will be deleted by father destructor
550
551   char id_of_end[MAX_ID_SIZE];
552   fscanf(fp, "%s\n", id_of_end);
553   if(strcmp(id_of_end, GROUP_ID_END) != 0) {
554     cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
555     return false;
556   }
557
558   return true;
559 }
560
561
562 //============================================================================
563 // function : CreateDatasetFromASCII
564 // purpose  : Creates a HDF dataset from a set attributes situated under theLabel
565 //============================================================================
566 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
567 {
568   char name[HDF_NAME_MAX_LEN+1];
569   hdf_type type;
570   hdf_byte_order order;
571   int nbDim, nbAttr;
572   long i, size;
573
574   fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
575   char* new_name = restoreName(name);
576
577   fscanf(fp, "%i\n", &nbDim);
578
579   hdf_size* sizeArray = new hdf_size[nbDim];
580   int dim = 0;
581   for(i = 0; i<nbDim; i++) {
582     fscanf(fp, "%i\n", &dim);
583     sizeArray[i] = dim;
584   }
585  
586   // order (2-d member) was not written in earlier versions
587   char tmp;
588   int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
589   if ( nbRead < 2 ) { // fscanf stops before ":"
590     fscanf(fp, "%c", &tmp);
591     order = H5T_ORDER_NONE;
592   }
593   if ( type != HDF_FLOAT64 )  // use order only for FLOAT64
594     order = H5T_ORDER_NONE;
595
596   HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
597   delete new_name;
598   delete sizeArray;
599
600   hdf_dataset->CreateOnDisk();
601
602   if (type == HDF_STRING) {     
603     char *val = new char[size+1];
604     fread(val, 1, size, fp);
605     hdf_dataset->WriteOnDisk(val);
606     delete val;
607   } else if (type == HDF_FLOAT64) {
608     hdf_float64* val = new hdf_float64[size];
609     for(i=0; i<size; i++) {
610       read_float64(fp, &(val[i]));
611     }
612     hdf_dataset->WriteOnDisk(val);
613     delete val;
614   } else if(type == HDF_INT64) {
615     hdf_int64* val = new hdf_int64[size];
616     for(i=0; i<size; i++) {
617       fscanf(fp, " %li", &(val[i]));
618     }
619     hdf_dataset->WriteOnDisk(val);
620     delete val;
621   } else if(type == HDF_INT32) {
622     hdf_int32* val = new hdf_int32[size];
623     for(i=0; i<size; i++) {
624       fscanf(fp, " %i", &(val[i]));
625     }
626     hdf_dataset->WriteOnDisk(val);
627     delete val;
628   }
629
630   char token[MAX_ID_SIZE];
631
632   for(i = 0; i < nbAttr; i++) {
633     fscanf(fp, "%s\n", token);
634     
635     if(strcmp(token, ATTRIBUTE_ID) == 0) {
636       if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
637         cout << "Can not create attribute " << i << " for dataset " << name << endl;
638         return false;
639       }
640     }
641     else {
642       cout << "CreateGroupFromASCII : Unrecognized type " << token << endl; 
643       return false;
644     }
645   }
646   
647   fscanf(fp, "%s\n", token);
648   if(strcmp(token, DATASET_ID_END) != 0) {
649     cout << "CreateDatasetFromASCII : Invalid end token : " << token << endl;
650     return false;
651   }
652
653   hdf_dataset->CloseOnDisk();
654   hdf_dataset = 0; //will be deleted by father destructor
655
656   return true;
657 }
658
659
660 //============================================================================
661 // function : CreateAttributeFromASCII
662 // purpose  : Creates a HDF attribute from a set attributes situated under theLabel
663 //============================================================================
664 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
665 {
666   char name[HDF_NAME_MAX_LEN+1];
667
668   hdf_type type;
669   int size;
670   fscanf(fp, "%s %i %i\n", name, &type, &size);
671   char* new_name = restoreName(name);
672   HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
673
674   hdf_attribute->CreateOnDisk();
675
676   delete new_name;
677   
678   if (type == HDF_STRING) {     
679     char tmp;
680     fscanf(fp, "%c", &tmp);
681     char *val = new char[size+1];
682     val[size] = (char)0;
683     fread(val, 1, size, fp);
684     hdf_attribute->WriteOnDisk(val);
685     delete val;
686   } else if (type == HDF_FLOAT64) {
687     hdf_float64 val;
688     read_float64(fp, &val);
689     hdf_attribute->WriteOnDisk(&val);
690   } else if(type == HDF_INT64) {
691     hdf_int64 val;
692     fscanf(fp, "%li", &val);
693     hdf_attribute->WriteOnDisk(&val);
694   } else if(type == HDF_INT32) {
695     hdf_int32 val;
696     fscanf(fp, "%i", &val);
697     hdf_attribute->WriteOnDisk(&val);
698   }
699   
700   hdf_attribute->CloseOnDisk();
701   hdf_attribute = 0; //will be deleted by father destructor
702
703
704   char id_of_end[MAX_ID_SIZE];
705   fscanf(fp, "%s\n", id_of_end);
706   if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
707     cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << endl;
708     return false;
709   }
710
711   return true;
712 }
713
714
715 //============================================================================
716 // function : GetTempDir
717 // purpose  : Return a temp directory to store created files like "/tmp/sub_dir/" 
718 //============================================================================ 
719 char* GetTmpDir()
720 {
721   //Find a temporary directory to store a file
722
723   //TCollection_AsciiString aTmpDir;
724   std::string aTmpDir;
725
726 #ifdef WNT
727   char *aTmp;
728   aTmp = getenv("TMP");
729   if(aTmp != NULL) {
730 //      aTmpDir = TCollection_AsciiString(aTmp);
731         aTmpDir = std::string(aTmp);
732   }
733   else {
734 //      aTmpDir = TCollection_AsciiString("C:\\");
735         aTmpDir = std::string("C:\\");
736   }
737 #else
738   //aTmpDir = TCollection_AsciiString("/tmp/");
739   aTmpDir = std::string("/tmp/");
740 #endif
741
742   srand((unsigned int)time(NULL));
743
744   int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
745 //  TCollection_AsciiString aSubDir(aRND);
746 //  if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
747   std::ostringstream oss;
748   oss << aRND;
749   std::string aSubDir(oss.str());
750   if(aSubDir.length() <= 1) aSubDir = std::string("123409876");
751
752   aTmpDir += aSubDir; //Get RND sub directory
753
754 #ifdef WIN32
755 //  if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
756   if(aTmpDir[aTmpDir.length()-1] != '\\') aTmpDir+='\\';
757 #else
758 //  if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
759   if(aTmpDir[aTmpDir.length()-1] != '/') aTmpDir+='/';
760 #endif
761
762 //  OSD_Path aPath(aTmpDir);
763 //  OSD_Directory aDir(aPath);
764   std::string aDir(aTmpDir);
765
766   //std::cerr << "temp dir .... : " << aTmpDir << std::endl;
767
768   for(aRND = 0; directoryExists(aDir.c_str()); aRND++) {
769     //aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND));  //Build a unique directory name
770     aTmpDir.insert((aTmpDir.length() - 1), oss.str());  //Build a unique directory name
771     std::cerr << "Tempory directory exist, changing name ..." << std::endl;
772     std::cerr << "temp dir .... : " << aTmpDir << std::endl;
773     aDir = std::string(aTmpDir);
774 //    aPath = OSD_Path(aTmpDir);
775 //    aDir = OSD_Directory(aPath);
776   }
777
778   //OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
779   //aDir.Build(aProtection);
780   createDirectory(aDir.c_str());
781   //int length = strlen(aTmpDir.ToCString());
782   int length = strlen(aTmpDir.c_str());
783   char *new_str = new char[ 1+length ];
784   //strcpy(new_str , aTmpDir.ToCString());
785   strcpy(new_str , aTmpDir.c_str());
786   return new_str;
787 }
788
789 char* makeName(char* name)
790 {
791   //TCollection_AsciiString aName(name), aNewName;
792   std::string aName(name), aNewName;
793   //Standard_Integer i, length = aName.Length();
794   int i, length = aName.length();
795   char replace = (char)19;
796
797   for(i=1; i<=length; i++) {
798     //if(aName.Value(i) == ' ') aNewName+=replace;
799     //else aNewName += aName.Value(i);
800     if(aName[i] == ' ') aNewName+=replace;
801     else aNewName += aName[i];
802   }
803
804   //length = strlen(aNewName.ToCString());
805   length = strlen(aNewName.c_str());
806   char *new_str = new char[ 1+length ];
807   //strcpy(new_str , aNewName.ToCString()) ;
808   strcpy(new_str , aNewName.c_str()) ;
809   return new_str;
810 }
811
812 char* restoreName(char* name)
813 {
814   //TCollection_AsciiString aName(name), aNewName;
815   std::string aName(name), aNewName;
816   //Standard_Integer i, length = aName.Length();
817   int i, length = aName.length();
818   char replace = (char)19;
819
820   for(i=1; i<=length; i++) {
821     //if(aName.Value(i) == replace) aNewName+=' ';
822     //else aNewName += aName.Value(i);
823     if(aName[i] == replace) aNewName+=' ';
824     else aNewName += aName[i];
825   }
826
827   //length = strlen(aNewName.ToCString());
828   length = strlen(aNewName.c_str());
829   char *new_str = new char[ 1+length ];
830   //strcpy(new_str , aNewName.ToCString()) ;
831   strcpy(new_str , aNewName.c_str()) ;
832   return new_str;
833 }
834
835 void write_float64(FILE* fp, hdf_float64* value)
836 {
837   unsigned char* array = (unsigned char*)value;
838   for(int i = 0; i < sizeof(hdf_float64); i++) {
839     unsigned tmp = (unsigned short)array[i];
840     fprintf(fp, " %2x", tmp);
841   }
842 }
843
844 void read_float64(FILE* fp, hdf_float64* value)
845 {
846   unsigned char* array = (unsigned char*)value;
847   for(int i = 0; i < sizeof(hdf_float64); i++) {
848     unsigned tmp;
849     fscanf(fp, " %x", &tmp); 
850     array[i] = (unsigned char)tmp;
851   }
852 }
853
854 bool directoryExists(const char* dir)
855 {
856     DIR* dhandle = opendir(dir);
857
858     if (dhandle != NULL)
859     {
860         closedir(dhandle);
861         return true;
862     }
863     else
864     {
865         return false;
866     }
867 }
868
869 bool createDirectory(const char* dir)
870 {
871     return mkdir(dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0;
872 }
873
874 bool is_readable( const std::string & file ) 
875
876     std::ifstream fichier( file.c_str() ); 
877     return !fichier.fail(); 
878 }