1 // Copyright (c) 2015 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <StdLDrivers_DocumentRetrievalDriver.hxx>
15 #include <StdLDrivers.hxx>
17 #include <StdObjMgt_Persistent.hxx>
18 #include <StdObjMgt_MapOfInstantiators.hxx>
19 #include <StdObjMgt_ReadData.hxx>
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>
30 #include <PCDM_ReadWriter.hxx>
32 #include <Standard_ErrorHandler.hxx>
33 #include <Standard_NotImplemented.hxx>
34 #include <NCollection_Array1.hxx>
35 #include <NCollection_Handle.hxx>
36 #include <TDocStd_Document.hxx>
38 IMPLEMENT_STANDARD_RTTIEXT (StdLDrivers_DocumentRetrievalDriver, PCDM_RetrievalDriver)
40 //=======================================================================
41 //function : CreateDocument
42 //purpose : Create an empty TDocStd_Document
43 //=======================================================================
44 Handle(CDM_Document) StdLDrivers_DocumentRetrievalDriver::CreateDocument()
46 return new TDocStd_Document (PCDM_RetrievalDriver::GetFormat());
49 //=======================================================================
51 //purpose : Retrieve the content of a file into a new document
52 //=======================================================================
53 void StdLDrivers_DocumentRetrievalDriver::Read (const TCollection_ExtendedString& theFileName,
54 const Handle(CDM_Document)& theNewDocument,
55 const Handle(CDM_Application)&)
57 // Read header data and persistent document
58 Storage_HeaderData aHeaderData;
59 Handle(StdObjMgt_Persistent) aPDocument = read (theFileName, aHeaderData);
60 if (aPDocument.IsNull())
63 // Import transient document from the persistent one
64 aPDocument->ImportDocument (
65 Handle(TDocStd_Document)::DownCast (theNewDocument));
67 // Copy comments from the header data
68 theNewDocument->SetComments (aHeaderData.Comments());
71 //=======================================================================
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)
81 // Create a driver appropriate for the given file
82 PCDM_BaseDriverPointer aFileDriverPtr;
83 if (PCDM::FileDriverType (TCollection_AsciiString (theFileName), aFileDriverPtr) == PCDM_TOFD_Unknown)
85 myReaderStatus = PCDM_RS_UnknownFileDriver;
89 NCollection_Handle<Storage_BaseDriver> aFileDriver (aFileDriverPtr);
91 // Try to open the file
95 PCDM_ReadWriter::Open (*aFileDriver, theFileName, Storage_VSRead);
96 myReaderStatus = PCDM_RS_OK;
98 catch (Standard_Failure)
100 myReaderStatus = PCDM_RS_OpenError;
102 Standard_SStream aMsg;
103 aMsg << Standard_Failure::Caught() << endl;
104 Standard_Failure::Raise (aMsg);
107 // Read header section
108 if (!theHeaderData.Read (*aFileDriver))
109 raiseOnStorageError (theHeaderData.ErrorStatus());
112 Storage_TypeData aTypeData;
113 if (!aTypeData.Read (*aFileDriver))
114 raiseOnStorageError (aTypeData.ErrorStatus());
117 Storage_RootData aRootData;
118 if (!aRootData.Read (*aFileDriver))
119 raiseOnStorageError (aRootData.ErrorStatus());
121 if (aRootData.NumberOfRoots() < 1)
123 myReaderStatus = PCDM_RS_NoDocument;
125 Standard_SStream aMsg;
126 aMsg << "could not find any document in this file" << endl;
127 Standard_Failure::Raise (aMsg);
130 // Select instantiators for the used types
131 NCollection_Array1<StdObjMgt_Persistent::Instantiator>
132 anInstantiators (1, aTypeData.NumberOfTypes());
134 StdObjMgt_MapOfInstantiators aMapOfInstantiators;
135 bindTypes (aMapOfInstantiators);
137 TColStd_SequenceOfAsciiString anUnknownTypes;
138 Standard_Integer aCurTypeNum;
139 TCollection_AsciiString aCurTypeName;
141 for (i = 1; i <= aTypeData.NumberOfTypes(); i++)
143 aCurTypeName = aTypeData.Type (i);
144 aCurTypeNum = aTypeData.Type (aCurTypeName);
146 StdObjMgt_Persistent::Instantiator anInstantiator;
147 if (aMapOfInstantiators.Find (aCurTypeName, anInstantiator))
148 anInstantiators (aCurTypeNum) = anInstantiator;
150 anUnknownTypes.Append (aCurTypeName);
153 if (!anUnknownTypes.IsEmpty())
155 myReaderStatus = PCDM_RS_TypeNotFoundInSchema;
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++)
162 aMsg << anUnknownTypes(i);
163 if (i < anUnknownTypes.Length()) aMsg << ",";
167 Standard_Failure::Raise (aMsg);
171 // Read and parse reference section
172 StdObjMgt_ReadData aReadData (*aFileDriver, theHeaderData.NumberOfObjects());
174 raiseOnStorageError (aFileDriver->BeginReadRefSection());
176 Standard_Integer len = aFileDriver->RefSectionSize();
177 for (i = 1; i <= len; i++)
179 Standard_Integer aRef = 0, aType = 0;
180 Storage_Error anError;
184 aFileDriver->ReadReferenceType (aRef, aType);
185 anError = Storage_VSOk;
187 catch (Storage_StreamTypeMismatchError)
189 anError = Storage_VSTypeMismatch;
192 raiseOnStorageError (anError);
194 aReadData.CreatePersistentObject (aRef, anInstantiators (aType));
197 raiseOnStorageError (aFileDriver->EndReadRefSection());
199 // Read and parse data section
200 raiseOnStorageError (aFileDriver->BeginReadDataSection());
202 for (i = 1; i <= theHeaderData.NumberOfObjects(); i++)
204 Storage_Error anError;
208 aReadData.ReadPersistentObject (i);
209 anError = Storage_VSOk;
211 catch (Storage_StreamTypeMismatchError) { anError = Storage_VSTypeMismatch; }
212 catch (Storage_StreamFormatError ) { anError = Storage_VSFormatError; }
213 catch (Storage_StreamReadError ) { anError = Storage_VSFormatError; }
215 raiseOnStorageError (anError);
218 raiseOnStorageError (aFileDriver->EndReadDataSection());
220 // Get persistent document from the root object
221 return aReadData.PersistentObject (aRootData.Roots()->First()->Reference());
224 //=======================================================================
226 //purpose : not implemented
227 //=======================================================================
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*/)
234 Standard_NotImplemented::Raise ("Reading from stream is not supported by StdLDrivers_DocumentRetrievalDriver");
237 //=======================================================================
238 //function : raiseOnStorageError
239 //purpose : Update the reader status and raise an exception
240 // appropriate for the given storage error
241 //=======================================================================
242 void StdLDrivers_DocumentRetrievalDriver::raiseOnStorageError (Storage_Error theError)
244 Standard_SStream aMsg;
251 case Storage_VSOpenError:
252 case Storage_VSNotOpen:
253 case Storage_VSAlreadyOpen:
254 myReaderStatus = PCDM_RS_OpenError;
255 aMsg << "Stream Open Error" << endl;
256 Standard_Failure::Raise (aMsg);
258 case Storage_VSModeError:
259 myReaderStatus = PCDM_RS_WrongStreamMode;
260 aMsg << "Stream is opened with a wrong mode for operation" << endl;
261 Standard_Failure::Raise (aMsg);
263 case Storage_VSSectionNotFound:
264 myReaderStatus = PCDM_RS_FormatFailure;
265 aMsg << "Section is not found" << endl;
266 Standard_Failure::Raise (aMsg);
268 case Storage_VSFormatError:
269 myReaderStatus = PCDM_RS_FormatFailure;
270 aMsg << "Wrong format error" << endl;
271 Standard_Failure::Raise (aMsg);
273 case Storage_VSUnknownType:
274 myReaderStatus = PCDM_RS_TypeFailure;
275 aMsg << "Try to read an unknown type" << endl;
276 Standard_Failure::Raise (aMsg);
278 case Storage_VSTypeMismatch:
279 myReaderStatus = PCDM_RS_TypeFailure;
280 aMsg << "Try to read a wrong primitive type" << endl;
281 Standard_Failure::Raise (aMsg);
284 myReaderStatus = PCDM_RS_DriverFailure;
285 aMsg << "Retrieval Driver Failure" << endl;
286 Standard_Failure::Raise (aMsg);
290 //=======================================================================
291 //function : bindTypes
292 //purpose : Register types
293 //=======================================================================
294 void StdLDrivers_DocumentRetrievalDriver::bindTypes (StdObjMgt_MapOfInstantiators& theMap)
296 StdLDrivers::BindTypes (theMap);