2 // File : SALOMEDS_Tool.cxx
3 // Created : Mon Oct 21 16:24:34 2002
4 // Author : Sergey RUIN
8 // Copyright : Open CASCADE
12 #include <OSD_Path.hxx>
13 #include <OSD_File.hxx>
14 #include <OSD_Protection.hxx>
15 #include <OSD_Directory.hxx>
16 #include <TCollection_AsciiString.hxx>
23 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
24 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
25 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
27 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
28 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
29 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
32 char* makeName(char* name);
33 char* restoreName(char* name);
34 void write_float64(FILE* fp, hdf_float64* value);
35 void read_float64(FILE* fp, hdf_float64* value);
37 #define MAX_STRING_SIZE 65535
38 #define MAX_ID_SIZE 20
39 #define NB_FLOAT_IN_ROW 3
40 #define NB_INTEGER_IN_ROW 9
42 #define ASCIIHDF_ID "ASCIIHDF"
43 #define ATTRIBUTE_ID "ATTRIBUTE"
44 #define DATASET_ID "DATASET"
45 #define GROUP_ID "GROUP"
47 #define ASCIIHDF_ID_END "ASCIIHDF_END"
48 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
49 #define DATASET_ID_END "DATASET_END"
50 #define GROUP_ID_END "GROUP_END"
53 //============================================================================
55 // purpose : Returns True if the file is a converted to ASCII HDF file
56 //============================================================================
57 bool HDFascii::isASCII(const char* thePath) {
59 if(!(fd = open(thePath, O_RDONLY))) return false;
60 char* aBuffer = new char[9];
65 if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
70 //############################## HDF => ASCII ################################
72 //============================================================================
73 // function : ConvertFromHDFToASCII
74 // purpose : Converts a file pointed by thePath to ASCII format
75 // If isReplace is true the newly created file will replace the existent one.
76 // If isReplace is false theExtension will be added to a created file name
77 // Returns the file name of ASCII file
78 //============================================================================
79 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
81 const char* theExtension)
83 TCollection_AsciiString aPath((char*)thePath);
85 if(theExtension == NULL) aPath += ".asc";
86 else aPath += (char*)theExtension;
89 TCollection_AsciiString aFileName(aPath);
90 if(isReplace) aFileName=aPath+".ascii_tmp";
92 HDFfile *hdf_file = new HDFfile((char*)thePath);
93 hdf_file->OpenOnDisk(HDF_RDONLY);
95 char name[HDF_NAME_MAX_LEN+1];
96 int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes();
98 FILE* fp = fopen(aFileName.ToCString(), "w");
99 fprintf(fp, "%s\n", ASCIIHDF_ID);
100 fprintf(fp, "%i\n", nbsons+nbAttr);
102 for(unsigned j=0; j<nbAttr; j++) {
103 char* attr_name = hdf_file->GetAttributeName(j);
104 HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
106 SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
110 for (Standard_Integer i=0; i<nbsons; i++) {
111 hdf_file->InternalObjectIndentify(i,name);
112 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
114 hdf_object_type type = hdf_file->InternalObjectType(name);
116 if(type == HDF_DATASET) {
117 HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
118 SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
120 } else if(type == HDF_GROUP) {
121 HDFgroup *hdf_group = new HDFgroup(name, hdf_file);
122 SaveGroupInASCIIfile(hdf_group, fp, 0);
127 fprintf(fp, "%s", ASCIIHDF_ID_END);
131 hdf_file->CloseOnDisk();
135 OSD_Path anOSDPath(aFileName);
136 OSD_File anOSDFile(anOSDPath);
137 if(anOSDFile.Exists())
138 anOSDFile.Move(aPath);
143 int length = strlen(aPath.ToCString());
144 char *new_str = new char[ 1+length ];
145 strcpy(new_str , aPath.ToCString()) ;
151 //============================================================================
152 // function : SaveGroupInASCIIfile
154 //============================================================================
155 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
157 hdf_group->OpenOnDisk();
159 TCollection_AsciiString anIdent(ident, '\t');
160 int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes();
162 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID);*/
163 fprintf(fp, "%s\n", GROUP_ID);
165 char* name = makeName(hdf_group->GetName());
167 /*fprintf(fp, "%s%s %i\n", anIdent.ToCString(), name, nbsons+nbAttr);*/
168 fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
171 for(unsigned j=0; j<nbAttr; j++) {
172 name = hdf_group->GetAttributeName(j);
173 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
175 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
179 char objName[HDF_NAME_MAX_LEN+1];
181 for (int i=0; i<nbsons; i++) {
182 hdf_group->InternalObjectIndentify(i, objName);
184 if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0) continue;
186 hdf_object_type type = hdf_group->InternalObjectType(objName);
188 if (type == HDF_DATASET) {
189 HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
190 SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
192 } else if (type == HDF_GROUP) {
193 HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
194 SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
199 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID_END);*/
200 fprintf(fp, "%s\n", GROUP_ID_END);
202 hdf_group->CloseOnDisk();
205 //============================================================================
206 // function : SaveDatasetInASCIIfile
208 //============================================================================
209 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
211 hdf_dataset->OpenOnDisk();
213 long size = hdf_dataset->GetSize();
214 long ndim = hdf_dataset->nDim(); //Get number of dimesions
215 hdf_size *dim = new hdf_size[ndim];
216 hdf_type type = hdf_dataset->GetType();
217 int nbAttr = hdf_dataset->nAttributes(), j;
219 TCollection_AsciiString anIdent(ident, '\t');
220 TCollection_AsciiString anIdentChild(ident+1, '\t');
222 char* name = makeName(hdf_dataset->GetName());
224 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID);*/
225 fprintf(fp, "%s\n", DATASET_ID);
226 /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, nbAttr);*/
227 fprintf(fp, "%s %i %i\n", name, type, nbAttr);
230 hdf_dataset->GetDim(dim);
231 /*fprintf(fp, "%s %i\n", anIdentChild.ToCString(), ndim);*/
232 fprintf(fp, " %i\n", ndim);
234 for(int i = 0;i < ndim;i++) {
235 /*fprintf(fp, "%s%i", anIdentChild.ToCString(), dim[i]);*/
236 fprintf(fp, " %i", dim[i]);
239 /*fprintf(fp, "%s\n", anIdentChild.ToCString());*/
243 /*fprintf(fp, "%s%li:", anIdentChild.ToCString(), size);*/
244 fprintf(fp, "%li:", size);
246 if (type == HDF_STRING) {
247 char* val = new char[size];
248 hdf_dataset->ReadFromDisk(val);
249 fwrite(val, 1, size, fp);
251 } else if (type == HDF_FLOAT64) {
252 hdf_float64* val = new hdf_float64[size];
253 hdf_dataset->ReadFromDisk(val);
255 for (int i = 0, j = 0; i < size; i++) {
256 write_float64(fp, &val[i]);
257 if(++j == NB_FLOAT_IN_ROW) {
261 else fprintf(fp," ");
264 } else if(type == HDF_INT64) {
265 hdf_int64* val = new hdf_int64[size];
266 hdf_dataset->ReadFromDisk(val);
268 for (int i = 0, j = 0; i < size; i++) {
269 fprintf(fp, " %li", val[i]);
270 if(++j == NB_INTEGER_IN_ROW) {
276 } else if(type == HDF_INT32) {
277 hdf_int32* val = new hdf_int32[size];
278 hdf_dataset->ReadFromDisk(val);
280 for (int i = 0, j = 0; i < size; i++) {
281 fprintf(fp, " %i", val[i]);
282 if(++j == NB_INTEGER_IN_ROW) {
292 for(unsigned j=0; j<nbAttr; j++) {
293 name = hdf_dataset->GetAttributeName(j);
294 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
296 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
300 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID_END); */
301 fprintf(fp, "%s\n", DATASET_ID_END);
303 hdf_dataset->CloseOnDisk();
307 //============================================================================
308 // function : SaveAttributeInASCIIfile
310 //============================================================================
311 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
313 hdf_attribute->OpenOnDisk();
315 hdf_type type = hdf_attribute->GetType();
317 TCollection_AsciiString anIdent(ident, '\t');
318 TCollection_AsciiString anIdentChild(ident+1, '\t');
320 char* name = makeName(hdf_attribute->GetName());
321 int size = hdf_attribute->GetSize();
323 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID);*/
324 fprintf(fp, "%s\n", ATTRIBUTE_ID);
325 /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, size);*/
326 fprintf(fp, "%s %i %i\n", name, type, size);
330 if (type == HDF_STRING) {
331 char* val = new char[size+1];
332 hdf_attribute->ReadFromDisk(val);
333 /*fprintf(fp, "%s:", anIdentChild.ToCString());*/
335 fwrite(val, 1, size, fp);
338 } else if (type == HDF_FLOAT64) {
340 hdf_attribute->ReadFromDisk(&val);
341 /*fprintf(fp, "%s", anIdentChild.ToCString());*/
342 write_float64(fp, &val);
344 } else if(type == HDF_INT64) {
346 hdf_attribute->ReadFromDisk(&val);
347 /*fprintf(fp, "%s%li \n", anIdentChild.ToCString(), val);*/
348 fprintf(fp, "%li \n", val);
349 } else if(type == HDF_INT32) {
351 hdf_attribute->ReadFromDisk(&val);
352 /*fprintf(fp, "%s%i \n", anIdentChild.ToCString(), val);*/
353 fprintf(fp, "%i \n", val);
356 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID_END);*/
357 fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
359 hdf_attribute->CloseOnDisk();
362 //############################## ASCII => HDF ################################
364 //============================================================================
365 // function : ConvertFromASCIIToHDF
366 // purpose : Converts a file pointed by thePath to HDF format
367 // Returns a name of directory where a created HDF file is placed
368 // The created file is named "hdf_from_ascii.hdf"
369 //============================================================================
370 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
372 // Get a temporary directory to store a file
373 TCollection_AsciiString aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
374 // Build a full file name of temporary file
375 TCollection_AsciiString aFullName = aTmpDir + aFileName;
377 HDFfile *hdf_file = new HDFfile(aFullName.ToCString());
378 hdf_file->CreateOnDisk();
380 FILE *fp = fopen(thePath, "r");
385 fscanf(fp, "%s", type);
386 fscanf(fp, "%i",&nbsons);
388 if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
390 for(i = 0; i < nbsons; i++) {
391 char id_of_begin[MAX_ID_SIZE];
392 fscanf(fp, "%s\n", id_of_begin);
394 if(strcmp(id_of_begin, GROUP_ID) == 0) {
395 if(!CreateGroupFromASCII(hdf_file, fp)) {
396 cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
400 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
401 if(!CreateDatasetFromASCII(hdf_file, fp)) {
402 cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
406 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
407 if(!CreateAttributeFromASCII(hdf_file, fp)) {
408 cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
413 cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl;
416 char id_of_end[MAX_ID_SIZE];
417 fscanf(fp, "%s", id_of_end);
418 if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
419 cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
423 hdf_file->CloseOnDisk();
426 int length = strlen(aTmpDir.ToCString());
427 char *new_str = new char[ 1+length ];
428 strcpy(new_str , aTmpDir.ToCString()) ;
434 //============================================================================
435 // function : CreateGroupFromASCII
436 // purpose : Creates a HDF group from a set attributes situated under theLabel
437 //============================================================================
438 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
440 char name[HDF_NAME_MAX_LEN+1];
442 fscanf(fp, "%s %i\n", name, &nbsons);
444 char* new_name = restoreName(name);
446 HDFgroup* hdf_group = new HDFgroup(new_name, father);
450 hdf_group->CreateOnDisk();
452 for(i = 0; i < nbsons; i++) {
453 char id_of_begin[MAX_ID_SIZE];
454 fscanf(fp, "%s\n", id_of_begin);
456 if(strcmp(id_of_begin, GROUP_ID) == 0) {
457 if(!CreateGroupFromASCII(hdf_group, fp)) {
458 cout << "Can not create subgroup " << i << " for group " << name << endl;
462 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
463 if(!CreateDatasetFromASCII(hdf_group, fp)) {
464 cout << "Can not create dataset " << i << " for group " << name << endl;
468 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
469 if(!CreateAttributeFromASCII(hdf_group, fp)) {
470 cout << "Can not create attribute " << i << " for group " << name << endl;
475 cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl;
478 hdf_group->CloseOnDisk();
479 hdf_group = 0; //will be deleted by father destructor
481 char id_of_end[MAX_ID_SIZE];
482 fscanf(fp, "%s\n", id_of_end);
483 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
484 cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
492 //============================================================================
493 // function : CreateDatasetFromASCII
494 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
495 //============================================================================
496 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
498 char name[HDF_NAME_MAX_LEN+1];
503 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
504 char* new_name = restoreName(name);
506 fscanf(fp, "%i\n", &nbDim);
508 hdf_size* sizeArray = new hdf_size[nbDim];
509 for(i = 0; i<nbDim; i++) {
510 fscanf(fp, "%i\n", &(sizeArray[i]));
513 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim);
517 hdf_dataset->CreateOnDisk();
520 fscanf(fp, "%li%c", &size, &tmp);
522 if (type == HDF_STRING) {
523 char *val = new char[size+1];
524 fread(val, 1, size, fp);
525 hdf_dataset->WriteOnDisk(val);
527 } else if (type == HDF_FLOAT64) {
528 hdf_float64* val = new hdf_float64[size];
529 for(i=0; i<size; i++) {
530 read_float64(fp, &(val[i]));
532 hdf_dataset->WriteOnDisk(val);
534 } else if(type == HDF_INT64) {
535 hdf_int64* val = new hdf_int64[size];
536 for(i=0; i<size; i++) {
537 fscanf(fp, " %li", &(val[i]));
539 hdf_dataset->WriteOnDisk(val);
541 } else if(type == HDF_INT32) {
542 hdf_int32* val = new hdf_int32[size];
543 for(i=0; i<size; i++) {
544 fscanf(fp, " %i", &(val[i]));
546 hdf_dataset->WriteOnDisk(val);
550 char token[MAX_ID_SIZE];
552 for(i = 0; i < nbAttr; i++) {
553 fscanf(fp, "%s\n", token);
555 if(strcmp(token, ATTRIBUTE_ID) == 0) {
556 if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
557 cout << "Can not create attribute " << i << " for dataset " << name << endl;
562 cout << "CreateGroupFromASCII : Unrecognized type " << token << endl;
567 fscanf(fp, "%s\n", token);
568 if(strcmp(token, DATASET_ID_END) != 0) {
569 cout << "CreateDatasetFromASCII : Invalid end token : " << token << endl;
573 hdf_dataset->CloseOnDisk();
574 hdf_dataset = 0; //will be deleted by father destructor
580 //============================================================================
581 // function : CreateAttributeFromASCII
582 // purpose : Creates a HDF attribute from a set attributes situated under theLabel
583 //============================================================================
584 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
586 char name[HDF_NAME_MAX_LEN+1];
590 fscanf(fp, "%s %i %i\n", name, &type, &size);
591 char* new_name = restoreName(name);
592 HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
594 hdf_attribute->CreateOnDisk();
598 if (type == HDF_STRING) {
600 fscanf(fp, "%c", &tmp);
601 char *val = new char[size+1];
603 fread(val, 1, size, fp);
604 hdf_attribute->WriteOnDisk(val);
606 } else if (type == HDF_FLOAT64) {
608 read_float64(fp, &val);
609 hdf_attribute->WriteOnDisk(&val);
610 } else if(type == HDF_INT64) {
612 fscanf(fp, "%li", &val);
613 hdf_attribute->WriteOnDisk(&val);
614 } else if(type == HDF_INT32) {
616 fscanf(fp, "%i", &val);
617 hdf_attribute->WriteOnDisk(&val);
620 hdf_attribute->CloseOnDisk();
621 hdf_attribute = 0; //will be deleted by father destructor
624 char id_of_end[MAX_ID_SIZE];
625 fscanf(fp, "%s\n", id_of_end);
626 if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
627 cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << endl;
635 //============================================================================
636 // function : GetTempDir
637 // purpose : Return a temp directory to store created files like "/tmp/sub_dir/"
638 //============================================================================
641 //Find a temporary directory to store a file
643 TCollection_AsciiString aTmpDir;
646 aTmpDir = TCollection_AsciiString("C:\\");
648 aTmpDir = TCollection_AsciiString("/tmp/");
651 srand((unsigned int)time(NULL));
652 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
653 TCollection_AsciiString aSubDir(aRND);
654 if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
656 aTmpDir += aSubDir; //Get RND sub directory
659 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
661 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
664 OSD_Path aPath(aTmpDir);
665 OSD_Directory aDir(aPath);
667 for(aRND = 0; aDir.Exists(); aRND++) {
668 aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND)); //Build a unique directory name
669 aPath = OSD_Path(aTmpDir);
670 aDir = OSD_Directory(aPath);
673 OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
674 aDir.Build(aProtection);
676 int length = strlen(aTmpDir.ToCString());
677 char *new_str = new char[ 1+length ];
678 strcpy(new_str , aTmpDir.ToCString());
683 char* makeName(char* name)
685 TCollection_AsciiString aName(name), aNewName;
686 Standard_Integer i, length = aName.Length();
687 char replace = (char)19;
689 for(i=1; i<=length; i++) {
690 if(aName.Value(i) == ' ') aNewName+=replace;
691 else aNewName += aName.Value(i);
694 length = strlen(aNewName.ToCString());
695 char *new_str = new char[ 1+length ];
696 strcpy(new_str , aNewName.ToCString()) ;
700 char* restoreName(char* name)
702 TCollection_AsciiString aName(name), aNewName;
703 Standard_Integer i, length = aName.Length();
704 char replace = (char)19;
706 for(i=1; i<=length; i++) {
707 if(aName.Value(i) == replace) aNewName+=' ';
708 else aNewName += aName.Value(i);
711 length = strlen(aNewName.ToCString());
712 char *new_str = new char[ 1+length ];
713 strcpy(new_str , aNewName.ToCString()) ;
717 void write_float64(FILE* fp, hdf_float64* value)
719 unsigned char* array = (unsigned char*)value;
720 for(int i = 0; i < sizeof(hdf_float64); i++) {
721 unsigned tmp = (unsigned short)array[i];
722 fprintf(fp, " %2x", tmp);
726 void read_float64(FILE* fp, hdf_float64* value)
728 unsigned char* array = (unsigned char*)value;
729 for(int i = 0; i < sizeof(hdf_float64); i++) {
731 fscanf(fp, " %x", &tmp);
732 array[i] = (unsigned char)tmp;