Salome HOME
bf003ae44c04b131eb328e22b2ed8b570eff71cd
[modules/gui.git] / src / LightApp / LightApp_HDFDriver.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "LightApp_HDFDriver.h"
20
21 #include "HDFexplorer.hxx"
22 #include "HDFOI.hxx"
23
24 // OCCT Includes
25 #include <TCollection_AsciiString.hxx>
26
27 /*! Constructor.*/
28 LightApp_HDFDriver::LightApp_HDFDriver()
29 {
30 }
31
32 /*! Destructor.*/
33 LightApp_HDFDriver::~LightApp_HDFDriver()
34 {
35 }
36
37 using namespace std;
38
39 //================================================================
40 //  Function : SaveDatasInFile
41 /*! Purpose  : save 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 //  Function : ReadDatasFromFile
168 /*! Purpose  : filling current driver from file 'theFileName'*/
169 //=======================================================================
170 bool LightApp_HDFDriver::ReadDatasFromFile( const char* theFileName, bool isMultiFile )
171 {
172   bool isASCII = false;
173   bool isError = false;
174   TCollection_AsciiString aHDFUrl;
175
176   HDFfile *hdf_file = 0;
177   HDFgroup *hdf_group_datacomponent = 0;
178   HDFgroup *hdf_group_study_structure = 0;
179   HDFgroup *hdf_sco_group  = 0;
180   HDFgroup *hdf_sco_group2 = 0;
181
182   std::map<std::string, std::string> mapEntryName;
183
184   if (HDFascii::isASCII(theFileName)) {
185     isASCII = true;
186     char* aResultPath = HDFascii::ConvertFromASCIIToHDF(theFileName);
187     aHDFUrl = aResultPath;
188     aHDFUrl += "hdf_from_ascii.hdf";
189     delete(aResultPath);
190   } else {
191     aHDFUrl = (char*)theFileName;
192   }
193
194   hdf_file = new HDFfile((char*)aHDFUrl.ToCString());
195
196   char aMultifileState[2];
197   char ASCIIfileState[2];
198
199   try {
200     hdf_file->OpenOnDisk(HDF_RDONLY);
201
202   } catch (HDFexception) {
203     //char *eStr = new char[strlen(aUrl.ToCString()) + 17];
204     //sprintf(eStr,"Can't open file %s", aUrl.ToCString());
205     //_errorCode = TCollection_AsciiString(eStr);
206     //delete [] eStr;
207     return false;
208   }
209
210   try {
211     if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
212       //_errorCode = "Study is empty";
213       isError = true;
214     } else {
215       hdf_group_study_structure = new HDFgroup ("STUDY_STRUCTURE", hdf_file);
216       hdf_group_study_structure->OpenOnDisk();
217
218       char name[HDF_NAME_MAX_LEN + 1];
219       Standard_Integer nbsons = hdf_group_study_structure->nInternalObjects();
220       for (Standard_Integer i = 0; i < nbsons; i++) {
221         hdf_group_study_structure->InternalObjectIndentify(i, name);
222         if (strncmp(name, "INTERNAL_COMPLEX", 16) == 0) continue;
223         hdf_object_type type = hdf_group_study_structure->InternalObjectType(name);
224         if (type == HDF_GROUP) {
225           hdf_sco_group2 = new HDFgroup (name, hdf_group_study_structure);
226           hdf_sco_group2->OpenOnDisk();
227
228           // Read component data
229           char* aCompDataType = NULL;
230           int aDataSize = 0;
231
232           if (hdf_sco_group2->ExistInternalObject("COMPONENTDATATYPE")) {
233             HDFdataset *hdf_dataset = new HDFdataset("COMPONENTDATATYPE", hdf_sco_group2);
234             hdf_dataset->OpenOnDisk();
235             aDataSize = hdf_dataset->GetSize();
236             aCompDataType = new char[aDataSize];
237             if (aCompDataType == NULL) {
238               isError = true;
239             } else {
240               hdf_dataset->ReadFromDisk(aCompDataType);
241
242               mapEntryName[name] = aCompDataType;
243
244               delete [] aCompDataType;
245             }
246
247             hdf_dataset->CloseOnDisk();
248             hdf_dataset = 0;
249           }
250
251           hdf_sco_group2->CloseOnDisk();
252         }
253       }
254
255       hdf_group_study_structure->CloseOnDisk();
256     }
257
258     if (!hdf_file->ExistInternalObject("DATACOMPONENT")) {
259       //_errorCode = "No components stored";
260       isError = true;
261     } else {
262       hdf_group_datacomponent = new HDFgroup ("DATACOMPONENT", hdf_file);
263       hdf_group_datacomponent->OpenOnDisk();
264
265       char name[HDF_NAME_MAX_LEN + 1];
266       Standard_Integer nbsons = hdf_group_datacomponent->nInternalObjects();
267       for (Standard_Integer i = 0; i < nbsons; i++) {
268         hdf_group_datacomponent->InternalObjectIndentify(i, name);
269         if (strncmp(name, "INTERNAL_COMPLEX", 16) == 0) continue;
270         hdf_object_type type = hdf_group_datacomponent->InternalObjectType(name);
271         if (type == HDF_GROUP) {
272           hdf_sco_group = new HDFgroup (name, hdf_group_datacomponent);
273           hdf_sco_group->OpenOnDisk();
274
275           // Read component data
276           unsigned char* aStreamFile = NULL;
277           int aStreamSize = 0;
278
279           if (hdf_sco_group->ExistInternalObject("FILE_STREAM")) {
280             HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group);
281             hdf_dataset->OpenOnDisk();
282             aStreamSize = hdf_dataset->GetSize();
283             aStreamFile = new unsigned char[aStreamSize];
284             if (aStreamFile == NULL) {
285               isError = true;
286             } else {
287               hdf_dataset->ReadFromDisk(aStreamFile);
288             }
289
290             hdf_dataset->CloseOnDisk();
291             hdf_dataset = 0;
292           }
293
294           HDFdataset *multifile_hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group);
295           multifile_hdf_dataset->OpenOnDisk();
296           multifile_hdf_dataset->ReadFromDisk(aMultifileState);
297           multifile_hdf_dataset->CloseOnDisk();
298           multifile_hdf_dataset = 0;
299
300           HDFdataset *ascii_hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group);
301           ascii_hdf_dataset->OpenOnDisk();
302           ascii_hdf_dataset->ReadFromDisk(ASCIIfileState);
303           ascii_hdf_dataset->CloseOnDisk();
304           ascii_hdf_dataset = 0;
305
306           isASCII = (ASCIIfileState[0] == 'A') ? true : false;
307
308           if (aStreamFile != NULL) {
309             // Put buffer to aListOfFiles and set to myMap
310             ListOfFiles aListOfFiles = PutStreamToFiles(aStreamFile, aStreamSize, isMultiFile);
311             char* aCompDataType = (char*)(mapEntryName[name].c_str());
312             SetListOfFiles(aCompDataType, aListOfFiles);
313
314             delete [] aStreamFile;
315           }
316
317           hdf_sco_group->CloseOnDisk();
318         }
319       }
320
321       hdf_group_datacomponent->CloseOnDisk();
322     }
323   } catch (HDFexception) {
324     isError = true;
325
326     //Handle(TColStd_HSequenceOfAsciiString) aFilesToRemove = new TColStd_HSequenceOfAsciiString;
327     //aFilesToRemove->Append(aHDFUrl);
328     //RemoveFiles(aFilesToRemove, true);
329   }
330
331   hdf_file->CloseOnDisk();
332   delete hdf_file; // all related hdf objects will be deleted
333
334   if (isASCII && !isError) {
335     //Handle(TColStd_HSequenceOfAsciiString) aFilesToRemove = new TColStd_HSequenceOfAsciiString;
336     //aFilesToRemove->Append(aHDFUrl);
337     //RemoveFiles(aFilesToRemove, true);
338   }
339
340   //std::map<std::string, std::string>::const_iterator it;
341   //for (it = mapEntryName.begin(); it != mapEntryName.end(); ++it) {
342   //  cout << "Read Component: entry = " << it->first
343   //       << ", Component data type = " << it->second << endl;
344   //}
345
346   return !isError;
347 }