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(), "wb");
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, "rb");
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()) ;
455 //============================================================================
456 // function : CreateGroupFromASCII
457 // purpose : Creates a HDF group from a set attributes situated under theLabel
458 //============================================================================
459 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
461 char name[HDF_NAME_MAX_LEN+1];
463 fscanf(fp, "%s %i\n", name, &nbsons);
465 char* new_name = restoreName(name);
467 HDFgroup* hdf_group = new HDFgroup(new_name, father);
471 hdf_group->CreateOnDisk();
473 for(i = 0; i < nbsons; i++) {
474 char id_of_begin[MAX_ID_SIZE];
475 fscanf(fp, "%s\n", id_of_begin);
477 if(strcmp(id_of_begin, GROUP_ID) == 0) {
478 if(!CreateGroupFromASCII(hdf_group, fp)) {
479 std::cout << "Can not create subgroup " << i << " for group " << name << std::endl;
483 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
484 if(!CreateDatasetFromASCII(hdf_group, fp)) {
485 std::cout << "Can not create dataset " << i << " for group " << name << std::endl;
489 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
490 if(!CreateAttributeFromASCII(hdf_group, fp)) {
491 std::cout << "Can not create attribute " << i << " for group " << name << std::endl;
496 std::cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << std::endl;
499 hdf_group->CloseOnDisk();
500 hdf_group = 0; //will be deleted by father destructor
502 char id_of_end[MAX_ID_SIZE];
503 fscanf(fp, "%s\n", id_of_end);
504 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
505 std::cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << std::endl;
513 //============================================================================
514 // function : CreateDatasetFromASCII
515 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
516 //============================================================================
517 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
519 char name[HDF_NAME_MAX_LEN+1];
521 hdf_byte_order order;
525 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
526 char* new_name = restoreName(name);
528 fscanf(fp, "%i\n", &nbDim);
530 hdf_size* sizeArray = new hdf_size[nbDim];
532 for(i = 0; i<nbDim; i++) {
533 fscanf(fp, "%i\n", &dim);
537 // order (2-d member) was not written in earlier versions
539 int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
540 if ( nbRead < 2 ) { // fscanf stops before ":"
541 fscanf(fp, "%c", &tmp);
542 order = H5T_ORDER_NONE;
544 if ( type != HDF_FLOAT64 ) // use order only for FLOAT64
545 order = H5T_ORDER_NONE;
547 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
551 hdf_dataset->CreateOnDisk();
553 if (type == HDF_STRING) {
554 char *val = new char[size+1];
555 fread(val, 1, size, fp);
556 hdf_dataset->WriteOnDisk(val);
558 } else if (type == HDF_FLOAT64) {
559 hdf_float64* val = new hdf_float64[size];
560 for(i=0; i<size; i++) {
561 read_float64(fp, &(val[i]));
563 hdf_dataset->WriteOnDisk(val);
565 } else if(type == HDF_INT64) {
566 hdf_int64* val = new hdf_int64[size];
567 for(i=0; i<size; i++) {
568 fscanf(fp, " %li", &(val[i]));
570 hdf_dataset->WriteOnDisk(val);
572 } else if(type == HDF_INT32) {
573 hdf_int32* val = new hdf_int32[size];
574 for(i=0; i<size; i++) {
575 fscanf(fp, " %i", &(val[i]));
577 hdf_dataset->WriteOnDisk(val);
581 char token[MAX_ID_SIZE];
583 for(i = 0; i < nbAttr; i++) {
584 fscanf(fp, "%s\n", token);
586 if(strcmp(token, ATTRIBUTE_ID) == 0) {
587 if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
588 std::cout << "Can not create attribute " << i << " for dataset " << name << std::endl;
593 std::cout << "CreateGroupFromASCII : Unrecognized type " << token << std::endl;
598 fscanf(fp, "%s\n", token);
599 if(strcmp(token, DATASET_ID_END) != 0) {
600 std::cout << "CreateDatasetFromASCII : Invalid end token : " << token << std::endl;
604 hdf_dataset->CloseOnDisk();
605 hdf_dataset = 0; //will be deleted by father destructor
611 //============================================================================
612 // function : CreateAttributeFromASCII
613 // purpose : Creates a HDF attribute from a set attributes situated under theLabel
614 //============================================================================
615 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
617 char name[HDF_NAME_MAX_LEN+1];
621 fscanf(fp, "%s %i %i\n", name, &type, &size);
622 char* new_name = restoreName(name);
623 HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
625 hdf_attribute->CreateOnDisk();
629 if (type == HDF_STRING) {
631 fscanf(fp, "%c", &tmp);
632 char *val = new char[size+1];
634 fread(val, 1, size, fp);
635 hdf_attribute->WriteOnDisk(val);
637 } else if (type == HDF_FLOAT64) {
639 read_float64(fp, &val);
640 hdf_attribute->WriteOnDisk(&val);
641 } else if(type == HDF_INT64) {
643 fscanf(fp, "%li", &val);
644 hdf_attribute->WriteOnDisk(&val);
645 } else if(type == HDF_INT32) {
647 fscanf(fp, "%i", &val);
648 hdf_attribute->WriteOnDisk(&val);
651 hdf_attribute->CloseOnDisk();
652 hdf_attribute = 0; //will be deleted by father destructor
655 char id_of_end[MAX_ID_SIZE];
656 fscanf(fp, "%s\n", id_of_end);
657 if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
658 std::cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << std::endl;
666 //============================================================================
667 // function : GetTempDir
668 // purpose : Return a temp directory to store created files like "/tmp/sub_dir/"
669 //============================================================================
670 std::string GetTmpDir()
672 //Find a temporary directory to store a file
674 char *Tmp_dir = getenv("SALOME_TMP_DIR");
675 if(Tmp_dir != NULL) {
676 aTmpDir = std::string(Tmp_dir);
677 if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
681 aTmpDir = std::string("C:\\");
683 aTmpDir = std::string("/tmp/");
687 srand((unsigned int)time(NULL));
688 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
690 sprintf(buffer, "%d", aRND);
691 std:: string aSubDir(buffer);
692 if(aSubDir.size() <= 1) aSubDir = std::string("123409876");
694 aTmpDir += aSubDir; //Get RND sub directory
696 if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
698 std::string aDir = aTmpDir;
700 for(aRND = 0; Exists(aDir); aRND++) {
701 sprintf(buffer, "%d", aRND);
702 aDir = aTmpDir+buffer; //Build a unique directory name
706 //fuction CreateDirectory create only final directory, but not intermediate
707 CreateDirectory(aTmpDir.c_str(), NULL);
708 CreateDirectory(aDir.c_str(), NULL);
710 mkdir(aDir.c_str(), 0x1ff);
713 return aDir + dir_separator;
716 char* makeName(char* name)
718 std::string aName(name), aNewName;
719 int i, length = aName.size();
720 char replace = (char)19;
722 for(i=0; i<length; i++) {
723 if(aName[i] == ' ') aNewName+=replace;
724 else aNewName += aName[i];
727 length = strlen(aNewName.c_str());
728 char *new_str = new char[ 1+length ];
729 strcpy(new_str , aNewName.c_str()) ;
733 char* restoreName(char* name)
735 std::string aName(name), aNewName;
736 int i, length = aName.size();
737 char replace = (char)19;
739 for(i=0; i<length; i++) {
740 if(aName[i] == replace) aNewName+=' ';
741 else aNewName += aName[i];
744 length = strlen(aNewName.c_str());
745 char *new_str = new char[ 1+length ];
746 strcpy(new_str , aNewName.c_str()) ;
750 void write_float64(FILE* fp, hdf_float64* value)
752 unsigned char* array = (unsigned char*)value;
753 for(int i = 0; i < sizeof(hdf_float64); i++) {
754 unsigned tmp = (unsigned short)array[i];
755 fprintf(fp, " %2x", tmp);
759 void read_float64(FILE* fp, hdf_float64* value)
761 unsigned char* array = (unsigned char*)value;
762 for(int i = 0; i < sizeof(hdf_float64); i++) {
764 fscanf(fp, " %x", &tmp);
765 array[i] = (unsigned char)tmp;
769 bool Exists(const std::string thePath)
772 if ( GetFileAttributes ( thePath.c_str() ) == 0xFFFFFFFF ) {
773 DWORD errorId = GetLastError ();
774 if ( errorId == ERROR_FILE_NOT_FOUND || errorId == ERROR_PATH_NOT_FOUND )
778 int status = access ( thePath.c_str() , F_OK );
779 if (status != 0) return false;
784 void Move(const std::string& fName, const std::string& fNameDst)
787 MoveFileEx (fName.c_str(), fNameDst.c_str(),MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
789 rename(fName.c_str(), fNameDst.c_str());