1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : SALOMEDS_Tool.cxx
21 // Created : Mon Oct 21 16:24:34 2002
22 // Author : Sergey RUIN
42 void Move(const string& fName, const string& fNameDst);
43 bool Exists(const string thePath);
44 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
45 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
46 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
48 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
49 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
50 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
53 char* makeName(char* name);
54 char* restoreName(char* name);
55 void write_float64(FILE* fp, hdf_float64* value);
56 void read_float64(FILE* fp, hdf_float64* value);
58 #define MAX_STRING_SIZE 65535
59 #define MAX_ID_SIZE 20
60 #define NB_FLOAT_IN_ROW 3
61 #define NB_INTEGER_IN_ROW 9
63 #define ASCIIHDF_ID "ASCIIHDF"
64 #define ATTRIBUTE_ID "ATTRIBUTE"
65 #define DATASET_ID "DATASET"
66 #define GROUP_ID "GROUP"
68 #define ASCIIHDF_ID_END "ASCIIHDF_END"
69 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
70 #define DATASET_ID_END "DATASET_END"
71 #define GROUP_ID_END "GROUP_END"
74 //============================================================================
76 // purpose : Returns True if the file is a converted to ASCII HDF file
77 //============================================================================
78 bool HDFascii::isASCII(const char* thePath) {
80 if(!(fd = open(thePath, O_RDONLY))) return false;
81 char* aBuffer = new char[9];
86 if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
91 //############################## HDF => ASCII ################################
93 //============================================================================
94 // function : ConvertFromHDFToASCII
95 // purpose : Converts a file pointed by thePath to ASCII format
96 // If isReplace is true the newly created file will replace the existent one.
97 // If isReplace is false theExtension will be added to a created file name
98 // Returns the file name of ASCII file
99 //============================================================================
100 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
102 const char* theExtension)
104 string aPath(thePath);
106 if(theExtension == NULL) aPath += ".asc";
107 else aPath += (char*)theExtension;
110 string aFileName(aPath);
111 if(isReplace) aFileName=aPath+".ascii_tmp";
113 HDFfile *hdf_file = new HDFfile((char*)thePath);
114 hdf_file->OpenOnDisk(HDF_RDONLY);
116 char name[HDF_NAME_MAX_LEN+1];
117 int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes();
119 FILE* fp = fopen(aFileName.c_str(), "w");
120 fprintf(fp, "%s\n", ASCIIHDF_ID);
121 fprintf(fp, "%i\n", nbsons+nbAttr);
123 for(unsigned j=0; j<nbAttr; j++) {
124 char* attr_name = hdf_file->GetAttributeName(j);
125 HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
127 SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
131 for (int i=0; i<nbsons; i++) {
132 hdf_file->InternalObjectIndentify(i,name);
133 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
135 hdf_object_type type = hdf_file->InternalObjectType(name);
137 if(type == HDF_DATASET) {
138 HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
139 SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
141 } else if(type == HDF_GROUP) {
142 HDFgroup *hdf_group = new HDFgroup(name, hdf_file);
143 SaveGroupInASCIIfile(hdf_group, fp, 0);
148 fprintf(fp, "%s", ASCIIHDF_ID_END);
152 hdf_file->CloseOnDisk();
156 if(Exists(aFileName))
157 Move(aFileName, aPath);
162 int length = strlen(aPath.c_str());
163 char *new_str = new char[ 1+length ];
164 strcpy(new_str , aPath.c_str()) ;
170 //============================================================================
171 // function : SaveGroupInASCIIfile
173 //============================================================================
174 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
176 hdf_group->OpenOnDisk();
178 int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes();
180 fprintf(fp, "%s\n", GROUP_ID);
182 char* name = makeName(hdf_group->GetName());
184 fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
187 for(unsigned j=0; j<nbAttr; j++) {
188 name = hdf_group->GetAttributeName(j);
189 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
191 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
195 char objName[HDF_NAME_MAX_LEN+1];
197 for (int i=0; i<nbsons; i++) {
198 hdf_group->InternalObjectIndentify(i, objName);
200 if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0) continue;
202 hdf_object_type type = hdf_group->InternalObjectType(objName);
204 if (type == HDF_DATASET) {
205 HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
206 SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
208 } else if (type == HDF_GROUP) {
209 HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
210 SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
215 fprintf(fp, "%s\n", GROUP_ID_END);
217 hdf_group->CloseOnDisk();
220 //============================================================================
221 // function : SaveDatasetInASCIIfile
223 //============================================================================
224 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
226 hdf_dataset->OpenOnDisk();
228 long size = hdf_dataset->GetSize();
229 long ndim = hdf_dataset->nDim(); //Get number of dimesions
230 hdf_size *dim = new hdf_size[ndim];
231 hdf_type type = hdf_dataset->GetType();
232 hdf_byte_order order = hdf_dataset->GetOrder();
233 int nbAttr = hdf_dataset->nAttributes();
235 char* name = makeName(hdf_dataset->GetName());
237 fprintf(fp, "%s\n", DATASET_ID);
238 fprintf(fp, "%s %i %i\n", name, type, nbAttr);
241 hdf_dataset->GetDim(dim);
242 fprintf(fp, " %i\n", ndim);
244 for(int i = 0;i < ndim;i++) {
245 fprintf(fp, " %i", dim[i]);
251 fprintf(fp, "%li %i:", size, order);
253 if (type == HDF_STRING) {
254 char* val = new char[size];
255 hdf_dataset->ReadFromDisk(val);
256 fwrite(val, 1, size, fp);
258 } else if (type == HDF_FLOAT64) {
259 hdf_float64* val = new hdf_float64[size];
260 hdf_dataset->ReadFromDisk(val);
262 for (int i = 0, j = 0; i < size; i++) {
263 write_float64(fp, &val[i]);
264 if(++j == NB_FLOAT_IN_ROW) {
268 else fprintf(fp," ");
271 } else if(type == HDF_INT64) {
272 hdf_int64* val = new hdf_int64[size];
273 hdf_dataset->ReadFromDisk(val);
275 for (int i = 0, j = 0; i < size; i++) {
276 fprintf(fp, " %li", val[i]);
277 if(++j == NB_INTEGER_IN_ROW) {
283 } else if(type == HDF_INT32) {
284 hdf_int32* val = new hdf_int32[size];
285 hdf_dataset->ReadFromDisk(val);
287 for (int i = 0, j = 0; i < size; i++) {
288 fprintf(fp, " %i", val[i]);
289 if(++j == NB_INTEGER_IN_ROW) {
299 for ( unsigned j=0; j<nbAttr; j++ )
301 name = hdf_dataset->GetAttributeName(j);
302 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
304 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
308 fprintf(fp, "%s\n", DATASET_ID_END);
310 hdf_dataset->CloseOnDisk();
314 //============================================================================
315 // function : SaveAttributeInASCIIfile
317 //============================================================================
318 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
320 hdf_attribute->OpenOnDisk();
322 hdf_type type = hdf_attribute->GetType();
324 char* name = makeName(hdf_attribute->GetName());
325 int size = hdf_attribute->GetSize();
327 fprintf(fp, "%s\n", ATTRIBUTE_ID);
328 fprintf(fp, "%s %i %i\n", name, type, size);
332 if (type == HDF_STRING) {
333 char* val = new char[size+1];
334 hdf_attribute->ReadFromDisk(val);
336 fwrite(val, 1, size, fp);
339 } else if (type == HDF_FLOAT64) {
341 hdf_attribute->ReadFromDisk(&val);
342 write_float64(fp, &val);
344 } else if(type == HDF_INT64) {
346 hdf_attribute->ReadFromDisk(&val);
347 fprintf(fp, "%li \n", val);
348 } else if(type == HDF_INT32) {
350 hdf_attribute->ReadFromDisk(&val);
351 fprintf(fp, "%i \n", val);
354 fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
356 hdf_attribute->CloseOnDisk();
359 //############################## ASCII => HDF ################################
361 //============================================================================
362 // function : ConvertFromASCIIToHDF
363 // purpose : Converts a file pointed by thePath to HDF format
364 // Returns a name of directory where a created HDF file is placed
365 // The created file is named "hdf_from_ascii.hdf"
366 //============================================================================
367 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
369 // Get a temporary directory to store a file
370 string aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
371 // Build a full file name of temporary file
372 string aFullName = aTmpDir + aFileName;
374 HDFfile *hdf_file = new HDFfile((char*)aFullName.c_str());
375 hdf_file->CreateOnDisk();
377 FILE *fp = fopen(thePath, "r");
382 fscanf(fp, "%s", type);
383 fscanf(fp, "%i",&nbsons);
385 if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
387 for(i = 0; i < nbsons; i++) {
388 char id_of_begin[MAX_ID_SIZE];
389 fscanf(fp, "%s\n", id_of_begin);
391 if(strcmp(id_of_begin, GROUP_ID) == 0) {
392 if(!CreateGroupFromASCII(hdf_file, fp)) {
393 cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
397 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
398 if(!CreateDatasetFromASCII(hdf_file, fp)) {
399 cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
403 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
404 if(!CreateAttributeFromASCII(hdf_file, fp)) {
405 cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
410 cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl;
413 char id_of_end[MAX_ID_SIZE];
414 fscanf(fp, "%s", id_of_end);
415 if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
416 cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
420 hdf_file->CloseOnDisk();
423 int length = strlen(aTmpDir.c_str());
424 char *new_str = new char[ 1+length ];
425 strcpy(new_str , aTmpDir.c_str()) ;
431 //============================================================================
432 // function : CreateGroupFromASCII
433 // purpose : Creates a HDF group from a set attributes situated under theLabel
434 //============================================================================
435 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
437 char name[HDF_NAME_MAX_LEN+1];
439 fscanf(fp, "%s %i\n", name, &nbsons);
441 char* new_name = restoreName(name);
443 HDFgroup* hdf_group = new HDFgroup(new_name, father);
447 hdf_group->CreateOnDisk();
449 for(i = 0; i < nbsons; i++) {
450 char id_of_begin[MAX_ID_SIZE];
451 fscanf(fp, "%s\n", id_of_begin);
453 if(strcmp(id_of_begin, GROUP_ID) == 0) {
454 if(!CreateGroupFromASCII(hdf_group, fp)) {
455 cout << "Can not create subgroup " << i << " for group " << name << endl;
459 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
460 if(!CreateDatasetFromASCII(hdf_group, fp)) {
461 cout << "Can not create dataset " << i << " for group " << name << endl;
465 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
466 if(!CreateAttributeFromASCII(hdf_group, fp)) {
467 cout << "Can not create attribute " << i << " for group " << name << endl;
472 cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl;
475 hdf_group->CloseOnDisk();
476 hdf_group = 0; //will be deleted by father destructor
478 char id_of_end[MAX_ID_SIZE];
479 fscanf(fp, "%s\n", id_of_end);
480 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
481 cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
489 //============================================================================
490 // function : CreateDatasetFromASCII
491 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
492 //============================================================================
493 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
495 char name[HDF_NAME_MAX_LEN+1];
497 hdf_byte_order order;
501 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
502 char* new_name = restoreName(name);
504 fscanf(fp, "%i\n", &nbDim);
506 hdf_size* sizeArray = new hdf_size[nbDim];
508 for(i = 0; i<nbDim; i++) {
509 fscanf(fp, "%i\n", &dim);
513 // order (2-d member) was not written in earlier versions
515 int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
516 if ( nbRead < 2 ) { // fscanf stops before ":"
517 fscanf(fp, "%c", &tmp);
518 order = H5T_ORDER_NONE;
520 if ( type != HDF_FLOAT64 ) // use order only for FLOAT64
521 order = H5T_ORDER_NONE;
523 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
527 hdf_dataset->CreateOnDisk();
529 if (type == HDF_STRING) {
530 char *val = new char[size+1];
531 fread(val, 1, size, fp);
532 hdf_dataset->WriteOnDisk(val);
534 } else if (type == HDF_FLOAT64) {
535 hdf_float64* val = new hdf_float64[size];
536 for(i=0; i<size; i++) {
537 read_float64(fp, &(val[i]));
539 hdf_dataset->WriteOnDisk(val);
541 } else if(type == HDF_INT64) {
542 hdf_int64* val = new hdf_int64[size];
543 for(i=0; i<size; i++) {
544 fscanf(fp, " %li", &(val[i]));
546 hdf_dataset->WriteOnDisk(val);
548 } else if(type == HDF_INT32) {
549 hdf_int32* val = new hdf_int32[size];
550 for(i=0; i<size; i++) {
551 fscanf(fp, " %i", &(val[i]));
553 hdf_dataset->WriteOnDisk(val);
557 char token[MAX_ID_SIZE];
559 for(i = 0; i < nbAttr; i++) {
560 fscanf(fp, "%s\n", token);
562 if(strcmp(token, ATTRIBUTE_ID) == 0) {
563 if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
564 cout << "Can not create attribute " << i << " for dataset " << name << endl;
569 cout << "CreateGroupFromASCII : Unrecognized type " << token << endl;
574 fscanf(fp, "%s\n", token);
575 if(strcmp(token, DATASET_ID_END) != 0) {
576 cout << "CreateDatasetFromASCII : Invalid end token : " << token << endl;
580 hdf_dataset->CloseOnDisk();
581 hdf_dataset = 0; //will be deleted by father destructor
587 //============================================================================
588 // function : CreateAttributeFromASCII
589 // purpose : Creates a HDF attribute from a set attributes situated under theLabel
590 //============================================================================
591 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
593 char name[HDF_NAME_MAX_LEN+1];
597 fscanf(fp, "%s %i %i\n", name, &type, &size);
598 char* new_name = restoreName(name);
599 HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
601 hdf_attribute->CreateOnDisk();
605 if (type == HDF_STRING) {
607 fscanf(fp, "%c", &tmp);
608 char *val = new char[size+1];
610 fread(val, 1, size, fp);
611 hdf_attribute->WriteOnDisk(val);
613 } else if (type == HDF_FLOAT64) {
615 read_float64(fp, &val);
616 hdf_attribute->WriteOnDisk(&val);
617 } else if(type == HDF_INT64) {
619 fscanf(fp, "%li", &val);
620 hdf_attribute->WriteOnDisk(&val);
621 } else if(type == HDF_INT32) {
623 fscanf(fp, "%i", &val);
624 hdf_attribute->WriteOnDisk(&val);
627 hdf_attribute->CloseOnDisk();
628 hdf_attribute = 0; //will be deleted by father destructor
631 char id_of_end[MAX_ID_SIZE];
632 fscanf(fp, "%s\n", id_of_end);
633 if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
634 cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << endl;
642 //============================================================================
643 // function : GetTempDir
644 // purpose : Return a temp directory to store created files like "/tmp/sub_dir/"
645 //============================================================================
649 //Find a temporary directory to store a file
653 char *Tmp_dir = getenv("SALOME_TMP_DIR");
654 if(Tmp_dir != NULL) {
655 aTmpDir = string(Tmp_dir);
657 if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
659 if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
664 aTmpDir = string("C:\\");
666 aTmpDir = string("/tmp/");
670 srand((unsigned int)time(NULL));
671 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
673 sprintf(buffer, "%d", aRND);
674 string aSubDir(buffer);
675 if(aSubDir.size() <= 1) aSubDir = string("123409876");
677 aTmpDir += aSubDir; //Get RND sub directory
680 if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
682 if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
685 string aDir = aTmpDir;
687 for(aRND = 0; Exists(aDir); aRND++) {
688 sprintf(buffer, "%d", aRND);
689 aDir = aTmpDir+buffer; //Build a unique directory name
693 CreateDirectory(aDir.c_str(), NULL);
695 mkdir(aDir.c_str(), 0x1ff);
701 char* makeName(char* name)
703 string aName(name), aNewName;
704 int i, length = aName.size();
705 char replace = (char)19;
707 for(i=0; i<length; i++) {
708 if(aName[i] == ' ') aNewName+=replace;
709 else aNewName += aName[i];
712 length = strlen(aNewName.c_str());
713 char *new_str = new char[ 1+length ];
714 strcpy(new_str , aNewName.c_str()) ;
718 char* restoreName(char* name)
720 string aName(name), aNewName;
721 int i, length = aName.size();
722 char replace = (char)19;
724 for(i=0; i<length; i++) {
725 if(aName[i] == replace) aNewName+=' ';
726 else aNewName += aName[i];
729 length = strlen(aNewName.c_str());
730 char *new_str = new char[ 1+length ];
731 strcpy(new_str , aNewName.c_str()) ;
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;
754 bool Exists(const string thePath)
757 if ( GetFileAttributes ( thePath.c_str() ) == 0xFFFFFFFF ) {
758 if ( GetLastError () != ERROR_FILE_NOT_FOUND ) {
763 int status = access ( thePath.c_str() , F_OK );
764 if (status != 0) return false;
769 void Move(const string& fName, const string& fNameDst)
772 MoveFileEx (fName.c_str(), fNameDst.c_str(),MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
774 rename(fName.c_str(), fNameDst.c_str());