0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / StdLDrivers / StdLDrivers_DocumentRetrievalDriver.cxx
CommitLineData
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
38IMPLEMENT_STANDARD_RTTIEXT (StdLDrivers_DocumentRetrievalDriver, PCDM_RetrievalDriver)
39
40//=======================================================================
41//function : CreateDocument
42//purpose : Create an empty TDocStd_Document
43//=======================================================================
44Handle(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 53void StdLDrivers_DocumentRetrievalDriver::Read (const TCollection_ExtendedString& theFileName,
7ed7467d 54 const Handle(CDM_Document)& theNewDocument,
55 const Handle(CDM_Application)&)
56{
ff205346 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//=======================================================================
75Handle(StdObjMgt_Persistent) StdLDrivers_DocumentRetrievalDriver::read (
76 const TCollection_ExtendedString& theFileName,
77 Storage_HeaderData& theHeaderData)
78{
7ed7467d 79 Standard_Integer i;
80
81 // Create a driver appropriate for the given file
39c8dc70 82 Handle(Storage_BaseDriver) aFileDriver;
83 if (PCDM::FileDriverType (TCollection_AsciiString (theFileName), aFileDriver) == PCDM_TOFD_Unknown)
7ed7467d 84 {
85 myReaderStatus = PCDM_RS_UnknownFileDriver;
ff205346 86 return NULL;
7ed7467d 87 }
88
89 // Try to open the file
45d8465e 90 try
91 {
92 OCC_CATCH_SIGNALS
39c8dc70 93 PCDM_ReadWriter::Open (aFileDriver, theFileName, Storage_VSRead);
45d8465e 94 myReaderStatus = PCDM_RS_OK;
95 }
9775fa61 96 catch (Standard_Failure const& anException)
45d8465e 97 {
98 myReaderStatus = PCDM_RS_OpenError;
99
100 Standard_SStream aMsg;
04232180 101 aMsg << anException << std::endl;
9775fa61 102 throw Standard_Failure(aMsg.str().c_str());
45d8465e 103 }
7ed7467d 104
105 // Read header section
39c8dc70 106 if (!theHeaderData.Read (aFileDriver))
ff205346 107 raiseOnStorageError (theHeaderData.ErrorStatus());
7ed7467d 108
109 // Read type section
ff205346 110 Storage_TypeData aTypeData;
39c8dc70 111 if (!aTypeData.Read (aFileDriver))
ff205346 112 raiseOnStorageError (aTypeData.ErrorStatus());
7ed7467d 113
114 // Read root section
ff205346 115 Storage_RootData aRootData;
39c8dc70 116 if (!aRootData.Read (aFileDriver))
ff205346 117 raiseOnStorageError (aRootData.ErrorStatus());
7ed7467d 118
ff205346 119 if (aRootData.NumberOfRoots() < 1)
7ed7467d 120 {
121 myReaderStatus = PCDM_RS_NoDocument;
122
123 Standard_SStream aMsg;
04232180 124 aMsg << "could not find any document in this file" << std::endl;
9775fa61 125 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 126 }
127
128 // Select instantiators for the used types
129 NCollection_Array1<StdObjMgt_Persistent::Instantiator>
ff205346 130 anInstantiators (1, aTypeData.NumberOfTypes());
7ed7467d 131 {
ec964372 132 StdObjMgt_MapOfInstantiators aMapOfInst;
133 bindTypes (aMapOfInst);
7ed7467d 134
135 TColStd_SequenceOfAsciiString anUnknownTypes;
136 Standard_Integer aCurTypeNum;
137 TCollection_AsciiString aCurTypeName;
138
ff205346 139 for (i = 1; i <= aTypeData.NumberOfTypes(); i++)
7ed7467d 140 {
ff205346 141 aCurTypeName = aTypeData.Type (i);
142 aCurTypeNum = aTypeData.Type (aCurTypeName);
7ed7467d 143
144 StdObjMgt_Persistent::Instantiator anInstantiator;
ec964372 145 if (aMapOfInst.Find(aCurTypeName, anInstantiator))
7ed7467d 146 anInstantiators (aCurTypeNum) = anInstantiator;
147 else
148 anUnknownTypes.Append (aCurTypeName);
149 }
150
151 if (!anUnknownTypes.IsEmpty())
152 {
153 myReaderStatus = PCDM_RS_TypeNotFoundInSchema;
154
155 Standard_SStream aMsg;
156 aMsg << "cannot read: `" << theFileName
157 << "' because it contains the following unknown types: ";
158 for (i = 1; i <= anUnknownTypes.Length(); i++)
159 {
160 aMsg << anUnknownTypes(i);
161 if (i < anUnknownTypes.Length()) aMsg << ",";
04232180 162 else aMsg << std::endl;
7ed7467d 163 }
164
9775fa61 165 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 166 }
167 }
168
169 // Read and parse reference section
39c8dc70 170 StdObjMgt_ReadData aReadData (aFileDriver, theHeaderData.NumberOfObjects());
7ed7467d 171
ff205346 172 raiseOnStorageError (aFileDriver->BeginReadRefSection());
7ed7467d 173
174 Standard_Integer len = aFileDriver->RefSectionSize();
175 for (i = 1; i <= len; i++)
176 {
177 Standard_Integer aRef = 0, aType = 0;
178 Storage_Error anError;
179 try
180 {
181 OCC_CATCH_SIGNALS
182 aFileDriver->ReadReferenceType (aRef, aType);
183 anError = Storage_VSOk;
184 }
a738b534 185 catch (Storage_StreamTypeMismatchError const&)
7ed7467d 186 {
187 anError = Storage_VSTypeMismatch;
188 }
189
ff205346 190 raiseOnStorageError (anError);
7ed7467d 191
ff205346 192 aReadData.CreatePersistentObject (aRef, anInstantiators (aType));
7ed7467d 193 }
194
ff205346 195 raiseOnStorageError (aFileDriver->EndReadRefSection());
7ed7467d 196
197 // Read and parse data section
ff205346 198 raiseOnStorageError (aFileDriver->BeginReadDataSection());
7ed7467d 199
ff205346 200 for (i = 1; i <= theHeaderData.NumberOfObjects(); i++)
7ed7467d 201 {
ff205346 202 Storage_Error anError;
203 try
7ed7467d 204 {
ff205346 205 OCC_CATCH_SIGNALS
206 aReadData.ReadPersistentObject (i);
207 anError = Storage_VSOk;
7ed7467d 208 }
a738b534 209 catch (Storage_StreamTypeMismatchError const&) { anError = Storage_VSTypeMismatch; }
210 catch (Storage_StreamFormatError const& ) { anError = Storage_VSFormatError; }
211 catch (Storage_StreamReadError const& ) { anError = Storage_VSFormatError; }
7ed7467d 212
ff205346 213 raiseOnStorageError (anError);
214 }
7ed7467d 215
ff205346 216 raiseOnStorageError (aFileDriver->EndReadDataSection());
7ed7467d 217
ff205346 218 // Get persistent document from the root object
219 return aReadData.PersistentObject (aRootData.Roots()->First()->Reference());
7ed7467d 220}
221
222//=======================================================================
201c2208 223//function : Read
224//purpose : not implemented
225//=======================================================================
226
227void StdLDrivers_DocumentRetrievalDriver::Read (Standard_IStream& /*theIStream*/,
228 const Handle(Storage_Data)& /*theStorageData*/,
229 const Handle(CDM_Document)& /*theDoc*/,
230 const Handle(CDM_Application)& /*theApplication*/)
231{
9775fa61 232 throw Standard_NotImplemented("Reading from stream is not supported by StdLDrivers_DocumentRetrievalDriver");
201c2208 233}
234
235//=======================================================================
ff205346 236//function : raiseOnStorageError
7ed7467d 237//purpose : Update the reader status and raise an exception
238// appropriate for the given storage error
239//=======================================================================
ff205346 240void StdLDrivers_DocumentRetrievalDriver::raiseOnStorageError (Storage_Error theError)
7ed7467d 241{
242 Standard_SStream aMsg;
243
244 switch (theError)
245 {
246 case Storage_VSOk:
ff205346 247 break;
7ed7467d 248
249 case Storage_VSOpenError:
250 case Storage_VSNotOpen:
251 case Storage_VSAlreadyOpen:
252 myReaderStatus = PCDM_RS_OpenError;
04232180 253 aMsg << "Stream Open Error" << std::endl;
9775fa61 254 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 255
256 case Storage_VSModeError:
257 myReaderStatus = PCDM_RS_WrongStreamMode;
04232180 258 aMsg << "Stream is opened with a wrong mode for operation" << std::endl;
9775fa61 259 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 260
261 case Storage_VSSectionNotFound:
262 myReaderStatus = PCDM_RS_FormatFailure;
04232180 263 aMsg << "Section is not found" << std::endl;
9775fa61 264 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 265
266 case Storage_VSFormatError:
267 myReaderStatus = PCDM_RS_FormatFailure;
04232180 268 aMsg << "Wrong format error" << std::endl;
9775fa61 269 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 270
271 case Storage_VSUnknownType:
272 myReaderStatus = PCDM_RS_TypeFailure;
04232180 273 aMsg << "Try to read an unknown type" << std::endl;
9775fa61 274 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 275
276 case Storage_VSTypeMismatch:
277 myReaderStatus = PCDM_RS_TypeFailure;
04232180 278 aMsg << "Try to read a wrong primitive type" << std::endl;
9775fa61 279 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 280
281 default:
282 myReaderStatus = PCDM_RS_DriverFailure;
04232180 283 aMsg << "Retrieval Driver Failure" << std::endl;
9775fa61 284 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 285 }
7ed7467d 286}
287
288//=======================================================================
ff205346 289//function : bindTypes
7ed7467d 290//purpose : Register types
291//=======================================================================
ff205346 292void StdLDrivers_DocumentRetrievalDriver::bindTypes (StdObjMgt_MapOfInstantiators& theMap)
7ed7467d 293{
294 StdLDrivers::BindTypes (theMap);
295}