0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[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
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 }
9775fa61 98 catch (Standard_Failure const& anException)
45d8465e 99 {
100 myReaderStatus = PCDM_RS_OpenError;
101
102 Standard_SStream aMsg;
9775fa61 103 aMsg << anException << endl;
104 throw Standard_Failure(aMsg.str().c_str());
45d8465e 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;
9775fa61 127 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 128 }
129
130 // Select instantiators for the used types
131 NCollection_Array1<StdObjMgt_Persistent::Instantiator>
ff205346 132 anInstantiators (1, aTypeData.NumberOfTypes());
7ed7467d 133 {
ec964372 134 StdObjMgt_MapOfInstantiators aMapOfInst;
135 bindTypes (aMapOfInst);
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;
ec964372 147 if (aMapOfInst.Find(aCurTypeName, anInstantiator))
7ed7467d 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
9775fa61 167 throw Standard_Failure(aMsg.str().c_str());
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
224//=======================================================================
201c2208 225//function : Read
226//purpose : not implemented
227//=======================================================================
228
229void 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{
9775fa61 234 throw Standard_NotImplemented("Reading from stream is not supported by StdLDrivers_DocumentRetrievalDriver");
201c2208 235}
236
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 242void 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;
9775fa61 256 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 257
258 case Storage_VSModeError:
259 myReaderStatus = PCDM_RS_WrongStreamMode;
260 aMsg << "Stream is opened with a wrong mode for operation" << endl;
9775fa61 261 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 262
263 case Storage_VSSectionNotFound:
264 myReaderStatus = PCDM_RS_FormatFailure;
265 aMsg << "Section is not found" << endl;
9775fa61 266 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 267
268 case Storage_VSFormatError:
269 myReaderStatus = PCDM_RS_FormatFailure;
270 aMsg << "Wrong format error" << endl;
9775fa61 271 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 272
273 case Storage_VSUnknownType:
274 myReaderStatus = PCDM_RS_TypeFailure;
275 aMsg << "Try to read an unknown type" << endl;
9775fa61 276 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 277
278 case Storage_VSTypeMismatch:
279 myReaderStatus = PCDM_RS_TypeFailure;
280 aMsg << "Try to read a wrong primitive type" << endl;
9775fa61 281 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 282
283 default:
284 myReaderStatus = PCDM_RS_DriverFailure;
285 aMsg << "Retrieval Driver Failure" << endl;
9775fa61 286 throw Standard_Failure(aMsg.str().c_str());
7ed7467d 287 }
7ed7467d 288}
289
290//=======================================================================
ff205346 291//function : bindTypes
7ed7467d 292//purpose : Register types
293//=======================================================================
ff205346 294void StdLDrivers_DocumentRetrievalDriver::bindTypes (StdObjMgt_MapOfInstantiators& theMap)
7ed7467d 295{
296 StdLDrivers::BindTypes (theMap);
297}