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