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