1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : SALOMEDS_Tool.cxx
24 // Created : Mon Oct 21 16:24:34 2002
25 // Author : Sergey RUIN
44 #define dir_separator '\\'
46 #define dir_separator '/'
49 void Move(const std::string& fName, const std::string& fNameDst);
50 bool Exists(const std::string thePath);
51 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
52 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
53 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
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);
59 std::string 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);
65 #define MAX_STRING_SIZE 65535
66 #define MAX_ID_SIZE 20
67 #define NB_FLOAT_IN_ROW 3
68 #define NB_INTEGER_IN_ROW 9
70 #define ASCIIHDF_ID "ASCIIHDF"
71 #define ATTRIBUTE_ID "ATTRIBUTE"
72 #define DATASET_ID "DATASET"
73 #define GROUP_ID "GROUP"
75 #define ASCIIHDF_ID_END "ASCIIHDF_END"
76 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
77 #define DATASET_ID_END "DATASET_END"
78 #define GROUP_ID_END "GROUP_END"
81 //============================================================================
83 // purpose : Returns True if the file is a converted to ASCII HDF file
84 //============================================================================
85 bool HDFascii::isASCII(const char* thePath) {
87 if(!(fd = open(thePath, O_RDONLY))) return false;
88 char* aBuffer = new char[9];
93 if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
98 //############################## HDF => ASCII ################################
100 //============================================================================
101 // function : ConvertFromHDFToASCII
102 // purpose : Converts a file pointed by thePath to ASCII format
103 // If isReplace is true the newly created file will replace the existent one.
104 // If isReplace is false theExtension will be added to a created file name
105 // Returns the file name of ASCII file
106 //============================================================================
107 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
109 const char* theExtension)
111 std::string aPath(thePath);
113 if(theExtension == NULL) aPath += ".asc";
114 else aPath += (char*)theExtension;
117 std::string aFileName(aPath);
118 if(isReplace) aFileName=aPath+".ascii_tmp";
120 HDFfile *hdf_file = new HDFfile((char*)thePath);
121 hdf_file->OpenOnDisk(HDF_RDONLY);
123 char name[HDF_NAME_MAX_LEN+1];
124 int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes();
126 FILE* fp = fopen(aFileName.c_str(), "w");
127 fprintf(fp, "%s\n", ASCIIHDF_ID);
128 fprintf(fp, "%i\n", nbsons+nbAttr);
130 for(int j=0; j<nbAttr; j++) {
131 char* attr_name = hdf_file->GetAttributeName(j);
132 HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
134 SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
138 for (int i=0; i<nbsons; i++) {
139 hdf_file->InternalObjectIndentify(i,name);
140 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
142 hdf_object_type type = hdf_file->InternalObjectType(name);
144 if(type == HDF_DATASET) {
145 HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
146 SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
148 } else if(type == HDF_GROUP) {
149 HDFgroup *hdf_group = new HDFgroup(name, hdf_file);
150 SaveGroupInASCIIfile(hdf_group, fp, 0);
155 fprintf(fp, "%s", ASCIIHDF_ID_END);
159 hdf_file->CloseOnDisk();
163 if(Exists(aFileName))
164 Move(aFileName, aPath);
169 int length = strlen(aPath.c_str());
170 char *new_str = new char[ 1+length ];
171 strcpy(new_str , aPath.c_str()) ;
177 //============================================================================
178 // function : SaveGroupInASCIIfile
180 //============================================================================
181 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
183 hdf_group->OpenOnDisk();
185 int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes();
187 fprintf(fp, "%s\n", GROUP_ID);
189 char* name = makeName(hdf_group->GetName());
191 fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
194 for(int j=0; j<nbAttr; j++) {
195 name = hdf_group->GetAttributeName(j);
196 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
198 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
202 char objName[HDF_NAME_MAX_LEN+1];
204 for (int i=0; i<nbsons; i++) {
205 hdf_group->InternalObjectIndentify(i, objName);
207 if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0) continue;
209 hdf_object_type type = hdf_group->InternalObjectType(objName);
211 if (type == HDF_DATASET) {
212 HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
213 SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
215 } else if (type == HDF_GROUP) {
216 HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
217 SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
222 fprintf(fp, "%s\n", GROUP_ID_END);
224 hdf_group->CloseOnDisk();
227 //============================================================================
228 // function : SaveDatasetInASCIIfile
230 //============================================================================
231 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
233 hdf_dataset->OpenOnDisk();
235 long size = (long) hdf_dataset->GetSize();
236 long ndim = hdf_dataset->nDim(); //Get number of dimesions
237 hdf_size *dim = new hdf_size[ndim];
238 hdf_type type = hdf_dataset->GetType();
239 hdf_byte_order order = hdf_dataset->GetOrder();
240 int nbAttr = hdf_dataset->nAttributes();
242 char* name = makeName(hdf_dataset->GetName());
244 fprintf(fp, "%s\n", DATASET_ID);
245 fprintf(fp, "%s %i %i\n", name, type, nbAttr);
248 hdf_dataset->GetDim(dim);
249 fprintf(fp, " %i\n", ndim);
251 for(int i = 0;i < ndim;i++) {
252 fprintf(fp, " %i", dim[i]);
258 fprintf(fp, "%li %i:", size, order);
260 if (type == HDF_STRING) {
261 char* val = new char[size];
262 hdf_dataset->ReadFromDisk(val);
263 fwrite(val, 1, size, fp);
265 } else if (type == HDF_FLOAT64) {
266 hdf_float64* val = new hdf_float64[size];
267 hdf_dataset->ReadFromDisk(val);
269 for (int i = 0, j = 0; i < size; i++) {
270 write_float64(fp, &val[i]);
271 if(++j == NB_FLOAT_IN_ROW) {
275 else fprintf(fp," ");
278 } else if(type == HDF_INT64) {
279 hdf_int64* val = new hdf_int64[size];
280 hdf_dataset->ReadFromDisk(val);
282 for (int i = 0, j = 0; i < size; i++) {
283 fprintf(fp, " %li", val[i]);
284 if(++j == NB_INTEGER_IN_ROW) {
290 } else if(type == HDF_INT32) {
291 hdf_int32* val = new hdf_int32[size];
292 hdf_dataset->ReadFromDisk(val);
294 for (int i = 0, j = 0; i < size; i++) {
295 fprintf(fp, " %i", val[i]);
296 if(++j == NB_INTEGER_IN_ROW) {
306 for ( int j=0; j<nbAttr; j++ )
308 name = hdf_dataset->GetAttributeName(j);
309 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
311 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
315 fprintf(fp, "%s\n", DATASET_ID_END);
317 hdf_dataset->CloseOnDisk();
321 //============================================================================
322 // function : SaveAttributeInASCIIfile
324 //============================================================================
325 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
327 hdf_attribute->OpenOnDisk();
329 hdf_type type = hdf_attribute->GetType();
331 char* name = makeName(hdf_attribute->GetName());
332 int size = hdf_attribute->GetSize();
334 fprintf(fp, "%s\n", ATTRIBUTE_ID);
335 fprintf(fp, "%s %i %i\n", name, type, size);
339 if (type == HDF_STRING) {
340 char* val = new char[size+1];
341 hdf_attribute->ReadFromDisk(val);
343 fwrite(val, 1, size, fp);
346 } else if (type == HDF_FLOAT64) {
348 hdf_attribute->ReadFromDisk(&val);
349 write_float64(fp, &val);
351 } else if(type == HDF_INT64) {
353 hdf_attribute->ReadFromDisk(&val);
354 fprintf(fp, "%li \n", val);
355 } else if(type == HDF_INT32) {
357 hdf_attribute->ReadFromDisk(&val);
358 fprintf(fp, "%i \n", val);
361 fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
363 hdf_attribute->CloseOnDisk();
366 //############################## ASCII => HDF ################################
368 //============================================================================
369 // function : ConvertFromASCIIToHDF
370 // purpose : Converts a file pointed by thePath to HDF format
371 // Returns a name of directory where a created HDF file is placed
372 // The created file is named "hdf_from_ascii.hdf"
373 //============================================================================
374 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath,
377 std::string aTmpDir, aFullName;
379 // Get a temporary directory to store a file
380 aTmpDir = GetTmpDir();
381 // Build a full file name of temporary file
382 aFullName = aTmpDir + "hdf_from_ascii.hdf";
386 aFullName = std::string(thePath)+".ascii_tmp";
389 FILE *fp = fopen(thePath, "r");
392 HDFfile *hdf_file = new HDFfile((char*)aFullName.c_str());
393 hdf_file->CreateOnDisk();
397 fscanf(fp, "%s", type);
398 fscanf(fp, "%i",&nbsons);
400 if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
402 for(i = 0; i < nbsons; i++) {
403 char id_of_begin[MAX_ID_SIZE];
404 fscanf(fp, "%s\n", id_of_begin);
406 if(strcmp(id_of_begin, GROUP_ID) == 0) {
407 if(!CreateGroupFromASCII(hdf_file, fp)) {
408 std::cout << "ConvertFromASCIIToHDF : Can not create group number " << i << std::endl;
412 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
413 if(!CreateDatasetFromASCII(hdf_file, fp)) {
414 std::cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << std::endl;
418 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
419 if(!CreateAttributeFromASCII(hdf_file, fp)) {
420 std::cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << std::endl;
425 std::cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << std::endl;
428 char id_of_end[MAX_ID_SIZE];
429 fscanf(fp, "%s", id_of_end);
430 if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
431 std::cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << std::endl;
435 hdf_file->CloseOnDisk();
439 if(Exists(aFullName))
440 Move(aFullName, thePath);
445 int length = strlen(aTmpDir.c_str());
446 char *new_str = new char[ 1+length ];
447 strcpy(new_str , aTmpDir.c_str()) ;
453 //============================================================================
454 // function : CreateGroupFromASCII
455 // purpose : Creates a HDF group from a set attributes situated under theLabel
456 //============================================================================
457 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
459 char name[HDF_NAME_MAX_LEN+1];
461 fscanf(fp, "%s %i\n", name, &nbsons);
463 char* new_name = restoreName(name);
465 HDFgroup* hdf_group = new HDFgroup(new_name, father);
469 hdf_group->CreateOnDisk();
471 for(i = 0; i < nbsons; i++) {
472 char id_of_begin[MAX_ID_SIZE];
473 fscanf(fp, "%s\n", id_of_begin);
475 if(strcmp(id_of_begin, GROUP_ID) == 0) {
476 if(!CreateGroupFromASCII(hdf_group, fp)) {
477 std::cout << "Can not create subgroup " << i << " for group " << name << std::endl;
481 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
482 if(!CreateDatasetFromASCII(hdf_group, fp)) {
483 std::cout << "Can not create dataset " << i << " for group " << name << std::endl;
487 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
488 if(!CreateAttributeFromASCII(hdf_group, fp)) {
489 std::cout << "Can not create attribute " << i << " for group " << name << std::endl;
494 std::cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << std::endl;
497 hdf_group->CloseOnDisk();
498 hdf_group = 0; //will be deleted by father destructor
500 char id_of_end[MAX_ID_SIZE];
501 fscanf(fp, "%s\n", id_of_end);
502 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
503 std::cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << std::endl;
511 //============================================================================
512 // function : CreateDatasetFromASCII
513 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
514 //============================================================================
515 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
517 char name[HDF_NAME_MAX_LEN+1];
519 hdf_byte_order order;
523 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
524 char* new_name = restoreName(name);
526 fscanf(fp, "%i\n", &nbDim);
528 hdf_size* sizeArray = new hdf_size[nbDim];
530 for(i = 0; i<nbDim; i++) {
531 fscanf(fp, "%i\n", &dim);
535 // order (2-d member) was not written in earlier versions
537 int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
538 if ( nbRead < 2 ) { // fscanf stops before ":"
539 fscanf(fp, "%c", &tmp);
540 order = H5T_ORDER_NONE;
542 if ( type != HDF_FLOAT64 ) // use order only for FLOAT64
543 order = H5T_ORDER_NONE;
545 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
549 hdf_dataset->CreateOnDisk();
551 if (type == HDF_STRING) {
552 char *val = new char[size+1];
553 fread(val, 1, size, fp);
554 hdf_dataset->WriteOnDisk(val);
556 } else if (type == HDF_FLOAT64) {
557 hdf_float64* val = new hdf_float64[size];
558 for(i=0; i<size; i++) {
559 read_float64(fp, &(val[i]));
561 hdf_dataset->WriteOnDisk(val);
563 } else if(type == HDF_INT64) {
564 hdf_int64* val = new hdf_int64[size];
565 for(i=0; i<size; i++) {
566 fscanf(fp, " %li", &(val[i]));
568 hdf_dataset->WriteOnDisk(val);
570 } else if(type == HDF_INT32) {
571 hdf_int32* val = new hdf_int32[size];
572 for(i=0; i<size; i++) {
573 fscanf(fp, " %i", &(val[i]));
575 hdf_dataset->WriteOnDisk(val);
579 char token[MAX_ID_SIZE];
581 for(i = 0; i < nbAttr; i++) {
582 fscanf(fp, "%s\n", token);
584 if(strcmp(token, ATTRIBUTE_ID) == 0) {
585 if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
586 std::cout << "Can not create attribute " << i << " for dataset " << name << std::endl;
591 std::cout << "CreateGroupFromASCII : Unrecognized type " << token << std::endl;
596 fscanf(fp, "%s\n", token);
597 if(strcmp(token, DATASET_ID_END) != 0) {
598 std::cout << "CreateDatasetFromASCII : Invalid end token : " << token << std::endl;
602 hdf_dataset->CloseOnDisk();
603 hdf_dataset = 0; //will be deleted by father destructor
609 //============================================================================
610 // function : CreateAttributeFromASCII
611 // purpose : Creates a HDF attribute from a set attributes situated under theLabel
612 //============================================================================
613 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
615 char name[HDF_NAME_MAX_LEN+1];
619 fscanf(fp, "%s %i %i\n", name, &type, &size);
620 char* new_name = restoreName(name);
621 HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
623 hdf_attribute->CreateOnDisk();
627 if (type == HDF_STRING) {
629 fscanf(fp, "%c", &tmp);
630 char *val = new char[size+1];
632 fread(val, 1, size, fp);
633 hdf_attribute->WriteOnDisk(val);
635 } else if (type == HDF_FLOAT64) {
637 read_float64(fp, &val);
638 hdf_attribute->WriteOnDisk(&val);
639 } else if(type == HDF_INT64) {
641 fscanf(fp, "%li", &val);
642 hdf_attribute->WriteOnDisk(&val);
643 } else if(type == HDF_INT32) {
645 fscanf(fp, "%i", &val);
646 hdf_attribute->WriteOnDisk(&val);
649 hdf_attribute->CloseOnDisk();
650 hdf_attribute = 0; //will be deleted by father destructor
653 char id_of_end[MAX_ID_SIZE];
654 fscanf(fp, "%s\n", id_of_end);
655 if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
656 std::cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << std::endl;
664 //============================================================================
665 // function : GetTempDir
666 // purpose : Return a temp directory to store created files like "/tmp/sub_dir/"
667 //============================================================================
668 std::string GetTmpDir()
671 //Find a temporary directory to store a file
675 char *Tmp_dir = getenv("SALOME_TMP_DIR");
676 if(Tmp_dir != NULL) {
677 aTmpDir = std::string(Tmp_dir);
678 if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
680 if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
682 if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
687 aTmpDir = std::string("C:\\");
689 aTmpDir = std::string("/tmp/");
693 srand((unsigned int)time(NULL));
694 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
696 sprintf(buffer, "%d", aRND);
697 std:: string aSubDir(buffer);
698 if(aSubDir.size() <= 1) aSubDir = std::string("123409876");
700 aTmpDir += aSubDir; //Get RND sub directory
702 if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
705 if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
707 if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
711 std::string aDir = aTmpDir;
713 for(aRND = 0; Exists(aDir); aRND++) {
714 sprintf(buffer, "%d", aRND);
715 aDir = aTmpDir+buffer; //Build a unique directory name
719 //fuction CreateDirectory create only final directory, but not intermediate
720 CreateDirectory(aTmpDir.c_str(), NULL);
721 CreateDirectory(aDir.c_str(), NULL);
723 mkdir(aDir.c_str(), 0x1ff);
726 return aDir + dir_separator;
729 char* makeName(char* name)
731 std::string aName(name), aNewName;
732 int i, length = aName.size();
733 char replace = (char)19;
735 for(i=0; i<length; i++) {
736 if(aName[i] == ' ') aNewName+=replace;
737 else aNewName += aName[i];
740 length = strlen(aNewName.c_str());
741 char *new_str = new char[ 1+length ];
742 strcpy(new_str , aNewName.c_str()) ;
746 char* restoreName(char* name)
748 std::string aName(name), aNewName;
749 int i, length = aName.size();
750 char replace = (char)19;
752 for(i=0; i<length; i++) {
753 if(aName[i] == replace) aNewName+=' ';
754 else aNewName += aName[i];
757 length = strlen(aNewName.c_str());
758 char *new_str = new char[ 1+length ];
759 strcpy(new_str , aNewName.c_str()) ;
763 void write_float64(FILE* fp, hdf_float64* value)
765 unsigned char* array = (unsigned char*)value;
766 for(int i = 0; i < sizeof(hdf_float64); i++) {
767 unsigned tmp = (unsigned short)array[i];
768 fprintf(fp, " %2x", tmp);
772 void read_float64(FILE* fp, hdf_float64* value)
774 unsigned char* array = (unsigned char*)value;
775 for(int i = 0; i < sizeof(hdf_float64); i++) {
777 fscanf(fp, " %x", &tmp);
778 array[i] = (unsigned char)tmp;
782 bool Exists(const std::string thePath)
785 if ( GetFileAttributes ( thePath.c_str() ) == 0xFFFFFFFF ) {
786 if ( GetLastError () != ERROR_FILE_NOT_FOUND ) {
791 int status = access ( thePath.c_str() , F_OK );
792 if (status != 0) return false;
797 void Move(const std::string& fName, const std::string& fNameDst)
800 MoveFileEx (fName.c_str(), fNameDst.c_str(),MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
802 rename(fName.c_str(), fNameDst.c_str());