1 // Copyright (c) 2022 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 <DE_Wrapper.hxx>
16 #include <DE_ConfigurationContext.hxx>
17 #include <DE_ConfigurationNode.hxx>
18 #include <DE_Provider.hxx>
19 #include <Message_ProgressRange.hxx>
20 #include <NCollection_Buffer.hxx>
21 #include <OSD_File.hxx>
22 #include <OSD_Path.hxx>
23 #include <OSD_FileSystem.hxx>
24 #include <OSD_Protection.hxx>
25 #include <Standard_ErrorHandler.hxx>
26 #include <TopoDS_Shape.hxx>
28 IMPLEMENT_STANDARD_RTTIEXT(DE_Wrapper, Standard_Transient)
32 static const TCollection_AsciiString& THE_CONFIGURATION_SCOPE()
34 static const TCollection_AsciiString aScope ("global");
39 //=======================================================================
40 // function : DE_Wrapper
42 //=======================================================================
43 DE_Wrapper::DE_Wrapper()
46 //=======================================================================
47 // function : DE_Wrapper
49 //=======================================================================
50 DE_Wrapper::DE_Wrapper(const Handle(DE_Wrapper)& theWrapper)
53 if (theWrapper.IsNull())
57 GlobalParameters = theWrapper->GlobalParameters;
58 for (DE_ConfigurationFormatMap::Iterator aFormatIter(theWrapper->Nodes());
59 aFormatIter.More(); aFormatIter.Next())
61 for (DE_ConfigurationVendorMap::Iterator aVendorIter(aFormatIter.Value());
62 aVendorIter.More(); aVendorIter.Next())
64 Bind(aVendorIter.Value());
69 //=======================================================================
70 // function : GlobalWrapper
72 //=======================================================================
73 Handle(DE_Wrapper) DE_Wrapper::GlobalWrapper()
75 static const Handle(DE_Wrapper)& aConfiguration = new DE_Wrapper();
76 return aConfiguration;
79 //=======================================================================
82 //=======================================================================
83 Standard_Boolean DE_Wrapper::Read(const TCollection_AsciiString& thePath,
84 const Handle(TDocStd_Document)& theDocument,
85 Handle(XSControl_WorkSession)& theWS,
86 const Message_ProgressRange& theProgress)
88 if (theDocument.IsNull())
90 return Standard_False;
94 return Read(thePath, theDocument, theProgress);
96 Handle(DE_Provider) aProvider;
97 if (!FindProvider(thePath, Standard_True, aProvider))
99 return Standard_False;
101 return aProvider->Read(thePath, theDocument, theWS, theProgress);
104 //=======================================================================
107 //=======================================================================
108 Standard_Boolean DE_Wrapper::Write(const TCollection_AsciiString& thePath,
109 const Handle(TDocStd_Document)& theDocument,
110 Handle(XSControl_WorkSession)& theWS,
111 const Message_ProgressRange& theProgress)
113 if (theDocument.IsNull())
115 return Standard_False;
119 return Write(thePath, theDocument, theProgress);
121 Handle(DE_Provider) aProvider;
122 if (!FindProvider(thePath, Standard_False, aProvider))
124 return Standard_False;
126 return aProvider->Write(thePath, theDocument, theWS, theProgress);
129 //=======================================================================
132 //=======================================================================
133 Standard_Boolean DE_Wrapper::Read(const TCollection_AsciiString& thePath,
134 const Handle(TDocStd_Document)& theDocument,
135 const Message_ProgressRange& theProgress)
137 if (theDocument.IsNull())
139 return Standard_False;
141 Handle(DE_Provider) aProvider;
142 if (!FindProvider(thePath, Standard_True, aProvider))
144 return Standard_False;
146 return aProvider->Read(thePath, theDocument, theProgress);
149 //=======================================================================
152 //=======================================================================
153 Standard_Boolean DE_Wrapper::Write(const TCollection_AsciiString& thePath,
154 const Handle(TDocStd_Document)& theDocument,
155 const Message_ProgressRange& theProgress)
157 if (theDocument.IsNull())
159 return Standard_False;
161 Handle(DE_Provider) aProvider;
162 if (!FindProvider(thePath, Standard_False, aProvider))
164 return Standard_False;
166 return aProvider->Write(thePath, theDocument, theProgress);
169 //=======================================================================
172 //=======================================================================
173 Standard_Boolean DE_Wrapper::Read(const TCollection_AsciiString& thePath,
174 TopoDS_Shape& theShape,
175 Handle(XSControl_WorkSession)& theWS,
176 const Message_ProgressRange& theProgress)
180 return Read(thePath, theShape, theProgress);
182 Handle(DE_Provider) aProvider;
183 if (!FindProvider(thePath, Standard_True, aProvider))
185 return Standard_False;
187 return aProvider->Read(thePath, theShape, theWS, theProgress);
190 //=======================================================================
193 //=======================================================================
194 Standard_Boolean DE_Wrapper::Write(const TCollection_AsciiString& thePath,
195 const TopoDS_Shape& theShape,
196 Handle(XSControl_WorkSession)& theWS,
197 const Message_ProgressRange& theProgress)
201 return Write(thePath, theShape, theProgress);
203 Handle(DE_Provider) aProvider;
204 if (!FindProvider(thePath, Standard_False, aProvider))
206 return Standard_False;
208 return aProvider->Write(thePath, theShape, theWS, theProgress);
211 //=======================================================================
214 //=======================================================================
215 Standard_Boolean DE_Wrapper::Read(const TCollection_AsciiString& thePath,
216 TopoDS_Shape& theShape,
217 const Message_ProgressRange& theProgress)
220 Handle(DE_Provider) aProvider;
221 if (!FindProvider(thePath, Standard_True, aProvider))
223 return Standard_False;
225 return aProvider->Read(thePath, theShape, theProgress);
228 //=======================================================================
231 //=======================================================================
232 Standard_Boolean DE_Wrapper::Write(const TCollection_AsciiString& thePath,
233 const TopoDS_Shape& theShape,
234 const Message_ProgressRange& theProgress)
236 Handle(DE_Provider) aProvider;
237 if (!FindProvider(thePath, Standard_False, aProvider))
239 return Standard_False;
241 return aProvider->Write(thePath, theShape, theProgress);
244 //=======================================================================
247 //=======================================================================
248 Standard_Boolean DE_Wrapper::Load(const TCollection_AsciiString& theResource,
249 const Standard_Boolean theIsRecursive)
251 Handle(DE_ConfigurationContext) aResource = new DE_ConfigurationContext();
252 aResource->Load(theResource);
253 return Load(aResource, theIsRecursive);
256 //=======================================================================
259 //=======================================================================
260 Standard_Boolean DE_Wrapper::Load(const Handle(DE_ConfigurationContext)& theResource,
261 const Standard_Boolean theIsRecursive)
263 GlobalParameters.LengthUnit = theResource->RealVal("general.length.unit", GlobalParameters.LengthUnit, THE_CONFIGURATION_SCOPE());
266 for (DE_ConfigurationFormatMap::Iterator aFormatIter(myConfiguration);
267 aFormatIter.More(); aFormatIter.Next())
269 for (DE_ConfigurationVendorMap::Iterator aVendorIter(aFormatIter.Value());
270 aVendorIter.More(); aVendorIter.Next())
272 aVendorIter.Value()->Load(theResource);
277 return Standard_True;
280 //=======================================================================
283 //=======================================================================
284 Standard_Boolean DE_Wrapper::Save(const TCollection_AsciiString& theResourcePath,
285 const Standard_Boolean theIsRecursive,
286 const TColStd_ListOfAsciiString& theFormats,
287 const TColStd_ListOfAsciiString& theVendors)
289 OSD_Path aPath = theResourcePath;
290 OSD_File aFile(aPath);
291 OSD_Protection aProt;
296 aFile.Build(OSD_ReadWrite, aProt);
298 catch (Standard_Failure const&)
300 return Standard_False;
305 return Standard_False;
307 TCollection_AsciiString aResConfiguration = Save(theIsRecursive, theFormats, theVendors);
308 aFile.Write(aResConfiguration, aResConfiguration.Length());
310 return Standard_True;
313 //=======================================================================
316 //=======================================================================
317 TCollection_AsciiString DE_Wrapper::Save(const Standard_Boolean theIsRecursive,
318 const TColStd_ListOfAsciiString& theFormats,
319 const TColStd_ListOfAsciiString& theVendors)
321 TCollection_AsciiString aResult;
322 aResult += "!Description of the config file for DE toolkit\n";
323 aResult += "!*****************************************************************************\n";
325 aResult += "!Format of the file is compliant with the standard Open CASCADE resource files\n";
326 aResult += "!Each key defines a sequence of either further keys.\n";
327 aResult += "!Keys can be nested down to an arbitrary level.\n";
329 aResult += "!*****************************************************************************\n";
330 aResult += "!DE_Wrapper\n";
331 aResult += "!Priority vendor list. For every CAD format set indexed list of vendors\n";
332 for (DE_ConfigurationFormatMap::Iterator aFormatIter(myConfiguration);
333 aFormatIter.More(); aFormatIter.Next())
335 const TCollection_AsciiString& aFormat = aFormatIter.Key();
336 aResult += THE_CONFIGURATION_SCOPE() + '.' + "priority" + '.' + aFormat + " :\t ";
337 for (DE_ConfigurationVendorMap::Iterator aVendorIter(aFormatIter.Value());
338 aVendorIter.More(); aVendorIter.Next())
340 const TCollection_AsciiString& aVendorName = aVendorIter.Value()->GetVendor();
341 aResult += aVendorName + " ";
345 aResult += "!Global parameters. Used for all providers\n";
346 aResult += "!Length scale unit value. Should be more the 0. Default value: 1.0(MM)\n";
347 aResult += THE_CONFIGURATION_SCOPE() + ".general.length.unit :\t " + GlobalParameters.LengthUnit + "\n";
350 for (DE_ConfigurationFormatMap::Iterator aFormatIter(myConfiguration);
351 aFormatIter.More(); aFormatIter.Next())
353 if (!theFormats.IsEmpty() && !theFormats.Contains(aFormatIter.Key()))
357 for (DE_ConfigurationVendorMap::Iterator aVendorIter(aFormatIter.Value());
358 aVendorIter.More(); aVendorIter.Next())
360 if (!theVendors.IsEmpty() && !theVendors.Contains(aVendorIter.Key()))
365 aResult += aVendorIter.Value()->Save();
370 aResult += "!*****************************************************************************\n";
374 //=======================================================================
377 //=======================================================================
378 Standard_Boolean DE_Wrapper::Bind(const Handle(DE_ConfigurationNode)& theNode)
380 if (theNode.IsNull())
382 return Standard_False;
384 const TCollection_AsciiString aFileFormat = theNode->GetFormat();
385 const TCollection_AsciiString aVendorName = theNode->GetVendor();
386 DE_ConfigurationVendorMap* aVendorMap = myConfiguration.ChangeSeek(aFileFormat);
387 if (aVendorMap == NULL)
389 DE_ConfigurationVendorMap aTmpVendorMap;
390 aVendorMap = myConfiguration.Bound(aFileFormat, aTmpVendorMap);
392 return aVendorMap->Add(aVendorName, theNode) > 0;
395 //=======================================================================
398 //=======================================================================
399 Standard_Boolean DE_Wrapper::Find(const TCollection_AsciiString& theFormat,
400 const TCollection_AsciiString& theVendor,
401 Handle(DE_ConfigurationNode)& theNode) const
403 const DE_ConfigurationVendorMap* aVendorMap = myConfiguration.Seek(theFormat);
404 return aVendorMap != nullptr && aVendorMap->FindFromKey(theVendor, theNode);
407 //=======================================================================
408 // function : ChangePriority
410 //=======================================================================
411 void DE_Wrapper::ChangePriority(const TCollection_AsciiString& theFormat,
412 const TColStd_ListOfAsciiString& theVendorPriority,
413 const Standard_Boolean theToDisable)
415 DE_ConfigurationVendorMap aVendorMap;
416 if (!myConfiguration.Find(theFormat, aVendorMap))
420 DE_ConfigurationVendorMap aNewVendorMap;
421 // Sets according to the input priority
422 for (TColStd_ListOfAsciiString::Iterator aPriorIter(theVendorPriority);
423 aPriorIter.More(); aPriorIter.Next())
425 const TCollection_AsciiString& aVendorName = aPriorIter.Value();
426 Handle(DE_ConfigurationNode) aNode;
427 if (aVendorMap.FindFromKey(aVendorName, aNode))
429 aNode->SetEnabled(Standard_True);
431 aNewVendorMap.Add(aVendorName, aNode);
434 // Sets not used elements
435 for (DE_ConfigurationVendorMap::Iterator aVendorIter(aVendorMap);
436 aVendorIter.More(); aVendorIter.Next())
438 const TCollection_AsciiString& aVendorName = aVendorIter.Key();
439 if (!theVendorPriority.Contains(aVendorName))
441 Handle(DE_ConfigurationNode) aNode = aVendorIter.Value();
444 aNode->SetEnabled(Standard_False);
446 aNewVendorMap.Add(aVendorName, aNode);
449 myConfiguration.Bind(theFormat, aNewVendorMap);
452 //=======================================================================
453 // function : ChangePriority
455 //=======================================================================
456 void DE_Wrapper::ChangePriority(const TColStd_ListOfAsciiString& theVendorPriority,
457 const Standard_Boolean theToDisable)
459 for (DE_ConfigurationFormatMap::Iterator aFormatIter(myConfiguration);
460 aFormatIter.More(); aFormatIter.Next())
462 ChangePriority(aFormatIter.Key(), theVendorPriority, theToDisable);
466 //=======================================================================
469 //=======================================================================
470 const DE_ConfigurationFormatMap& DE_Wrapper::Nodes() const
472 return myConfiguration;
475 //=======================================================================
478 //=======================================================================
479 Handle(DE_Wrapper) DE_Wrapper::Copy() const
481 return new DE_Wrapper(*this);
484 //=======================================================================
485 // function : FindProvider
487 //=======================================================================
488 Standard_Boolean DE_Wrapper::FindProvider(const TCollection_AsciiString& thePath,
489 const Standard_Boolean theToImport,
490 Handle(DE_Provider)& theProvider) const
492 Handle(NCollection_Buffer) aBuffer;
495 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
496 std::shared_ptr<std::istream> aStream = aFileSystem->OpenIStream(thePath, std::ios::in | std::ios::binary);
497 if (aStream.get() != nullptr)
499 aBuffer = new NCollection_Buffer(NCollection_BaseAllocator::CommonBaseAllocator(), 2048);
500 aStream->read((char*)aBuffer->ChangeData(), 2048);
501 aBuffer->ChangeData()[2047] = '\0';
504 OSD_Path aPath(thePath);
505 const TCollection_AsciiString anExtr = aPath.Extension();
506 for (DE_ConfigurationFormatMap::Iterator aFormatIter(myConfiguration);
507 aFormatIter.More(); aFormatIter.Next())
509 for (DE_ConfigurationVendorMap::Iterator aVendorIter(aFormatIter.Value());
510 aVendorIter.More(); aVendorIter.Next())
512 const Handle(DE_ConfigurationNode)& aNode = aVendorIter.Value();
513 if (aNode->IsEnabled() &&
514 ((theToImport && aNode->IsImportSupported()) ||
515 (!theToImport && aNode->IsExportSupported())) &&
516 (aNode->CheckExtension(anExtr) ||
517 (theToImport && aNode->CheckContent(aBuffer))))
519 theProvider = aNode->BuildProvider();
520 aNode->GlobalParameters = GlobalParameters;
521 theProvider->SetNode(aNode);
522 return Standard_True;
526 return Standard_False;
529 //=======================================================================
532 //=======================================================================
533 void DE_Wrapper::sort(const Handle(DE_ConfigurationContext)& theResource)
535 const TCollection_AsciiString aScope(THE_CONFIGURATION_SCOPE() + '.' + "priority");
536 NCollection_List<Handle(DE_ConfigurationNode)> aVendors;
537 for (DE_ConfigurationFormatMap::Iterator aFormatIter(myConfiguration);
538 aFormatIter.More(); aFormatIter.Next())
540 TColStd_ListOfAsciiString aVendorPriority;
541 if (!theResource->GetStringSeq(aFormatIter.Key(), aVendorPriority, aScope))
545 ChangePriority(aFormatIter.Key(), aVendorPriority, Standard_True);