1 // File : SALOMEDS_Tool.cxx
2 // Created : Mon Oct 21 16:24:34 2002
3 // Author : Sergey RUIN
7 // Copyright : Open CASCADE
11 #include <OSD_Path.hxx>
12 #include <OSD_File.hxx>
13 #include <OSD_Protection.hxx>
14 #include <OSD_Directory.hxx>
15 #include <TCollection_AsciiString.hxx>
29 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
30 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
31 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
33 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
34 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
35 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
38 char* makeName(char* name);
39 char* restoreName(char* name);
40 void write_float64(FILE* fp, hdf_float64* value);
41 void read_float64(FILE* fp, hdf_float64* value);
43 #define MAX_STRING_SIZE 65535
44 #define MAX_ID_SIZE 20
45 #define NB_FLOAT_IN_ROW 3
46 #define NB_INTEGER_IN_ROW 9
48 #define ASCIIHDF_ID "ASCIIHDF"
49 #define ATTRIBUTE_ID "ATTRIBUTE"
50 #define DATASET_ID "DATASET"
51 #define GROUP_ID "GROUP"
53 #define ASCIIHDF_ID_END "ASCIIHDF_END"
54 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
55 #define DATASET_ID_END "DATASET_END"
56 #define GROUP_ID_END "GROUP_END"
59 //============================================================================
61 // purpose : Returns True if the file is a converted to ASCII HDF file
62 //============================================================================
63 bool HDFascii::isASCII(const char* thePath) {
65 if(!(fd = open(thePath, O_RDONLY))) return false;
66 char* aBuffer = new char[9];
71 if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
76 //############################## HDF => ASCII ################################
78 //============================================================================
79 // function : ConvertFromHDFToASCII
80 // purpose : Converts a file pointed by thePath to ASCII format
81 // If isReplace is true the newly created file will replace the existent one.
82 // If isReplace is false theExtension will be added to a created file name
83 // Returns the file name of ASCII file
84 //============================================================================
85 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
87 const char* theExtension)
89 TCollection_AsciiString aPath((char*)thePath);
91 if(theExtension == NULL) aPath += ".asc";
92 else aPath += (char*)theExtension;
95 TCollection_AsciiString aFileName(aPath);
96 if(isReplace) aFileName=aPath+".ascii_tmp";
98 HDFfile *hdf_file = new HDFfile((char*)thePath);
99 hdf_file->OpenOnDisk(HDF_RDONLY);
101 char name[HDF_NAME_MAX_LEN+1];
102 int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes();
104 FILE* fp = fopen(aFileName.ToCString(), "w");
105 fprintf(fp, "%s\n", ASCIIHDF_ID);
106 fprintf(fp, "%i\n", nbsons+nbAttr);
108 for(unsigned j=0; j<nbAttr; j++) {
109 char* attr_name = hdf_file->GetAttributeName(j);
110 HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
112 SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
116 for (Standard_Integer i=0; i<nbsons; i++) {
117 hdf_file->InternalObjectIndentify(i,name);
118 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
120 hdf_object_type type = hdf_file->InternalObjectType(name);
122 if(type == HDF_DATASET) {
123 HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
124 SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
126 } else if(type == HDF_GROUP) {
127 HDFgroup *hdf_group = new HDFgroup(name, hdf_file);
128 SaveGroupInASCIIfile(hdf_group, fp, 0);
133 fprintf(fp, "%s", ASCIIHDF_ID_END);
137 hdf_file->CloseOnDisk();
141 OSD_Path anOSDPath(aFileName);
142 OSD_File anOSDFile(anOSDPath);
143 if(anOSDFile.Exists())
144 anOSDFile.Move(aPath);
149 int length = strlen(aPath.ToCString());
150 char *new_str = new char[ 1+length ];
151 strcpy(new_str , aPath.ToCString()) ;
157 //============================================================================
158 // function : SaveGroupInASCIIfile
160 //============================================================================
161 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
163 hdf_group->OpenOnDisk();
165 TCollection_AsciiString anIdent(ident, '\t');
166 int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes();
168 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID);*/
169 fprintf(fp, "%s\n", GROUP_ID);
171 char* name = makeName(hdf_group->GetName());
173 /*fprintf(fp, "%s%s %i\n", anIdent.ToCString(), name, nbsons+nbAttr);*/
174 fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
177 for(unsigned j=0; j<nbAttr; j++) {
178 name = hdf_group->GetAttributeName(j);
179 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
181 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
185 char objName[HDF_NAME_MAX_LEN+1];
187 for (int i=0; i<nbsons; i++) {
188 hdf_group->InternalObjectIndentify(i, objName);
190 if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0) continue;
192 hdf_object_type type = hdf_group->InternalObjectType(objName);
194 if (type == HDF_DATASET) {
195 HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
196 SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
198 } else if (type == HDF_GROUP) {
199 HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
200 SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
205 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID_END);*/
206 fprintf(fp, "%s\n", GROUP_ID_END);
208 hdf_group->CloseOnDisk();
211 //============================================================================
212 // function : SaveDatasetInASCIIfile
214 //============================================================================
215 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
217 hdf_dataset->OpenOnDisk();
219 long size = hdf_dataset->GetSize();
220 long ndim = hdf_dataset->nDim(); //Get number of dimesions
221 hdf_size *dim = new hdf_size[ndim];
222 hdf_type type = hdf_dataset->GetType();
223 int nbAttr = hdf_dataset->nAttributes(), j;
225 TCollection_AsciiString anIdent(ident, '\t');
226 TCollection_AsciiString anIdentChild(ident+1, '\t');
228 char* name = makeName(hdf_dataset->GetName());
230 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID);*/
231 fprintf(fp, "%s\n", DATASET_ID);
232 /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, nbAttr);*/
233 fprintf(fp, "%s %i %i\n", name, type, nbAttr);
236 hdf_dataset->GetDim(dim);
237 /*fprintf(fp, "%s %i\n", anIdentChild.ToCString(), ndim);*/
238 fprintf(fp, " %i\n", ndim);
240 for(int i = 0;i < ndim;i++) {
241 /*fprintf(fp, "%s%i", anIdentChild.ToCString(), dim[i]);*/
242 fprintf(fp, " %i", dim[i]);
245 /*fprintf(fp, "%s\n", anIdentChild.ToCString());*/
249 /*fprintf(fp, "%s%li:", anIdentChild.ToCString(), size);*/
250 fprintf(fp, "%li:", size);
252 if (type == HDF_STRING) {
253 char* val = new char[size];
254 hdf_dataset->ReadFromDisk(val);
255 fwrite(val, 1, size, fp);
257 } else if (type == HDF_FLOAT64) {
258 hdf_float64* val = new hdf_float64[size];
259 hdf_dataset->ReadFromDisk(val);
261 for (int i = 0, j = 0; i < size; i++) {
262 write_float64(fp, &val[i]);
263 if(++j == NB_FLOAT_IN_ROW) {
267 else fprintf(fp," ");
270 } else if(type == HDF_INT64) {
271 hdf_int64* val = new hdf_int64[size];
272 hdf_dataset->ReadFromDisk(val);
274 for (int i = 0, j = 0; i < size; i++) {
275 fprintf(fp, " %li", val[i]);
276 if(++j == NB_INTEGER_IN_ROW) {
282 } else if(type == HDF_INT32) {
283 hdf_int32* val = new hdf_int32[size];
284 hdf_dataset->ReadFromDisk(val);
286 for (int i = 0, j = 0; i < size; i++) {
287 fprintf(fp, " %i", val[i]);
288 if(++j == NB_INTEGER_IN_ROW) {
299 for(unsigned j=0; j<nbAttr; j++) {
301 for(j=0; j<nbAttr; j++) {
303 name = hdf_dataset->GetAttributeName(j);
304 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
306 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
310 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID_END); */
311 fprintf(fp, "%s\n", DATASET_ID_END);
313 hdf_dataset->CloseOnDisk();
317 //============================================================================
318 // function : SaveAttributeInASCIIfile
320 //============================================================================
321 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
323 hdf_attribute->OpenOnDisk();
325 hdf_type type = hdf_attribute->GetType();
327 TCollection_AsciiString anIdent(ident, '\t');
328 TCollection_AsciiString anIdentChild(ident+1, '\t');
330 char* name = makeName(hdf_attribute->GetName());
331 int size = hdf_attribute->GetSize();
333 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID);*/
334 fprintf(fp, "%s\n", ATTRIBUTE_ID);
335 /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, size);*/
336 fprintf(fp, "%s %i %i\n", name, type, size);
340 if (type == HDF_STRING) {
341 char* val = new char[size+1];
342 hdf_attribute->ReadFromDisk(val);
343 /*fprintf(fp, "%s:", anIdentChild.ToCString());*/
345 fwrite(val, 1, size, fp);
348 } else if (type == HDF_FLOAT64) {
350 hdf_attribute->ReadFromDisk(&val);
351 /*fprintf(fp, "%s", anIdentChild.ToCString());*/
352 write_float64(fp, &val);
354 } else if(type == HDF_INT64) {
356 hdf_attribute->ReadFromDisk(&val);
357 /*fprintf(fp, "%s%li \n", anIdentChild.ToCString(), val);*/
358 fprintf(fp, "%li \n", val);
359 } else if(type == HDF_INT32) {
361 hdf_attribute->ReadFromDisk(&val);
362 /*fprintf(fp, "%s%i \n", anIdentChild.ToCString(), val);*/
363 fprintf(fp, "%i \n", val);
366 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID_END);*/
367 fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
369 hdf_attribute->CloseOnDisk();
372 //############################## ASCII => HDF ################################
374 //============================================================================
375 // function : ConvertFromASCIIToHDF
376 // purpose : Converts a file pointed by thePath to HDF format
377 // Returns a name of directory where a created HDF file is placed
378 // The created file is named "hdf_from_ascii.hdf"
379 //============================================================================
380 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
382 // Get a temporary directory to store a file
383 TCollection_AsciiString aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
384 // Build a full file name of temporary file
385 TCollection_AsciiString aFullName = aTmpDir + aFileName;
387 HDFfile *hdf_file = new HDFfile(aFullName.ToCString());
388 hdf_file->CreateOnDisk();
390 FILE *fp = fopen(thePath, "r");
395 fscanf(fp, "%s", type);
396 fscanf(fp, "%i",&nbsons);
398 if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
400 for(i = 0; i < nbsons; i++) {
401 char id_of_begin[MAX_ID_SIZE];
402 fscanf(fp, "%s\n", id_of_begin);
404 if(strcmp(id_of_begin, GROUP_ID) == 0) {
405 if(!CreateGroupFromASCII(hdf_file, fp)) {
406 cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
410 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
411 if(!CreateDatasetFromASCII(hdf_file, fp)) {
412 cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
416 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
417 if(!CreateAttributeFromASCII(hdf_file, fp)) {
418 cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
423 cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl;
426 char id_of_end[MAX_ID_SIZE];
427 fscanf(fp, "%s", id_of_end);
428 if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
429 cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
433 hdf_file->CloseOnDisk();
436 int length = strlen(aTmpDir.ToCString());
437 char *new_str = new char[ 1+length ];
438 strcpy(new_str , aTmpDir.ToCString()) ;
444 //============================================================================
445 // function : CreateGroupFromASCII
446 // purpose : Creates a HDF group from a set attributes situated under theLabel
447 //============================================================================
448 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
450 char name[HDF_NAME_MAX_LEN+1];
452 fscanf(fp, "%s %i\n", name, &nbsons);
454 char* new_name = restoreName(name);
456 HDFgroup* hdf_group = new HDFgroup(new_name, father);
460 hdf_group->CreateOnDisk();
462 for(i = 0; i < nbsons; i++) {
463 char id_of_begin[MAX_ID_SIZE];
464 fscanf(fp, "%s\n", id_of_begin);
466 if(strcmp(id_of_begin, GROUP_ID) == 0) {
467 if(!CreateGroupFromASCII(hdf_group, fp)) {
468 cout << "Can not create subgroup " << i << " for group " << name << endl;
472 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
473 if(!CreateDatasetFromASCII(hdf_group, fp)) {
474 cout << "Can not create dataset " << i << " for group " << name << endl;
478 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
479 if(!CreateAttributeFromASCII(hdf_group, fp)) {
480 cout << "Can not create attribute " << i << " for group " << name << endl;
485 cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl;
488 hdf_group->CloseOnDisk();
489 hdf_group = 0; //will be deleted by father destructor
491 char id_of_end[MAX_ID_SIZE];
492 fscanf(fp, "%s\n", id_of_end);
493 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
494 cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
502 //============================================================================
503 // function : CreateDatasetFromASCII
504 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
505 //============================================================================
506 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
508 char name[HDF_NAME_MAX_LEN+1];
513 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
514 char* new_name = restoreName(name);
516 fscanf(fp, "%i\n", &nbDim);
518 hdf_size* sizeArray = new hdf_size[nbDim];
520 for(i = 0; i<nbDim; i++) {
521 fscanf(fp, "%i\n", &dim);
525 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim);
529 hdf_dataset->CreateOnDisk();
532 fscanf(fp, "%li%c", &size, &tmp);
534 if (type == HDF_STRING) {
535 char *val = new char[size+1];
536 fread(val, 1, size, fp);
537 hdf_dataset->WriteOnDisk(val);
539 } else if (type == HDF_FLOAT64) {
540 hdf_float64* val = new hdf_float64[size];
541 for(i=0; i<size; i++) {
542 read_float64(fp, &(val[i]));
544 hdf_dataset->WriteOnDisk(val);
546 } else if(type == HDF_INT64) {
547 hdf_int64* val = new hdf_int64[size];
548 for(i=0; i<size; i++) {
549 fscanf(fp, " %li", &(val[i]));
551 hdf_dataset->WriteOnDisk(val);
553 } else if(type == HDF_INT32) {
554 hdf_int32* val = new hdf_int32[size];
555 for(i=0; i<size; i++) {
556 fscanf(fp, " %i", &(val[i]));
558 hdf_dataset->WriteOnDisk(val);
562 char token[MAX_ID_SIZE];
564 for(i = 0; i < nbAttr; i++) {
565 fscanf(fp, "%s\n", token);
567 if(strcmp(token, ATTRIBUTE_ID) == 0) {
568 if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
569 cout << "Can not create attribute " << i << " for dataset " << name << endl;
574 cout << "CreateGroupFromASCII : Unrecognized type " << token << endl;
579 fscanf(fp, "%s\n", token);
580 if(strcmp(token, DATASET_ID_END) != 0) {
581 cout << "CreateDatasetFromASCII : Invalid end token : " << token << endl;
585 hdf_dataset->CloseOnDisk();
586 hdf_dataset = 0; //will be deleted by father destructor
592 //============================================================================
593 // function : CreateAttributeFromASCII
594 // purpose : Creates a HDF attribute from a set attributes situated under theLabel
595 //============================================================================
596 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
598 char name[HDF_NAME_MAX_LEN+1];
602 fscanf(fp, "%s %i %i\n", name, &type, &size);
603 char* new_name = restoreName(name);
604 HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
606 hdf_attribute->CreateOnDisk();
610 if (type == HDF_STRING) {
612 fscanf(fp, "%c", &tmp);
613 char *val = new char[size+1];
615 fread(val, 1, size, fp);
616 hdf_attribute->WriteOnDisk(val);
618 } else if (type == HDF_FLOAT64) {
620 read_float64(fp, &val);
621 hdf_attribute->WriteOnDisk(&val);
622 } else if(type == HDF_INT64) {
624 fscanf(fp, "%li", &val);
625 hdf_attribute->WriteOnDisk(&val);
626 } else if(type == HDF_INT32) {
628 fscanf(fp, "%i", &val);
629 hdf_attribute->WriteOnDisk(&val);
632 hdf_attribute->CloseOnDisk();
633 hdf_attribute = 0; //will be deleted by father destructor
636 char id_of_end[MAX_ID_SIZE];
637 fscanf(fp, "%s\n", id_of_end);
638 if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
639 cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << endl;
647 //============================================================================
648 // function : GetTempDir
649 // purpose : Return a temp directory to store created files like "/tmp/sub_dir/"
650 //============================================================================
653 //Find a temporary directory to store a file
655 TCollection_AsciiString aTmpDir;
659 aTmp = getenv("TMP");
661 aTmpDir = TCollection_AsciiString(aTmp);
663 aTmpDir = TCollection_AsciiString("C:\\");
665 aTmpDir = TCollection_AsciiString("/tmp/");
668 srand((unsigned int)time(NULL));
670 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
671 TCollection_AsciiString aSubDir(aRND);
672 if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
674 aTmpDir += aSubDir; //Get RND sub directory
677 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
679 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
682 OSD_Path aPath(aTmpDir);
683 OSD_Directory aDir(aPath);
685 for(aRND = 0; aDir.Exists(); aRND++) {
686 aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND)); //Build a unique directory name
687 aPath = OSD_Path(aTmpDir);
688 aDir = OSD_Directory(aPath);
691 OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
692 aDir.Build(aProtection);
694 int length = strlen(aTmpDir.ToCString());
695 char *new_str = new char[ 1+length ];
696 strcpy(new_str , aTmpDir.ToCString());
701 char* makeName(char* name)
703 TCollection_AsciiString aName(name), aNewName;
704 Standard_Integer i, length = aName.Length();
705 char replace = (char)19;
707 for(i=1; i<=length; i++) {
708 if(aName.Value(i) == ' ') aNewName+=replace;
709 else aNewName += aName.Value(i);
712 length = strlen(aNewName.ToCString());
713 char *new_str = new char[ 1+length ];
714 strcpy(new_str , aNewName.ToCString()) ;
718 char* restoreName(char* name)
720 TCollection_AsciiString aName(name), aNewName;
721 Standard_Integer i, length = aName.Length();
722 char replace = (char)19;
724 for(i=1; i<=length; i++) {
725 if(aName.Value(i) == replace) aNewName+=' ';
726 else aNewName += aName.Value(i);
729 length = strlen(aNewName.ToCString());
730 char *new_str = new char[ 1+length ];
731 strcpy(new_str , aNewName.ToCString()) ;
735 void write_float64(FILE* fp, hdf_float64* value)
737 unsigned char* array = (unsigned char*)value;
738 for(int i = 0; i < sizeof(hdf_float64); i++) {
739 unsigned tmp = (unsigned short)array[i];
740 fprintf(fp, " %2x", tmp);
744 void read_float64(FILE* fp, hdf_float64* value)
746 unsigned char* array = (unsigned char*)value;
747 for(int i = 0; i < sizeof(hdf_float64); i++) {
749 fscanf(fp, " %x", &tmp);
750 array[i] = (unsigned char)tmp;