Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/gui.git] / src / LightApp / LightApp_HDFDriver.cxx
1 //  Copyright (C) 2007-2008  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.
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 #include "LightApp_HDFDriver.h"
23
24 #include "HDFOI.hxx"
25
26 // OCCT Includes
27 #include <TCollection_AsciiString.hxx>
28
29 /*! Constructor.*/
30 LightApp_HDFDriver::LightApp_HDFDriver()
31 {
32 }
33
34 /*! Destructor.*/
35 LightApp_HDFDriver::~LightApp_HDFDriver()
36 {
37 }
38
39 using namespace std;
40
41 /*!
42   Saves in file 'theFileName' datas from this driver
43 */
44 bool LightApp_HDFDriver::SaveDatasInFile( const char* theFileName, bool isMultiFile )
45 {
46   bool isASCII = false;
47   bool isError = false;
48
49   HDFfile *hdf_file = 0;
50   HDFgroup *hdf_group_datacomponent = 0;
51   HDFgroup *hdf_group_study_structure = 0;
52   HDFgroup *hdf_sco_group  = 0;
53   HDFgroup *hdf_sco_group2 = 0;
54   HDFdataset *hdf_dataset = 0;
55   hdf_size aHDFSize[1];
56
57   try {
58     hdf_file = new HDFfile ((char*)theFileName);
59     hdf_file->CreateOnDisk();
60
61     //-----------------------------------------------------------------------
62     // 1 - Create a groupe for each SComponent and Update the PersistanceRef
63     //-----------------------------------------------------------------------
64     hdf_group_datacomponent = new HDFgroup ("DATACOMPONENT", hdf_file);
65     hdf_group_datacomponent->CreateOnDisk();
66
67     std::map<std::string, std::string> mapNameEntry;
68
69     int tag = 1;
70     std::map<std::string, ListOfFiles>::const_iterator it;
71     for (it = myMap.begin(); it != myMap.end(); ++it, ++tag) {
72       std::string aName (it->first);
73       char* aModuleName = const_cast<char*>(aName.c_str());
74       unsigned char* aBuffer;
75       long           aBufferSize;
76       PutFilesToStream(aName, aBuffer, aBufferSize, isMultiFile);
77
78       //Handle(SALOMEDSImpl_SComponent) sco = itcomponent.Value();
79       //TCollection_AsciiString scoid = sco->GetID();
80       //hdf_sco_group = new HDFgroup(scoid.ToCString(), hdf_group_datacomponent);
81
82       TCollection_AsciiString entry ("0:1:");
83       entry += TCollection_AsciiString(tag);
84       mapNameEntry[aModuleName] = entry.ToCString();
85
86       //hdf_sco_group = new HDFgroup (aModuleName, hdf_group_datacomponent);
87       hdf_sco_group = new HDFgroup (entry.ToCString(), hdf_group_datacomponent);
88       hdf_sco_group->CreateOnDisk();
89
90       aHDFSize[0] = aBufferSize;
91
92       hdf_dataset = new HDFdataset ("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
93       hdf_dataset->CreateOnDisk();
94       hdf_dataset->WriteOnDisk(aBuffer); //Save the stream in the HDF file
95       hdf_dataset->CloseOnDisk();
96       hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
97
98       // store multifile state
99       aHDFSize[0] = 2;
100       hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
101       hdf_dataset->CreateOnDisk();
102       hdf_dataset->WriteOnDisk((void*)(isMultiFile ? "M" : "S")); // save: multi or single
103       hdf_dataset->CloseOnDisk();
104       hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
105
106       // store ASCII state
107       aHDFSize[0] = 2;
108       hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
109       hdf_dataset->CreateOnDisk();
110       hdf_dataset->WriteOnDisk((void*)(isASCII ? "A" : "B")); // save: ASCII or BINARY
111       hdf_dataset->CloseOnDisk();
112       hdf_dataset = 0; //will be deleted by hdf_sco_group destructor
113
114       hdf_sco_group->CloseOnDisk();
115       hdf_sco_group = 0; // will be deleted by hdf_group_datacomponent destructor
116
117       delete [] aBuffer;
118     }
119
120     hdf_group_datacomponent->CloseOnDisk();
121     hdf_group_datacomponent = 0; // will be deleted by hdf_file destructor
122
123     //-----------------------------------------------------------------------
124     // 3 - Write the Study Structure
125     //-----------------------------------------------------------------------
126     hdf_group_study_structure = new HDFgroup ("STUDY_STRUCTURE", hdf_file);
127     hdf_group_study_structure->CreateOnDisk();
128
129     for (it = myMap.begin(); it != myMap.end(); ++it) {
130       std::string aName (it->first);
131       char* aModuleName = const_cast<char*>(aName.c_str());
132
133       //hdf_sco_group2 = new HDFgroup(scid.ToCString(), hdf_group_study_structure);
134       char* entry = (char*)(mapNameEntry[aModuleName].c_str());
135       hdf_sco_group2 = new HDFgroup (entry, hdf_group_study_structure);
136       hdf_sco_group2->CreateOnDisk();
137
138       // ComponentDataType treatment
139       hdf_int32 name_len = (hdf_int32)strlen(aModuleName);
140       aHDFSize[0] = name_len + 1;
141       hdf_dataset = new HDFdataset ("COMPONENTDATATYPE", hdf_sco_group2, HDF_STRING, aHDFSize, 1);
142       hdf_dataset->CreateOnDisk();
143       hdf_dataset->WriteOnDisk(aModuleName);
144       hdf_dataset->CloseOnDisk();
145       hdf_dataset = 0; //will be deleted by hdf_sco_group2 destructor
146
147       hdf_sco_group2->CloseOnDisk();
148       hdf_sco_group2 = 0; // will be deleted by hdf_group_study_structure destructor
149     }
150
151     hdf_group_study_structure->CloseOnDisk();
152     hdf_group_study_structure = 0; // will be deleted by hdf_file destructor
153
154     hdf_file->CloseOnDisk();
155     delete hdf_file; // recursively deletes all hdf objects...
156
157   } catch (HDFexception) {
158     isError = true;
159   }
160   if (isASCII && !isError) { // save file in ASCII format
161     HDFascii::ConvertFromHDFToASCII(theFileName, true);
162   }
163
164   return !isError;
165 }
166
167 /*!
168   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 }