7ed7467d |
1 | // Copyright (c) 2015 OPEN CASCADE SAS |
2 | // |
3 | // This file is part of Open CASCADE Technology software library. |
4 | // |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
10 | // |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
13 | |
14 | #include <StdLDrivers_DocumentRetrievalDriver.hxx> |
15 | #include <StdLDrivers.hxx> |
7ed7467d |
16 | |
ff205346 |
17 | #include <StdObjMgt_Persistent.hxx> |
7ed7467d |
18 | #include <StdObjMgt_MapOfInstantiators.hxx> |
19 | #include <StdObjMgt_ReadData.hxx> |
20 | |
21 | #include <Storage_HeaderData.hxx> |
22 | #include <Storage_TypeData.hxx> |
23 | #include <Storage_RootData.hxx> |
24 | #include <Storage_BaseDriver.hxx> |
25 | #include <Storage_StreamTypeMismatchError.hxx> |
26 | #include <Storage_StreamFormatError.hxx> |
27 | #include <Storage_StreamReadError.hxx> |
28 | |
29 | #include <PCDM.hxx> |
30 | #include <PCDM_ReadWriter.hxx> |
31 | |
32 | #include <Standard_ErrorHandler.hxx> |
201c2208 |
33 | #include <Standard_NotImplemented.hxx> |
7ed7467d |
34 | #include <NCollection_Array1.hxx> |
ff205346 |
35 | #include <NCollection_Handle.hxx> |
7ed7467d |
36 | #include <TDocStd_Document.hxx> |
37 | |
38 | IMPLEMENT_STANDARD_RTTIEXT (StdLDrivers_DocumentRetrievalDriver, PCDM_RetrievalDriver) |
39 | |
40 | //======================================================================= |
41 | //function : CreateDocument |
42 | //purpose : Create an empty TDocStd_Document |
43 | //======================================================================= |
44 | Handle(CDM_Document) StdLDrivers_DocumentRetrievalDriver::CreateDocument() |
45 | { |
46 | return new TDocStd_Document (PCDM_RetrievalDriver::GetFormat()); |
47 | } |
48 | |
49 | //======================================================================= |
50 | //function : Read |
51 | //purpose : Retrieve the content of a file into a new document |
52 | //======================================================================= |
45d8465e |
53 | void StdLDrivers_DocumentRetrievalDriver::Read (const TCollection_ExtendedString& theFileName, |
7ed7467d |
54 | const Handle(CDM_Document)& theNewDocument, |
55 | const Handle(CDM_Application)&) |
ff205346 |
56 | { |
57 | // Read header data and persistent document |
58 | Storage_HeaderData aHeaderData; |
59 | Handle(StdObjMgt_Persistent) aPDocument = read (theFileName, aHeaderData); |
45d8465e |
60 | if (aPDocument.IsNull()) |
61 | return; |
ff205346 |
62 | |
63 | // Import transient document from the persistent one |
45d8465e |
64 | aPDocument->ImportDocument ( |
65 | Handle(TDocStd_Document)::DownCast (theNewDocument)); |
ff205346 |
66 | |
45d8465e |
67 | // Copy comments from the header data |
68 | theNewDocument->SetComments (aHeaderData.Comments()); |
ff205346 |
69 | } |
70 | |
71 | //======================================================================= |
72 | //function : read |
73 | //purpose : Read persistent document from a file |
74 | //======================================================================= |
75 | Handle(StdObjMgt_Persistent) StdLDrivers_DocumentRetrievalDriver::read ( |
76 | const TCollection_ExtendedString& theFileName, |
77 | Storage_HeaderData& theHeaderData) |
7ed7467d |
78 | { |
79 | Standard_Integer i; |
80 | |
81 | // Create a driver appropriate for the given file |
ff205346 |
82 | PCDM_BaseDriverPointer aFileDriverPtr; |
83 | if (PCDM::FileDriverType (TCollection_AsciiString (theFileName), aFileDriverPtr) == PCDM_TOFD_Unknown) |
7ed7467d |
84 | { |
85 | myReaderStatus = PCDM_RS_UnknownFileDriver; |
ff205346 |
86 | return NULL; |
7ed7467d |
87 | } |
88 | |
ff205346 |
89 | NCollection_Handle<Storage_BaseDriver> aFileDriver (aFileDriverPtr); |
90 | |
7ed7467d |
91 | // Try to open the file |
45d8465e |
92 | try |
93 | { |
94 | OCC_CATCH_SIGNALS |
95 | PCDM_ReadWriter::Open (*aFileDriver, theFileName, Storage_VSRead); |
96 | myReaderStatus = PCDM_RS_OK; |
97 | } |
98 | catch (Standard_Failure) |
99 | { |
100 | myReaderStatus = PCDM_RS_OpenError; |
101 | |
102 | Standard_SStream aMsg; |
103 | aMsg << Standard_Failure::Caught() << endl; |
104 | Standard_Failure::Raise (aMsg); |
105 | } |
7ed7467d |
106 | |
107 | // Read header section |
ff205346 |
108 | if (!theHeaderData.Read (*aFileDriver)) |
109 | raiseOnStorageError (theHeaderData.ErrorStatus()); |
7ed7467d |
110 | |
111 | // Read type section |
ff205346 |
112 | Storage_TypeData aTypeData; |
113 | if (!aTypeData.Read (*aFileDriver)) |
114 | raiseOnStorageError (aTypeData.ErrorStatus()); |
7ed7467d |
115 | |
116 | // Read root section |
ff205346 |
117 | Storage_RootData aRootData; |
118 | if (!aRootData.Read (*aFileDriver)) |
119 | raiseOnStorageError (aRootData.ErrorStatus()); |
7ed7467d |
120 | |
ff205346 |
121 | if (aRootData.NumberOfRoots() < 1) |
7ed7467d |
122 | { |
123 | myReaderStatus = PCDM_RS_NoDocument; |
124 | |
125 | Standard_SStream aMsg; |
126 | aMsg << "could not find any document in this file" << endl; |
127 | Standard_Failure::Raise (aMsg); |
7ed7467d |
128 | } |
129 | |
130 | // Select instantiators for the used types |
131 | NCollection_Array1<StdObjMgt_Persistent::Instantiator> |
ff205346 |
132 | anInstantiators (1, aTypeData.NumberOfTypes()); |
7ed7467d |
133 | { |
134 | StdObjMgt_MapOfInstantiators aMapOfInstantiators; |
ff205346 |
135 | bindTypes (aMapOfInstantiators); |
7ed7467d |
136 | |
137 | TColStd_SequenceOfAsciiString anUnknownTypes; |
138 | Standard_Integer aCurTypeNum; |
139 | TCollection_AsciiString aCurTypeName; |
140 | |
ff205346 |
141 | for (i = 1; i <= aTypeData.NumberOfTypes(); i++) |
7ed7467d |
142 | { |
ff205346 |
143 | aCurTypeName = aTypeData.Type (i); |
144 | aCurTypeNum = aTypeData.Type (aCurTypeName); |
7ed7467d |
145 | |
146 | StdObjMgt_Persistent::Instantiator anInstantiator; |
147 | if (aMapOfInstantiators.Find (aCurTypeName, anInstantiator)) |
148 | anInstantiators (aCurTypeNum) = anInstantiator; |
149 | else |
150 | anUnknownTypes.Append (aCurTypeName); |
151 | } |
152 | |
153 | if (!anUnknownTypes.IsEmpty()) |
154 | { |
155 | myReaderStatus = PCDM_RS_TypeNotFoundInSchema; |
156 | |
157 | Standard_SStream aMsg; |
158 | aMsg << "cannot read: `" << theFileName |
159 | << "' because it contains the following unknown types: "; |
160 | for (i = 1; i <= anUnknownTypes.Length(); i++) |
161 | { |
162 | aMsg << anUnknownTypes(i); |
163 | if (i < anUnknownTypes.Length()) aMsg << ","; |
164 | else aMsg << endl; |
165 | } |
166 | |
167 | Standard_Failure::Raise (aMsg); |
7ed7467d |
168 | } |
169 | } |
170 | |
171 | // Read and parse reference section |
ff205346 |
172 | StdObjMgt_ReadData aReadData (*aFileDriver, theHeaderData.NumberOfObjects()); |
7ed7467d |
173 | |
ff205346 |
174 | raiseOnStorageError (aFileDriver->BeginReadRefSection()); |
7ed7467d |
175 | |
176 | Standard_Integer len = aFileDriver->RefSectionSize(); |
177 | for (i = 1; i <= len; i++) |
178 | { |
179 | Standard_Integer aRef = 0, aType = 0; |
180 | Storage_Error anError; |
181 | try |
182 | { |
183 | OCC_CATCH_SIGNALS |
184 | aFileDriver->ReadReferenceType (aRef, aType); |
185 | anError = Storage_VSOk; |
186 | } |
187 | catch (Storage_StreamTypeMismatchError) |
188 | { |
189 | anError = Storage_VSTypeMismatch; |
190 | } |
191 | |
ff205346 |
192 | raiseOnStorageError (anError); |
7ed7467d |
193 | |
ff205346 |
194 | aReadData.CreatePersistentObject (aRef, anInstantiators (aType)); |
7ed7467d |
195 | } |
196 | |
ff205346 |
197 | raiseOnStorageError (aFileDriver->EndReadRefSection()); |
7ed7467d |
198 | |
199 | // Read and parse data section |
ff205346 |
200 | raiseOnStorageError (aFileDriver->BeginReadDataSection()); |
7ed7467d |
201 | |
ff205346 |
202 | for (i = 1; i <= theHeaderData.NumberOfObjects(); i++) |
7ed7467d |
203 | { |
ff205346 |
204 | Storage_Error anError; |
205 | try |
7ed7467d |
206 | { |
ff205346 |
207 | OCC_CATCH_SIGNALS |
208 | aReadData.ReadPersistentObject (i); |
209 | anError = Storage_VSOk; |
7ed7467d |
210 | } |
ff205346 |
211 | catch (Storage_StreamTypeMismatchError) { anError = Storage_VSTypeMismatch; } |
212 | catch (Storage_StreamFormatError ) { anError = Storage_VSFormatError; } |
213 | catch (Storage_StreamReadError ) { anError = Storage_VSFormatError; } |
7ed7467d |
214 | |
ff205346 |
215 | raiseOnStorageError (anError); |
216 | } |
7ed7467d |
217 | |
ff205346 |
218 | raiseOnStorageError (aFileDriver->EndReadDataSection()); |
7ed7467d |
219 | |
ff205346 |
220 | // Get persistent document from the root object |
221 | return aReadData.PersistentObject (aRootData.Roots()->First()->Reference()); |
7ed7467d |
222 | } |
223 | |
201c2208 |
224 | //======================================================================= |
225 | //function : Read |
226 | //purpose : not implemented |
227 | //======================================================================= |
228 | |
229 | void StdLDrivers_DocumentRetrievalDriver::Read (Standard_IStream& /*theIStream*/, |
230 | const Handle(Storage_Data)& /*theStorageData*/, |
231 | const Handle(CDM_Document)& /*theDoc*/, |
232 | const Handle(CDM_Application)& /*theApplication*/) |
233 | { |
234 | Standard_NotImplemented::Raise ("Reading from stream is not supported by StdLDrivers_DocumentRetrievalDriver"); |
235 | } |
236 | |
7ed7467d |
237 | //======================================================================= |
ff205346 |
238 | //function : raiseOnStorageError |
7ed7467d |
239 | //purpose : Update the reader status and raise an exception |
240 | // appropriate for the given storage error |
241 | //======================================================================= |
ff205346 |
242 | void StdLDrivers_DocumentRetrievalDriver::raiseOnStorageError (Storage_Error theError) |
7ed7467d |
243 | { |
244 | Standard_SStream aMsg; |
245 | |
246 | switch (theError) |
247 | { |
248 | case Storage_VSOk: |
ff205346 |
249 | break; |
7ed7467d |
250 | |
251 | case Storage_VSOpenError: |
252 | case Storage_VSNotOpen: |
253 | case Storage_VSAlreadyOpen: |
254 | myReaderStatus = PCDM_RS_OpenError; |
255 | aMsg << "Stream Open Error" << endl; |
ff205346 |
256 | Standard_Failure::Raise (aMsg); |
7ed7467d |
257 | |
258 | case Storage_VSModeError: |
259 | myReaderStatus = PCDM_RS_WrongStreamMode; |
260 | aMsg << "Stream is opened with a wrong mode for operation" << endl; |
ff205346 |
261 | Standard_Failure::Raise (aMsg); |
7ed7467d |
262 | |
263 | case Storage_VSSectionNotFound: |
264 | myReaderStatus = PCDM_RS_FormatFailure; |
265 | aMsg << "Section is not found" << endl; |
ff205346 |
266 | Standard_Failure::Raise (aMsg); |
7ed7467d |
267 | |
268 | case Storage_VSFormatError: |
269 | myReaderStatus = PCDM_RS_FormatFailure; |
270 | aMsg << "Wrong format error" << endl; |
ff205346 |
271 | Standard_Failure::Raise (aMsg); |
7ed7467d |
272 | |
273 | case Storage_VSUnknownType: |
274 | myReaderStatus = PCDM_RS_TypeFailure; |
275 | aMsg << "Try to read an unknown type" << endl; |
ff205346 |
276 | Standard_Failure::Raise (aMsg); |
7ed7467d |
277 | |
278 | case Storage_VSTypeMismatch: |
279 | myReaderStatus = PCDM_RS_TypeFailure; |
280 | aMsg << "Try to read a wrong primitive type" << endl; |
ff205346 |
281 | Standard_Failure::Raise (aMsg); |
7ed7467d |
282 | |
283 | default: |
284 | myReaderStatus = PCDM_RS_DriverFailure; |
285 | aMsg << "Retrieval Driver Failure" << endl; |
ff205346 |
286 | Standard_Failure::Raise (aMsg); |
7ed7467d |
287 | } |
7ed7467d |
288 | } |
289 | |
290 | //======================================================================= |
ff205346 |
291 | //function : bindTypes |
7ed7467d |
292 | //purpose : Register types |
293 | //======================================================================= |
ff205346 |
294 | void StdLDrivers_DocumentRetrievalDriver::bindTypes (StdObjMgt_MapOfInstantiators& theMap) |
7ed7467d |
295 | { |
296 | StdLDrivers::BindTypes (theMap); |
297 | } |