0025748: Parallel version of progress indicator
[occt.git] / src / BinLDrivers / BinLDrivers_DocumentRetrievalDriver.cxx
CommitLineData
b311480e 1// Created on: 2002-10-31
2// Created by: Michael SAZONOV
973c2be1 3// Copyright (c) 2002-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
42cf5bc1 16
7fd59977 17#include <BinLDrivers.hxx>
42cf5bc1 18#include <BinLDrivers_DocumentRetrievalDriver.hxx>
19#include <BinLDrivers_DocumentSection.hxx>
7fd59977 20#include <BinLDrivers_Marker.hxx>
7fd59977 21#include <BinMDataStd.hxx>
42cf5bc1 22#include <BinMDF_ADriver.hxx>
23#include <BinMDF_ADriverTable.hxx>
7fd59977 24#include <BinObjMgt_Persistent.hxx>
42cf5bc1 25#include <CDM_Application.hxx>
26#include <CDM_Document.hxx>
83ae3591 27#include <Message_Messenger.hxx>
7fd59977 28#include <FSD_BinaryFile.hxx>
29#include <FSD_FileHeader.hxx>
4ff92abe 30#include <OSD_OpenFile.hxx>
42cf5bc1 31#include <PCDM_Document.hxx>
4ff92abe 32#include <PCDM_ReadWriter.hxx>
7fd59977 33#include <Standard_ErrorHandler.hxx>
34#include <Standard_Stream.hxx>
42cf5bc1 35#include <Standard_Type.hxx>
36#include <Storage_HeaderData.hxx>
7fd59977 37#include <Storage_Schema.hxx>
42cf5bc1 38#include <TCollection_AsciiString.hxx>
39#include <TCollection_ExtendedString.hxx>
40#include <TDF_Attribute.hxx>
7fd59977 41#include <TDF_Data.hxx>
42cf5bc1 42#include <TDF_Label.hxx>
7fd59977 43#include <TDocStd_Document.hxx>
44#include <TDocStd_Owner.hxx>
7e785937 45#include <Message_ProgressScope.hxx>
6d8f9f4a 46
7fd59977 47
92efcf78 48IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver)
49
7fd59977 50#define SHAPESECTION_POS "SHAPE_SECTION_POS:"
51#define SIZEOFSHAPELABEL 18
52
53#define DATATYPE_MIGRATION
54//#define DATATYPE_MIGRATION_DEB
55//=======================================================================
56//function : BinLDrivers_DocumentRetrievalDriver
57//purpose : Constructor
58//=======================================================================
59
60BinLDrivers_DocumentRetrievalDriver::BinLDrivers_DocumentRetrievalDriver ()
61{
62 myReaderStatus = PCDM_RS_OK;
63}
64
65//=======================================================================
66//function : CreateDocument
67//purpose : pure virtual method definition
68//=======================================================================
69
70Handle(CDM_Document) BinLDrivers_DocumentRetrievalDriver::CreateDocument()
71{
72 return new TDocStd_Document(PCDM_RetrievalDriver::GetFormat());
73}
74
7fd59977 75//=======================================================================
76//function : Read
77//purpose :
78//=======================================================================
7fd59977 79void BinLDrivers_DocumentRetrievalDriver::Read
80 (const TCollection_ExtendedString& theFileName,
81 const Handle(CDM_Document)& theNewDocument,
6d8f9f4a 82 const Handle(CDM_Application)& theApplication,
7e785937 83 const Message_ProgressRange& theRange)
4ff92abe 84{
85 std::ifstream aFileStream;
86 OSD_OpenStream (aFileStream, theFileName, std::ios::in | std::ios::binary);
87
88 if (aFileStream.is_open() && aFileStream.good())
89 {
90 Handle(Storage_Data) dData;
91 TCollection_ExtendedString aFormat = PCDM_ReadWriter::FileFormat (aFileStream, dData);
92
7e785937 93 Read(aFileStream, dData, theNewDocument, theApplication, theRange);
94 if (!theRange.More())
6d8f9f4a 95 {
96 myReaderStatus = PCDM_RS_UserBreak;
97 return;
98 }
4ff92abe 99 }
100 else
101 {
102 myReaderStatus = PCDM_RS_OpenError;
103 }
104}
105
106#define MODIFICATION_COUNTER "MODIFICATION_COUNTER: "
107#define REFERENCE_COUNTER "REFERENCE_COUNTER: "
108
109#define START_TYPES "START_TYPES"
110#define END_TYPES "END_TYPES"
111
112//=======================================================================
113//function : Read
114//purpose :
115//=======================================================================
116void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream& theIStream,
117 const Handle(Storage_Data)& theStorageData,
118 const Handle(CDM_Document)& theDoc,
6d8f9f4a 119 const Handle(CDM_Application)& theApplication,
7e785937 120 const Message_ProgressRange& theRange)
7fd59977 121{
122 myReaderStatus = PCDM_RS_DriverFailure;
123 myMsgDriver = theApplication -> MessageDriver();
124
125 const TCollection_ExtendedString aMethStr
126 ("BinLDrivers_DocumentRetrievalDriver: ");
127
128 Handle(TDocStd_Document) aDoc =
4ff92abe 129 Handle(TDocStd_Document)::DownCast(theDoc);
7fd59977 130 if (aDoc.IsNull()) {
0797d9d3 131#ifdef OCCT_DEBUG
83ae3591 132 myMsgDriver->Send (aMethStr + "error: null document", Message_Fail);
7fd59977 133#endif
134 myReaderStatus = PCDM_RS_NoDocument;
135 return;
136 }
137
4ff92abe 138 // 1. the information section
7fd59977 139 Handle(Storage_HeaderData) aHeaderData;
4ff92abe 140
141 if (!theStorageData.IsNull())
142 {
143 aHeaderData = theStorageData->HeaderData();
144 }
145
146 if (!aHeaderData.IsNull())
147 {
148 for (Standard_Integer i = 1; i <= aHeaderData->UserInfo().Length(); i++)
149 {
150 const TCollection_AsciiString& aLine = aHeaderData->UserInfo().Value(i);
151
152 if(aLine.Search(REFERENCE_COUNTER) != -1)
153 {
154 theDoc->SetReferenceCounter (aLine.Token(" ", 2).IntegerValue());
155 }
156 else if(aLine.Search(MODIFICATION_COUNTER) != -1)
157 {
158 theDoc->SetModifications (aLine.Token(" ", 2).IntegerValue());
159 }
160 }
7fd59977 161 }
162
163 // 1.a Version of writer
164 if (!aHeaderData->StorageVersion().IsIntegerValue()) {
165 // file has no format version
83ae3591 166 myMsgDriver->Send (aMethStr + "error: file has no format version", Message_Fail);
7fd59977 167 myReaderStatus = PCDM_RS_FormatFailure;
168 return;
169 }
170 Standard_Integer aFileVer = aHeaderData->StorageVersion().IntegerValue();
171 Standard_Integer aCurrVer = BinLDrivers::StorageVersion().IntegerValue();
172 // maintain one-way compatibility starting from version 2+
d9ff84e8 173 if (!CheckDocumentVersion(aFileVer, aCurrVer)) {
174 myReaderStatus = PCDM_RS_NoVersion;
7fd59977 175 // file was written with another version
83ae3591 176 myMsgDriver->Send (aMethStr + "error: wrong file version: " +
177 aHeaderData->StorageVersion() + " while current is " +
178 BinLDrivers::StorageVersion(), Message_Fail);
7fd59977 179 return;
180 }
181
182 // 1.b Retrieve the Types table
183 TColStd_SequenceOfAsciiString aTypeNames; //Sequence of types in file
184 const TColStd_SequenceOfAsciiString& aUserInfo = aHeaderData->UserInfo();
185 Standard_Boolean begin = Standard_False;
186 Standard_Integer i;
187 for (i=1; i <= aUserInfo.Length(); i++) {
188 //const TCollection_AsciiString& aStr = aUserInfo(i);
189 TCollection_AsciiString aStr = aUserInfo(i);
190 if (aStr == START_TYPES)
191 begin = Standard_True;
192 else if (aStr == END_TYPES)
193 break;
194 else if (begin) {
f47afe53 195 if ( aFileVer < 8 ) {
7fd59977 196#ifdef DATATYPE_MIGRATION
83ae3591 197 TCollection_AsciiString newName;
198 if(Storage_Schema::CheckTypeMigration(aStr, newName)) {
0797d9d3 199#ifdef OCCT_DEBUG
04232180 200 std::cout << "CheckTypeMigration:OldType = " <<aStr << " Len = "<<aStr.Length()<<std::endl;
201 std::cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<std::endl;
7fd59977 202#endif
83ae3591 203 aStr = newName;
204 }
7fd59977 205#endif
206 }
207 aTypeNames.Append (aStr);
208 }
209 }
210 if (myDrivers.IsNull())
211 myDrivers = AttributeDrivers (myMsgDriver);
212 myDrivers->AssignIds (aTypeNames);
213
214 // recognize types not supported by drivers
215 myMapUnsupported.Clear();
216 for (i=1; i <= aTypeNames.Length(); i++)
217 if (myDrivers->GetDriver(i).IsNull())
218 myMapUnsupported.Add(i);
219 if (!myMapUnsupported.IsEmpty()) {
83ae3591 220 myMsgDriver->Send (aMethStr + "warning: "
221 "the following attributes have no driver:", Message_Warning);
7fd59977 222 for (i=1; i <= aTypeNames.Length(); i++)
223 if (myMapUnsupported.Contains(i))
83ae3591 224 myMsgDriver->Send (aTypeNames(i), Message_Warning);
7fd59977 225 }
226
7fd59977 227 // 2. Read document contents
7fd59977 228 // 2a. Retrieve data from the stream:
229 myRelocTable.Clear();
fe21f796 230 myRelocTable.SetHeaderData(aHeaderData);
7fd59977 231 mySections.Clear();
232 myPAtt.Init();
233 Handle(TDF_Data) aData = new TDF_Data();
04232180 234 std::streampos aDocumentPos = -1;
7fd59977 235
7e785937 236 Message_ProgressScope aPS(theRange, "Reading data", 3);
6d8f9f4a 237
7fd59977 238 // 2b. Read the TOC of Sections
239 if (aFileVer >= 3) {
240 BinLDrivers_DocumentSection aSection;
241 do {
b34d86cb 242 BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream, aFileVer);
7fd59977 243 mySections.Append(aSection);
5ecc46c0 244 } while(!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS) && !theIStream.eof());
245
246 if (theIStream.eof()) {
247 // There is no shape section in the file.
83ae3591 248 myMsgDriver->Send (aMethStr + "error: shape section is not found", Message_Fail);
5ecc46c0 249 myReaderStatus = PCDM_RS_ReaderException;
250 return;
251 }
252
4ff92abe 253 aDocumentPos = theIStream.tellg(); // position of root label
7fd59977 254
255 BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
256 for (; anIterS.More(); anIterS.Next()) {
257 BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
258 if (aCurSection.IsPostRead() == Standard_False) {
04232180 259 theIStream.seekg ((std::streampos) aCurSection.Offset());
6d8f9f4a 260 if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS))
261 {
7e785937 262 ReadShapeSection (aCurSection, theIStream, false, aPS.Next());
6d8f9f4a 263 if (!aPS.More())
264 {
265 myReaderStatus = PCDM_RS_UserBreak;
266 return;
267 }
6d8f9f4a 268 }
7fd59977 269 else
6d8f9f4a 270 ReadSection (aCurSection, theDoc, theIStream);
7fd59977 271 }
272 }
273 } else { //aFileVer < 3
4ff92abe 274 aDocumentPos = theIStream.tellg(); // position of root label
7fd59977 275
276 // retrieve SHAPESECTION_POS string
277 char aShapeSecLabel[SIZEOFSHAPELABEL + 1];
278 aShapeSecLabel[SIZEOFSHAPELABEL] = 0x00;
4ff92abe 279 theIStream.read ((char*)&aShapeSecLabel, SIZEOFSHAPELABEL);// SHAPESECTION_POS
7fd59977 280 TCollection_AsciiString aShapeLabel(aShapeSecLabel);
281 // detect if a file was written in old fashion (version 2 without shapes)
282 // and if so then skip reading ShapeSection
283 if (aShapeLabel.Length() > 0) {
284 // version 2+(with shapes) and higher goes here
285 if(aShapeLabel.Length() <= 0 || aShapeLabel != SHAPESECTION_POS) {
83ae3591 286 myMsgDriver->Send (aMethStr + "error: Format failure", Message_Fail);
7fd59977 287 myReaderStatus = PCDM_RS_FormatFailure;
288 return;
289 }
290
291 // retrieve ShapeSection Position
292 Standard_Integer aShapeSectionPos; // go to ShapeSection
4ff92abe 293 theIStream.read ((char*)&aShapeSectionPos, sizeof(Standard_Integer));
7fd59977 294
295#if DO_INVERSE
296 aShapeSectionPos = InverseInt (aShapeSectionPos);
297#endif
0797d9d3 298#ifdef OCCT_DEBUG
04232180 299 std::cout <<"aShapeSectionPos = " <<aShapeSectionPos <<std::endl;
7fd59977 300#endif
301 if(aShapeSectionPos) {
83ae3591 302 aDocumentPos = theIStream.tellg();
04232180 303 theIStream.seekg((std::streampos) aShapeSectionPos);
7fd59977 304
83ae3591 305 CheckShapeSection(aShapeSectionPos, theIStream);
306 // Read Shapes
307 BinLDrivers_DocumentSection aCurSection;
7e785937 308 ReadShapeSection (aCurSection, theIStream, Standard_False, aPS.Next());
6d8f9f4a 309 if (!aPS.More())
310 {
311 myReaderStatus = PCDM_RS_UserBreak;
312 return;
313 }
7fd59977 314 }
315 }
316 } // end of reading Sections or shape section
317
318 // Return to read of the Document structure
4ff92abe 319 theIStream.seekg(aDocumentPos);
7fd59977 320
321 // read the header (tag) of the root label
322 Standard_Integer aTag;
4ff92abe 323 theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
7fd59977 324
325 // read sub-tree of the root label
7e785937 326 Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), aPS.Next());
6d8f9f4a 327 if (!aPS.More())
328 {
329 myReaderStatus = PCDM_RS_UserBreak;
330 return;
331 }
7e785937 332
bf954475 333 Clear();
6d8f9f4a 334 if (!aPS.More())
335 {
336 myReaderStatus = PCDM_RS_UserBreak;
337 return;
338 }
339 aPS.Next();
7fd59977 340
341 if (nbRead > 0) {
342 // attach data to the document
343 aDoc->SetData (aData);
344 TDocStd_Owner::SetDocument (aData, aDoc);
345 aDoc->SetComments(aHeaderData->Comments());
346 myReaderStatus = PCDM_RS_OK;
347 }
348
349 // Read Sections (post-reading type)
350 if (aFileVer >= 3) {
4ff92abe 351 BinLDrivers_VectorOfDocumentSection::Iterator aSectIter (mySections);
352 for (; aSectIter.More(); aSectIter.Next()) {
353 BinLDrivers_DocumentSection& aCurSection = aSectIter.ChangeValue();
7fd59977 354 if (aCurSection.IsPostRead()) {
04232180 355 theIStream.seekg ((std::streampos) aCurSection.Offset());
83ae3591 356 ReadSection (aCurSection, theDoc, theIStream);
7fd59977 357 }
358 }
359 }
360}
361
362//=======================================================================
363//function : ReadSubTree
364//purpose :
365//=======================================================================
366
367Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
368 (Standard_IStream& theIS,
6d8f9f4a 369 const TDF_Label& theLabel,
7e785937 370 const Message_ProgressRange& theRange)
7fd59977 371{
372 Standard_Integer nbRead = 0;
b34d86cb 373 TCollection_ExtendedString aMethStr
7fd59977 374 ("BinLDrivers_DocumentRetrievalDriver: ");
375
7e785937 376 Message_ProgressScope aPS(theRange, "Reading sub tree", 2, true);
6d8f9f4a 377
7fd59977 378 // Read attributes:
379 theIS >> myPAtt;
380 while (theIS && myPAtt.TypeId() > 0 && // not an end marker ?
5ecc46c0 381 myPAtt.Id() > 0 && // not a garbage ?
6d8f9f4a 382 !theIS.eof())
383 {
384 if (!aPS.More())
385 {
386 myReaderStatus = PCDM_RS_UserBreak;
387 return -1;
388 }
389
7fd59977 390 // get a driver according to TypeId
391 Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt.TypeId());
392 if (!aDriver.IsNull()) {
393 // create transient attribute
394 nbRead++;
395 Standard_Integer anID = myPAtt.Id();
396 Handle(TDF_Attribute) tAtt;
397 Standard_Boolean isBound = myRelocTable.IsBound(anID);
398 if (isBound)
399 tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID));
400 else
401 tAtt = aDriver->NewEmpty();
60fddce4 402
7fd59977 403 if (tAtt->Label().IsNull())
60fddce4 404 {
405 try
406 {
407 theLabel.AddAttribute (tAtt);
408 }
409 catch (const Standard_DomainError&)
410 {
411 // For attributes that can have arbitrary GUID (e.g. TDataStd_Integer), exception
412 // will be raised in valid case if attribute of that type with default GUID is already
413 // present on the same label; the reason is that actual GUID will be read later.
414 // To avoid this, set invalid (null) GUID to the newly added attribute (see #29669)
415 static const Standard_GUID fbidGuid;
416 tAtt->SetID (fbidGuid);
417 theLabel.AddAttribute (tAtt);
418 }
419 }
7fd59977 420 else
83ae3591 421 myMsgDriver->Send (aMethStr +
422 "warning: attempt to attach attribute " +
423 aDriver->TypeName() + " to a second label", Message_Warning);
7fd59977 424
425 Standard_Boolean ok = aDriver->Paste (myPAtt, tAtt, myRelocTable);
426 if (!ok) {
427 // error converting persistent to transient
83ae3591 428 myMsgDriver->Send (aMethStr + "warning: failure reading attribute " +
429 aDriver->TypeName(), Message_Warning);
7fd59977 430 }
431 else if (!isBound)
432 myRelocTable.Bind (anID, tAtt);
433 }
434 else if (!myMapUnsupported.Contains(myPAtt.TypeId()))
83ae3591 435 myMsgDriver->Send (aMethStr + "warning: type ID not registered in header: "
436 + myPAtt.TypeId(), Message_Warning);
7fd59977 437
438 // read next attribute
439 theIS >> myPAtt;
440 }
441 if (!theIS || myPAtt.TypeId() != BinLDrivers_ENDATTRLIST) {
442 // unexpected EOF or garbage data
83ae3591 443 myMsgDriver->Send (aMethStr + "error: unexpected EOF or garbage data", Message_Fail);
7fd59977 444 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
445 return -1;
446 }
447
448 // Read children:
449 // read the tag of a child label
450 Standard_Integer aTag = BinLDrivers_ENDLABEL;
451 theIS.read ((char*) &aTag, sizeof(Standard_Integer));
452#if DO_INVERSE
453 aTag = InverseInt (aTag);
454#endif
6d8f9f4a 455
5ecc46c0 456 while (theIS && aTag >= 0 && !theIS.eof()) { // not an end marker ?
7fd59977 457 // create sub-label
458 TDF_Label aLab = theLabel.FindChild (aTag, Standard_True);
6d8f9f4a 459 if (!aPS.More())
460 {
461 myReaderStatus = PCDM_RS_UserBreak;
462 return -1;
463 }
7fd59977 464
7e785937 465
7fd59977 466 // read sub-tree
7e785937 467 Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, aPS.Next());
7fd59977 468 // check for error
469 if (nbSubRead == -1)
470 return -1;
471 nbRead += nbSubRead;
472
473 // read the tag of the next child
474 theIS.read ((char*) &aTag, sizeof(Standard_Integer));
475#if DO_INVERSE
476 aTag = InverseInt (aTag);
477#endif
478 }
6d8f9f4a 479
7fd59977 480 if (aTag != BinLDrivers_ENDLABEL) {
481 // invalid end label marker
83ae3591 482 myMsgDriver->Send (aMethStr + "error: invalid end label marker", Message_Fail);
7fd59977 483 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
484 return -1;
485 }
486
487 return nbRead;
488}
489
490//=======================================================================
491//function : AttributeDrivers
492//purpose :
493//=======================================================================
494
495Handle(BinMDF_ADriverTable) BinLDrivers_DocumentRetrievalDriver::AttributeDrivers
83ae3591 496 (const Handle(Message_Messenger)& theMessageDriver)
7fd59977 497{
498 return BinLDrivers::AttributeDrivers (theMessageDriver);
499}
500
7fd59977 501//=======================================================================
502//function : ReadSection
503//purpose :
504//=======================================================================
505
506void BinLDrivers_DocumentRetrievalDriver::ReadSection
507 (BinLDrivers_DocumentSection& /*theSection*/,
508 const Handle(CDM_Document)& /*theDocument*/,
509 Standard_IStream& /*theIS*/)
510{
511 // empty; should be redefined in subclasses
512}
513
514//=======================================================================
515//function : ReadShapeSection
516//purpose :
517//=======================================================================
518
519void BinLDrivers_DocumentRetrievalDriver::ReadShapeSection
520 (BinLDrivers_DocumentSection& theSection,
6d8f9f4a 521 Standard_IStream& /*theIS*/,
522 const Standard_Boolean isMess,
7e785937 523 const Message_ProgressRange &/*theRange*/)
7fd59977 524
525{
526 if(isMess && theSection.Length()) {
527 const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: ");
83ae3591 528 myMsgDriver->Send (aMethStr + "warning: Geometry is not supported by Lite schema. ", Message_Warning);
7fd59977 529 }
530}
531
532//=======================================================================
533//function : CheckShapeSection
534//purpose :
535//=======================================================================
536void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection(
83ae3591 537 const Storage_Position& ShapeSectionPos,
538 Standard_IStream& IS)
7fd59977 539{
d41f6af3 540 if (!IS.eof())
541 {
105aae76 542 const std::streamoff endPos = IS.rdbuf()->pubseekoff(0L, std::ios_base::end, std::ios_base::in);
0797d9d3 543#ifdef OCCT_DEBUG
04232180 544 std::cout << "endPos = " << endPos <<std::endl;
7fd59977 545#endif
546 if(ShapeSectionPos != endPos) {
547 const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: ");
83ae3591 548 myMsgDriver->Send (aMethStr + "warning: Geometry is not supported by Lite schema. ", Message_Warning);
7fd59977 549 }
550 }
551}
552
bf954475 553//=======================================================================
554//function : Clear
555//purpose :
556//=======================================================================
557void BinLDrivers_DocumentRetrievalDriver::Clear()
558{
559 myPAtt.Destroy(); // free buffer
560 myRelocTable.Clear();
561 myMapUnsupported.Clear();
562}
563
d9ff84e8 564//=======================================================================
565//function : CheckDocumentVersion
566//purpose :
567//=======================================================================
568Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion(
569 const Standard_Integer theFileVersion,
570 const Standard_Integer theCurVersion)
571{
572 if (theFileVersion < 2 || theFileVersion > theCurVersion) {
573 // file was written with another version
574 return Standard_False;
575 }
576 return Standard_True;
577}