1 // Copyright (C) 2007-2008 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
22 // File : SALOMEDS_Tool.cxx
23 // Created : Mon Oct 21 16:24:34 2002
24 // Author : Sergey RUIN
40 #define dir_separator '\\'
42 #define dir_separator '/'
47 void Move(const string& fName, const string& fNameDst);
48 bool Exists(const string thePath);
49 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
50 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
51 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
53 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
54 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
55 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
58 char* makeName(char* name);
59 char* restoreName(char* name);
60 void write_float64(FILE* fp, hdf_float64* value);
61 void read_float64(FILE* fp, hdf_float64* value);
63 #define MAX_STRING_SIZE 65535
64 #define MAX_ID_SIZE 20
65 #define NB_FLOAT_IN_ROW 3
66 #define NB_INTEGER_IN_ROW 9
68 #define ASCIIHDF_ID "ASCIIHDF"
69 #define ATTRIBUTE_ID "ATTRIBUTE"
70 #define DATASET_ID "DATASET"
71 #define GROUP_ID "GROUP"
73 #define ASCIIHDF_ID_END "ASCIIHDF_END"
74 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
75 #define DATASET_ID_END "DATASET_END"
76 #define GROUP_ID_END "GROUP_END"
79 //============================================================================
81 // purpose : Returns True if the file is a converted to ASCII HDF file
82 //============================================================================
83 bool HDFascii::isASCII(const char* thePath) {
85 if(!(fd = open(thePath, O_RDONLY))) return false;
86 char* aBuffer = new char[9];
91 if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
96 //############################## HDF => ASCII ################################
98 //============================================================================
99 // function : ConvertFromHDFToASCII
100 // purpose : Converts a file pointed by thePath to ASCII format
101 // If isReplace is true the newly created file will replace the existent one.
102 // If isReplace is false theExtension will be added to a created file name
103 // Returns the file name of ASCII file
104 //============================================================================
105 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
107 const char* theExtension)
109 string aPath(thePath);
111 if(theExtension == NULL) aPath += ".asc";
112 else aPath += (char*)theExtension;
115 string aFileName(aPath);
116 if(isReplace) aFileName=aPath+".ascii_tmp";
118 HDFfile *hdf_file = new HDFfile((char*)thePath);
119 hdf_file->OpenOnDisk(HDF_RDONLY);
121 char name[HDF_NAME_MAX_LEN+1];
122 int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes();
124 FILE* fp = fopen(aFileName.c_str(), "w");
125 fprintf(fp, "%s\n", ASCIIHDF_ID);
126 fprintf(fp, "%i\n", nbsons+nbAttr);
128 for(unsigned j=0; j<nbAttr; j++) {
129 char* attr_name = hdf_file->GetAttributeName(j);
130 HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
132 SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
136 for (int i=0; i<nbsons; i++) {
137 hdf_file->InternalObjectIndentify(i,name);
138 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
140 hdf_object_type type = hdf_file->InternalObjectType(name);
142 if(type == HDF_DATASET) {
143 HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
144 SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
146 } else if(type == HDF_GROUP) {
147 HDFgroup *hdf_group = new HDFgroup(name, hdf_file);
148 SaveGroupInASCIIfile(hdf_group, fp, 0);
153 fprintf(fp, "%s", ASCIIHDF_ID_END);
157 hdf_file->CloseOnDisk();
161 if(Exists(aFileName))
162 Move(aFileName, aPath);
167 int length = strlen(aPath.c_str());
168 char *new_str = new char[ 1+length ];
169 strcpy(new_str , aPath.c_str()) ;
175 //============================================================================
176 // function : SaveGroupInASCIIfile
178 //============================================================================
179 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
181 hdf_group->OpenOnDisk();
183 int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes();
185 fprintf(fp, "%s\n", GROUP_ID);
187 char* name = makeName(hdf_group->GetName());
189 fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
192 for(unsigned j=0; j<nbAttr; j++) {
193 name = hdf_group->GetAttributeName(j);
194 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
196 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
200 char objName[HDF_NAME_MAX_LEN+1];
202 for (int i=0; i<nbsons; i++) {
203 hdf_group->InternalObjectIndentify(i, objName);
205 if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0) continue;
207 hdf_object_type type = hdf_group->InternalObjectType(objName);
209 if (type == HDF_DATASET) {
210 HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
211 SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
213 } else if (type == HDF_GROUP) {
214 HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
215 SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
220 fprintf(fp, "%s\n", GROUP_ID_END);
222 hdf_group->CloseOnDisk();
225 //============================================================================
226 // function : SaveDatasetInASCIIfile
228 //============================================================================
229 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
231 hdf_dataset->OpenOnDisk();
233 long size = hdf_dataset->GetSize();
234 long ndim = hdf_dataset->nDim(); //Get number of dimesions
235 hdf_size *dim = new hdf_size[ndim];
236 hdf_type type = hdf_dataset->GetType();
237 hdf_byte_order order = hdf_dataset->GetOrder();
238 int nbAttr = hdf_dataset->nAttributes();
240 char* name = makeName(hdf_dataset->GetName());
242 fprintf(fp, "%s\n", DATASET_ID);
243 fprintf(fp, "%s %i %i\n", name, type, nbAttr);
246 hdf_dataset->GetDim(dim);
247 fprintf(fp, " %i\n", ndim);
249 for(int i = 0;i < ndim;i++) {
250 fprintf(fp, " %i", dim[i]);
256 fprintf(fp, "%li %i:", size, order);
258 if (type == HDF_STRING) {
259 char* val = new char[size];
260 hdf_dataset->ReadFromDisk(val);
261 fwrite(val, 1, size, fp);
263 } else if (type == HDF_FLOAT64) {
264 hdf_float64* val = new hdf_float64[size];
265 hdf_dataset->ReadFromDisk(val);
267 for (int i = 0, j = 0; i < size; i++) {
268 write_float64(fp, &val[i]);
269 if(++j == NB_FLOAT_IN_ROW) {
273 else fprintf(fp," ");
276 } else if(type == HDF_INT64) {
277 hdf_int64* val = new hdf_int64[size];
278 hdf_dataset->ReadFromDisk(val);
280 for (int i = 0, j = 0; i < size; i++) {
281 fprintf(fp, " %li", val[i]);
282 if(++j == NB_INTEGER_IN_ROW) {
288 } else if(type == HDF_INT32) {
289 hdf_int32* val = new hdf_int32[size];
290 hdf_dataset->ReadFromDisk(val);
292 for (int i = 0, j = 0; i < size; i++) {
293 fprintf(fp, " %i", val[i]);
294 if(++j == NB_INTEGER_IN_ROW) {
304 for ( unsigned j=0; j<nbAttr; j++ )
306 name = hdf_dataset->GetAttributeName(j);
307 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
309 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
313 fprintf(fp, "%s\n", DATASET_ID_END);
315 hdf_dataset->CloseOnDisk();
319 //============================================================================
320 // function : SaveAttributeInASCIIfile
322 //============================================================================
323 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
325 hdf_attribute->OpenOnDisk();
327 hdf_type type = hdf_attribute->GetType();
329 char* name = makeName(hdf_attribute->GetName());
330 int size = hdf_attribute->GetSize();
332 fprintf(fp, "%s\n", ATTRIBUTE_ID);
333 fprintf(fp, "%s %i %i\n", name, type, size);
337 if (type == HDF_STRING) {
338 char* val = new char[size+1];
339 hdf_attribute->ReadFromDisk(val);
341 fwrite(val, 1, size, fp);
344 } else if (type == HDF_FLOAT64) {
346 hdf_attribute->ReadFromDisk(&val);
347 write_float64(fp, &val);
349 } else if(type == HDF_INT64) {
351 hdf_attribute->ReadFromDisk(&val);
352 fprintf(fp, "%li \n", val);
353 } else if(type == HDF_INT32) {
355 hdf_attribute->ReadFromDisk(&val);
356 fprintf(fp, "%i \n", val);
359 fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
361 hdf_attribute->CloseOnDisk();
364 //############################## ASCII => HDF ################################
366 //============================================================================
367 // function : ConvertFromASCIIToHDF
368 // purpose : Converts a file pointed by thePath to HDF format
369 // Returns a name of directory where a created HDF file is placed
370 // The created file is named "hdf_from_ascii.hdf"
371 //============================================================================
372 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
374 // Get a temporary directory to store a file
375 string aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
376 // Build a full file name of temporary file
377 string aFullName = aTmpDir + aFileName;
379 HDFfile *hdf_file = new HDFfile((char*)aFullName.c_str());
380 hdf_file->CreateOnDisk();
382 FILE *fp = fopen(thePath, "r");
387 fscanf(fp, "%s", type);
388 fscanf(fp, "%i",&nbsons);
390 if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
392 for(i = 0; i < nbsons; i++) {
393 char id_of_begin[MAX_ID_SIZE];
394 fscanf(fp, "%s\n", id_of_begin);
396 if(strcmp(id_of_begin, GROUP_ID) == 0) {
397 if(!CreateGroupFromASCII(hdf_file, fp)) {
398 cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
402 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
403 if(!CreateDatasetFromASCII(hdf_file, fp)) {
404 cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
408 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
409 if(!CreateAttributeFromASCII(hdf_file, fp)) {
410 cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
415 cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl;
418 char id_of_end[MAX_ID_SIZE];
419 fscanf(fp, "%s", id_of_end);
420 if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
421 cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
425 hdf_file->CloseOnDisk();
428 int length = strlen(aTmpDir.c_str());
429 char *new_str = new char[ 1+length ];
430 strcpy(new_str , aTmpDir.c_str()) ;
436 //============================================================================
437 // function : CreateGroupFromASCII
438 // purpose : Creates a HDF group from a set attributes situated under theLabel
439 //============================================================================
440 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
442 char name[HDF_NAME_MAX_LEN+1];
444 fscanf(fp, "%s %i\n", name, &nbsons);
446 char* new_name = restoreName(name);
448 HDFgroup* hdf_group = new HDFgroup(new_name, father);
452 hdf_group->CreateOnDisk();
454 for(i = 0; i < nbsons; i++) {
455 char id_of_begin[MAX_ID_SIZE];
456 fscanf(fp, "%s\n", id_of_begin);
458 if(strcmp(id_of_begin, GROUP_ID) == 0) {
459 if(!CreateGroupFromASCII(hdf_group, fp)) {
460 cout << "Can not create subgroup " << i << " for group " << name << endl;
464 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
465 if(!CreateDatasetFromASCII(hdf_group, fp)) {
466 cout << "Can not create dataset " << i << " for group " << name << endl;
470 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
471 if(!CreateAttributeFromASCII(hdf_group, fp)) {
472 cout << "Can not create attribute " << i << " for group " << name << endl;
477 cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl;
480 hdf_group->CloseOnDisk();
481 hdf_group = 0; //will be deleted by father destructor
483 char id_of_end[MAX_ID_SIZE];
484 fscanf(fp, "%s\n", id_of_end);
485 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
486 cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
494 //============================================================================
495 // function : CreateDatasetFromASCII
496 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
497 //============================================================================
498 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
500 char name[HDF_NAME_MAX_LEN+1];
502 hdf_byte_order order;
506 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
507 char* new_name = restoreName(name);
509 fscanf(fp, "%i\n", &nbDim);
511 hdf_size* sizeArray = new hdf_size[nbDim];
513 for(i = 0; i<nbDim; i++) {
514 fscanf(fp, "%i\n", &dim);
518 // order (2-d member) was not written in earlier versions
520 int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
521 if ( nbRead < 2 ) { // fscanf stops before ":"
522 fscanf(fp, "%c", &tmp);
523 order = H5T_ORDER_NONE;
525 if ( type != HDF_FLOAT64 ) // use order only for FLOAT64
526 order = H5T_ORDER_NONE;
528 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
532 hdf_dataset->CreateOnDisk();
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 //============================================================================
654 //Find a temporary directory to store a file
658 char *Tmp_dir = getenv("SALOME_TMP_DIR");
659 if(Tmp_dir != NULL) {
660 aTmpDir = string(Tmp_dir);
661 if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
663 if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
665 if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
670 aTmpDir = string("C:\\");
672 aTmpDir = string("/tmp/");
676 srand((unsigned int)time(NULL));
677 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
679 sprintf(buffer, "%d", aRND);
680 string aSubDir(buffer);
681 if(aSubDir.size() <= 1) aSubDir = string("123409876");
683 aTmpDir += aSubDir; //Get RND sub directory
685 if(aTmpDir[aTmpDir.size()-1] != dir_separator) aTmpDir+=dir_separator;
688 if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
690 if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
694 string aDir = aTmpDir;
696 for(aRND = 0; Exists(aDir); aRND++) {
697 sprintf(buffer, "%d", aRND);
698 aDir = aTmpDir+buffer; //Build a unique directory name
702 //fuction CreateDirectory create only final directory, but not intermediate
703 CreateDirectory(aTmpDir.c_str(), NULL);
704 CreateDirectory(aDir.c_str(), NULL);
706 mkdir(aDir.c_str(), 0x1ff);
709 return aDir + dir_separator;
712 char* makeName(char* name)
714 string aName(name), aNewName;
715 int i, length = aName.size();
716 char replace = (char)19;
718 for(i=0; i<length; i++) {
719 if(aName[i] == ' ') aNewName+=replace;
720 else aNewName += aName[i];
723 length = strlen(aNewName.c_str());
724 char *new_str = new char[ 1+length ];
725 strcpy(new_str , aNewName.c_str()) ;
729 char* restoreName(char* name)
731 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] == replace) aNewName+=' ';
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 void write_float64(FILE* fp, hdf_float64* value)
748 unsigned char* array = (unsigned char*)value;
749 for(int i = 0; i < sizeof(hdf_float64); i++) {
750 unsigned tmp = (unsigned short)array[i];
751 fprintf(fp, " %2x", tmp);
755 void read_float64(FILE* fp, hdf_float64* value)
757 unsigned char* array = (unsigned char*)value;
758 for(int i = 0; i < sizeof(hdf_float64); i++) {
760 fscanf(fp, " %x", &tmp);
761 array[i] = (unsigned char)tmp;
765 bool Exists(const string thePath)
768 if ( GetFileAttributes ( thePath.c_str() ) == 0xFFFFFFFF ) {
769 if ( GetLastError () != ERROR_FILE_NOT_FOUND ) {
774 int status = access ( thePath.c_str() , F_OK );
775 if (status != 0) return false;
780 void Move(const string& fName, const string& fNameDst)
783 MoveFileEx (fName.c_str(), fNameDst.c_str(),MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
785 rename(fName.c_str(), fNameDst.c_str());