Salome HOME
Copyright update 2022
[modules/gui.git] / src / LightApp / LightApp_HDFDriver.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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, or (at your option) any later version.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "LightApp_HDFDriver.h"
24
25 #include "HDFOI.hxx"
26
27 // OCCT Includes
28 #include <TCollection_AsciiString.hxx>
29
30 /*! Constructor.*/
31 LightApp_HDFDriver::LightApp_HDFDriver()
32 {
33 }
34
35 /*! Destructor.*/
36 LightApp_HDFDriver::~LightApp_HDFDriver()
37 {
38 }
39
40 /*!
41   Saves in file 'theFileName' datas from this driver
42 */
43 bool LightApp_HDFDriver::SaveDatasInFile( const char* theFileName, bool isMultiFile )
44 {
45   bool isASCII = false;
46   bool isError = false;
47
48   HDFfile *hdf_file = 0;
49   HDFgroup *hdf_group_datacomponent = 0;
50   HDFgroup *hdf_group_study_structure = 0;
51   HDFgroup *hdf_sco_group  = 0;
52   HDFgroup *hdf_sco_group2 = 0;
53   HDFdataset *hdf_dataset = 0;
54   hdf_size aHDFSize[1];
55
56   try {
57     hdf_file = new HDFfile ((char*)theFileName);
58     hdf_file->CreateOnDisk();
59
60     //-----------------------------------------------------------------------
61     // 1 - Create a groupe for each SComponent and Update the PersistanceRef
62     //-----------------------------------------------------------------------
63     hdf_group_datacomponent = new HDFgroup ("DATACOMPONENT", hdf_file);
64     hdf_group_datacomponent->CreateOnDisk();
65
66     std::map<std::string, std::string> mapNameEntry;
67
68     int tag = 1;
69     std::map<std::string, ListOfFiles>::const_iterator it;
70     for (it = myMap.begin(); it != myMap.end(); ++it, ++tag) {
71       std::string aName (it->first);
72       char* aModuleName = const_cast<char*>(aName.c_str());
73       unsigned char* aBuffer;
74       long           aBufferSize;
75       PutFilesToStream(aName, aBuffer, aBufferSize, isMultiFile);
76
77       //Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
78       //TCollection_AsciiString scoid = sco->GetID();
79       //hdf_sco_group = new HDFgroup(scoid.ToCString(), hdf_group_datacomponent);
80
81       TCollection_AsciiString entry ("0:1:");
82       entry += TCollection_AsciiString(tag);
83       mapNameEntry[aModuleName] = entry.ToCString();
84
85       //hdf_sco_group = new HDFgroup (aModuleName, hdf_group_datacomponent);
86       hdf_sco_group = new HDFgroup (entry.ToCString(), hdf_group_datacomponent);
87       hdf_sco_group->CreateOnDisk();
88
89       aHDFSize[0] = aBufferSize;
90
91       hdf_dataset = new HDFdataset ("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
92       hdf_dataset->CreateOnDisk();
93       hdf_dataset->WriteOnDisk(aBuffer); //Save the stream in the HDF file
94       hdf_dataset->CloseOnDisk();
95       hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
96
97       // store multifile state
98       aHDFSize[0] = 2;
99       hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
100       hdf_dataset->CreateOnDisk();
101       hdf_dataset->WriteOnDisk((void*)(isMultiFile ? "M" : "S")); // save: multi or single
102       hdf_dataset->CloseOnDisk();
103       hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
104
105       // store ASCII state
106       aHDFSize[0] = 2;
107       hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
108       hdf_dataset->CreateOnDisk();
109       hdf_dataset->WriteOnDisk((void*)(isASCII ? "A" : "B")); // save: ASCII or BINARY
110       hdf_dataset->CloseOnDisk();
111       hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
112
113       hdf_sco_group->CloseOnDisk();
114       hdf_sco_group = 0; // will be deleted by hdf_group_datacomponent destructor
115
116       delete [] aBuffer;
117     }
118
119     hdf_group_datacomponent->CloseOnDisk();
120     hdf_group_datacomponent = 0; // will be deleted by hdf_file destructor
121
122     //-----------------------------------------------------------------------
123     // 3 - Write the Study Structure
124     //-----------------------------------------------------------------------
125     hdf_group_study_structure = new HDFgroup ("STUDY_STRUCTURE", hdf_file);
126     hdf_group_study_structure->CreateOnDisk();
127
128     for (it = myMap.begin(); it != myMap.end(); ++it) {
129       std::string aName (it->first);
130       char* aModuleName = const_cast<char*>(aName.c_str());
131
132       //hdf_sco_group2 = new HDFgroup(scid.ToCString(), hdf_group_study_structure);
133       char* entry = (char*)(mapNameEntry[aModuleName].c_str());
134       hdf_sco_group2 = new HDFgroup (entry, hdf_group_study_structure);
135       hdf_sco_group2->CreateOnDisk();
136
137       // ComponentDataType treatment
138       hdf_int32 name_len = (hdf_int32)strlen(aModuleName);
139       aHDFSize[0] = name_len + 1;
140       hdf_dataset = new HDFdataset ("COMPONENTDATATYPE", hdf_sco_group2, HDF_STRING, aHDFSize, 1);
141       hdf_dataset->CreateOnDisk();
142       hdf_dataset->WriteOnDisk(aModuleName);
143       hdf_dataset->CloseOnDisk();
144       hdf_dataset = 0; //will be deleted by hdf_sco_group2 destructor
145
146       hdf_sco_group2->CloseOnDisk();
147       hdf_sco_group2 = 0; // will be deleted by hdf_group_study_structure destructor
148     }
149
150     hdf_group_study_structure->CloseOnDisk();
151     hdf_group_study_structure = 0; // will be deleted by hdf_file destructor
152
153     hdf_file->CloseOnDisk();
154     delete hdf_file; // recursively deletes all hdf objects...
155
156   } catch (HDFexception) {
157     isError = true;
158   }
159   if (isASCII && !isError) { // save file in ASCII format
160     HDFascii::ConvertFromHDFToASCII(theFileName, true);
161   }
162
163   return !isError;
164 }
165
166 /*!
167   Filling current driver from file 'theFileName'
168 */
169 bool LightApp_HDFDriver::ReadDatasFromFile( const char* theFileName, bool isMultiFile )
170 {
171   bool isASCII = false;
172   bool isError = false;
173   TCollection_AsciiString aHDFUrl;
174
175   HDFfile *hdf_file = 0;
176   HDFgroup *hdf_group_datacomponent = 0;
177   HDFgroup *hdf_group_study_structure = 0;
178   HDFgroup *hdf_sco_group  = 0;
179   HDFgroup *hdf_sco_group2 = 0;
180
181   std::map<std::string, std::string> mapEntryName;
182
183   if (HDFascii::isASCII(theFileName)) {
184     isASCII = true;
185     char* aResultPath = HDFascii::ConvertFromASCIIToHDF(theFileName);
186     aHDFUrl = aResultPath;
187     aHDFUrl += "hdf_from_ascii.hdf";
188     delete(aResultPath);
189   } else {
190     aHDFUrl = (char*)theFileName;
191   }
192
193   hdf_file = new HDFfile((char*)aHDFUrl.ToCString());
194
195   char aMultifileState[2];
196   char ASCIIfileState[2];
197
198   try {
199     hdf_file->OpenOnDisk(HDF_RDONLY);
200
201   } catch (HDFexception) {
202     //char *eStr = new char[strlen(aUrl.ToCString()) + 17];
203     //sprintf(eStr,"Can't open file %s", aUrl.ToCString());
204     //_errorCode = TCollection_AsciiString(eStr);
205     //delete [] eStr;
206     return false;
207   }
208
209   try {
210     if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
211       //_errorCode = "Study is empty";
212       isError = true;
213     } else {
214       hdf_group_study_structure = new HDFgroup ("STUDY_STRUCTURE", hdf_file);
215       hdf_group_study_structure->OpenOnDisk();
216
217       char name[HDF_NAME_MAX_LEN + 1];
218       Standard_Integer nbsons = hdf_group_study_structure->nInternalObjects();
219       for (Standard_Integer i = 0; i < nbsons; i++) {
220         hdf_group_study_structure->InternalObjectIndentify(i, name);
221         if (strncmp(name, "INTERNAL_COMPLEX", 16) == 0) continue;
222         hdf_object_type type = hdf_group_study_structure->InternalObjectType(name);
223         if (type == HDF_GROUP) {
224           hdf_sco_group2 = new HDFgroup (name, hdf_group_study_structure);
225           hdf_sco_group2->OpenOnDisk();
226
227           // Read component data
228           char* aCompDataType = NULL;
229           int aDataSize = 0;
230
231           if (hdf_sco_group2->ExistInternalObject("COMPONENTDATATYPE")) {
232             HDFdataset *hdf_dataset = new HDFdataset("COMPONENTDATATYPE", hdf_sco_group2);
233             hdf_dataset->OpenOnDisk();
234             aDataSize = hdf_dataset->GetSize();
235             aCompDataType = new char[aDataSize];
236             if (aCompDataType == NULL) {
237               isError = true;
238             } else {
239               hdf_dataset->ReadFromDisk(aCompDataType);
240
241               mapEntryName[name] = aCompDataType;
242
243               delete [] aCompDataType;
244             }
245
246             hdf_dataset->CloseOnDisk();
247             hdf_dataset = 0;
248           }
249
250           hdf_sco_group2->CloseOnDisk();
251         }
252       }
253
254       hdf_group_study_structure->CloseOnDisk();
255     }
256
257     if (!hdf_file->ExistInternalObject("DATACOMPONENT")) {
258       //_errorCode = "No components stored";
259       isError = true;
260     } else {
261       hdf_group_datacomponent = new HDFgroup ("DATACOMPONENT", hdf_file);
262       hdf_group_datacomponent->OpenOnDisk();
263
264       char name[HDF_NAME_MAX_LEN + 1];
265       Standard_Integer nbsons = hdf_group_datacomponent->nInternalObjects();
266       for (Standard_Integer i = 0; i < nbsons; i++) {
267         hdf_group_datacomponent->InternalObjectIndentify(i, name);
268         if (strncmp(name, "INTERNAL_COMPLEX", 16) == 0) continue;
269         hdf_object_type type = hdf_group_datacomponent->InternalObjectType(name);
270         if (type == HDF_GROUP) {
271           hdf_sco_group = new HDFgroup (name, hdf_group_datacomponent);
272           hdf_sco_group->OpenOnDisk();
273
274           // Read component data
275           unsigned char* aStreamFile = NULL;
276           int aStreamSize = 0;
277
278           if (hdf_sco_group->ExistInternalObject("FILE_STREAM")) {
279             HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group);
280             hdf_dataset->OpenOnDisk();
281             aStreamSize = hdf_dataset->GetSize();
282             aStreamFile = new unsigned char[aStreamSize];
283             if (aStreamFile == NULL) {
284               isError = true;
285             } else {
286               hdf_dataset->ReadFromDisk(aStreamFile);
287             }
288
289             hdf_dataset->CloseOnDisk();
290             hdf_dataset = 0;
291           }
292
293           HDFdataset *multifile_hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group);
294           multifile_hdf_dataset->OpenOnDisk();
295           multifile_hdf_dataset->ReadFromDisk(aMultifileState);
296           multifile_hdf_dataset->CloseOnDisk();
297           multifile_hdf_dataset = 0;
298
299           HDFdataset *ascii_hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group);
300           ascii_hdf_dataset->OpenOnDisk();
301           ascii_hdf_dataset->ReadFromDisk(ASCIIfileState);
302           ascii_hdf_dataset->CloseOnDisk();
303           ascii_hdf_dataset = 0;
304
305           isASCII = (ASCIIfileState[0] == 'A') ? true : false;
306
307           if (aStreamFile != NULL) {
308             // Put buffer to aListOfFiles and set to myMap
309             ListOfFiles aListOfFiles = PutStreamToFiles(aStreamFile, aStreamSize, isMultiFile);
310             char* aCompDataType = (char*)(mapEntryName[name].c_str());
311             SetListOfFiles(aCompDataType, aListOfFiles);
312
313             delete [] aStreamFile;
314           }
315
316           hdf_sco_group->CloseOnDisk();
317         }
318       }
319
320       hdf_group_datacomponent->CloseOnDisk();
321     }
322   } catch (HDFexception) {
323     isError = true;
324
325     //Handle(TColStd_HSequenceOfAsciiString) aFilesToRemove = new TColStd_HSequenceOfAsciiString;
326     //aFilesToRemove->Append(aHDFUrl);
327     //RemoveFiles(aFilesToRemove, true);
328   }
329
330   hdf_file->CloseOnDisk();
331   delete hdf_file; // all related hdf objects will be deleted
332
333   if (isASCII && !isError) {
334     //Handle(TColStd_HSequenceOfAsciiString) aFilesToRemove = new TColStd_HSequenceOfAsciiString;
335     //aFilesToRemove->Append(aHDFUrl);
336     //RemoveFiles(aFilesToRemove, true);
337   }
338
339   //std::map<std::string, std::string>::const_iterator it;
340   //for (it = mapEntryName.begin(); it != mapEntryName.end(); ++it) {
341   //  cout << "Read Component: entry = " << it->first
342   //       << ", Component data type = " << it->second << endl;
343   //}
344
345   return !isError;
346 }