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> |
27 | #include <CDM_MessageDriver.hxx> |
7fd59977 |
28 | #include <FSD_BinaryFile.hxx> |
29 | #include <FSD_FileHeader.hxx> |
42cf5bc1 |
30 | #include <PCDM_Document.hxx> |
7fd59977 |
31 | #include <Standard_ErrorHandler.hxx> |
32 | #include <Standard_Stream.hxx> |
42cf5bc1 |
33 | #include <Standard_Type.hxx> |
34 | #include <Storage_HeaderData.hxx> |
7fd59977 |
35 | #include <Storage_Schema.hxx> |
42cf5bc1 |
36 | #include <TCollection_AsciiString.hxx> |
37 | #include <TCollection_ExtendedString.hxx> |
38 | #include <TDF_Attribute.hxx> |
7fd59977 |
39 | #include <TDF_Data.hxx> |
42cf5bc1 |
40 | #include <TDF_Label.hxx> |
7fd59977 |
41 | #include <TDocStd_Document.hxx> |
42 | #include <TDocStd_Owner.hxx> |
43 | |
92efcf78 |
44 | IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver) |
45 | |
7fd59977 |
46 | #define SHAPESECTION_POS "SHAPE_SECTION_POS:" |
47 | #define SIZEOFSHAPELABEL 18 |
48 | |
49 | #define DATATYPE_MIGRATION |
50 | //#define DATATYPE_MIGRATION_DEB |
51 | //======================================================================= |
52 | //function : BinLDrivers_DocumentRetrievalDriver |
53 | //purpose : Constructor |
54 | //======================================================================= |
55 | |
56 | BinLDrivers_DocumentRetrievalDriver::BinLDrivers_DocumentRetrievalDriver () |
57 | { |
58 | myReaderStatus = PCDM_RS_OK; |
59 | } |
60 | |
61 | //======================================================================= |
62 | //function : CreateDocument |
63 | //purpose : pure virtual method definition |
64 | //======================================================================= |
65 | |
66 | Handle(CDM_Document) BinLDrivers_DocumentRetrievalDriver::CreateDocument() |
67 | { |
68 | return new TDocStd_Document(PCDM_RetrievalDriver::GetFormat()); |
69 | } |
70 | |
71 | //======================================================================= |
72 | //function : SchemaName |
73 | //purpose : pure virtual method definition |
74 | //======================================================================= |
75 | |
76 | TCollection_ExtendedString BinLDrivers_DocumentRetrievalDriver::SchemaName() const |
77 | { |
78 | TCollection_ExtendedString schemaname; |
79 | return schemaname; |
80 | } |
81 | |
82 | //======================================================================= |
83 | //function : Make |
84 | //purpose : pure virtual method definition |
85 | //======================================================================= |
86 | |
87 | void BinLDrivers_DocumentRetrievalDriver::Make (const Handle(PCDM_Document)&, |
88 | const Handle(CDM_Document)&) |
89 | { |
90 | } |
91 | |
92 | //======================================================================= |
93 | //function : Read |
94 | //purpose : |
95 | //======================================================================= |
96 | |
97 | #define START_TYPES "START_TYPES" |
98 | #define END_TYPES "END_TYPES" |
99 | |
100 | void BinLDrivers_DocumentRetrievalDriver::Read |
101 | (const TCollection_ExtendedString& theFileName, |
102 | const Handle(CDM_Document)& theNewDocument, |
103 | const Handle(CDM_Application)& theApplication) |
104 | { |
105 | myReaderStatus = PCDM_RS_DriverFailure; |
106 | myMsgDriver = theApplication -> MessageDriver(); |
107 | |
108 | const TCollection_ExtendedString aMethStr |
109 | ("BinLDrivers_DocumentRetrievalDriver: "); |
110 | |
111 | Handle(TDocStd_Document) aDoc = |
112 | Handle(TDocStd_Document)::DownCast(theNewDocument); |
113 | if (aDoc.IsNull()) { |
0797d9d3 |
114 | #ifdef OCCT_DEBUG |
7fd59977 |
115 | WriteMessage (aMethStr + "error: null document"); |
116 | #endif |
117 | myReaderStatus = PCDM_RS_NoDocument; |
118 | return; |
119 | } |
120 | |
d9ff84e8 |
121 | TCollection_AsciiString aFileName (theFileName); |
7fd59977 |
122 | |
123 | // 1. Read the information section |
124 | Handle(Storage_HeaderData) aHeaderData; |
125 | Storage_Position anInfoSectionEnd = ReadInfoSection( aFileName, aHeaderData ); |
126 | if (!anInfoSectionEnd) { |
127 | WriteMessage (aMethStr + "error: file has invalid header"); |
128 | myReaderStatus = PCDM_RS_UnrecognizedFileFormat; |
129 | return; |
130 | } |
131 | |
132 | // 1.a Version of writer |
133 | if (!aHeaderData->StorageVersion().IsIntegerValue()) { |
134 | // file has no format version |
135 | WriteMessage (aMethStr + "error: file has no format version"); |
136 | myReaderStatus = PCDM_RS_FormatFailure; |
137 | return; |
138 | } |
139 | Standard_Integer aFileVer = aHeaderData->StorageVersion().IntegerValue(); |
140 | Standard_Integer aCurrVer = BinLDrivers::StorageVersion().IntegerValue(); |
141 | // maintain one-way compatibility starting from version 2+ |
d9ff84e8 |
142 | if (!CheckDocumentVersion(aFileVer, aCurrVer)) { |
143 | myReaderStatus = PCDM_RS_NoVersion; |
7fd59977 |
144 | // file was written with another version |
145 | WriteMessage (aMethStr + "error: wrong file version: " + |
146 | aHeaderData->StorageVersion() + " while current is " + |
147 | BinLDrivers::StorageVersion()); |
7fd59977 |
148 | return; |
149 | } |
150 | |
151 | // 1.b Retrieve the Types table |
152 | TColStd_SequenceOfAsciiString aTypeNames; //Sequence of types in file |
153 | const TColStd_SequenceOfAsciiString& aUserInfo = aHeaderData->UserInfo(); |
154 | Standard_Boolean begin = Standard_False; |
155 | Standard_Integer i; |
156 | for (i=1; i <= aUserInfo.Length(); i++) { |
157 | //const TCollection_AsciiString& aStr = aUserInfo(i); |
158 | TCollection_AsciiString aStr = aUserInfo(i); |
159 | if (aStr == START_TYPES) |
160 | begin = Standard_True; |
161 | else if (aStr == END_TYPES) |
162 | break; |
163 | else if (begin) { |
164 | if(aFileVer < 5) { |
165 | #ifdef DATATYPE_MIGRATION |
166 | TCollection_AsciiString newName; |
167 | if(Storage_Schema::CheckTypeMigration(aStr, newName)) { |
0797d9d3 |
168 | #ifdef OCCT_DEBUG |
7fd59977 |
169 | cout << "CheckTypeMigration:OldType = " <<aStr << " Len = "<<aStr.Length()<<endl; |
170 | cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl; |
171 | #endif |
172 | aStr = newName; |
173 | } |
174 | #endif |
175 | } |
176 | aTypeNames.Append (aStr); |
177 | } |
178 | } |
179 | if (myDrivers.IsNull()) |
180 | myDrivers = AttributeDrivers (myMsgDriver); |
181 | myDrivers->AssignIds (aTypeNames); |
182 | |
183 | // recognize types not supported by drivers |
184 | myMapUnsupported.Clear(); |
185 | for (i=1; i <= aTypeNames.Length(); i++) |
186 | if (myDrivers->GetDriver(i).IsNull()) |
187 | myMapUnsupported.Add(i); |
188 | if (!myMapUnsupported.IsEmpty()) { |
189 | WriteMessage (aMethStr + "warning: " |
190 | "the following attributes have no driver:"); |
191 | for (i=1; i <= aTypeNames.Length(); i++) |
192 | if (myMapUnsupported.Contains(i)) |
193 | WriteMessage (aTypeNames(i)); |
194 | } |
195 | |
196 | // Open the file stream |
d9ff84e8 |
197 | #ifdef _WIN32 |
198 | ifstream anIS ((const wchar_t*) theFileName.ToExtString(), ios::in | ios::binary); |
7fd59977 |
199 | #else |
200 | ifstream anIS (aFileName.ToCString()); |
201 | #endif |
202 | |
203 | if (!anIS) { |
204 | // Can not open file |
205 | WriteMessage (aMethStr + "error: can't open file " + theFileName); |
206 | myReaderStatus = PCDM_RS_OpenError; |
207 | return; |
208 | } |
209 | |
210 | // skip info section |
211 | anIS.seekg( (streampos) anInfoSectionEnd ); |
212 | |
213 | // propagate the opened document version to data drivers |
214 | PropagateDocumentVersion(aFileVer); |
215 | |
216 | // 2. Read document contents |
217 | |
218 | // 2a. Retrieve data from the stream: |
219 | myRelocTable.Clear(); |
220 | mySections.Clear(); |
221 | myPAtt.Init(); |
222 | Handle(TDF_Data) aData = new TDF_Data(); |
60be1f9b |
223 | streampos aDocumentPos = -1; |
7fd59977 |
224 | |
225 | // 2b. Read the TOC of Sections |
226 | if (aFileVer >= 3) { |
227 | BinLDrivers_DocumentSection aSection; |
228 | do { |
229 | BinLDrivers_DocumentSection::ReadTOC (aSection, anIS); |
230 | mySections.Append(aSection); |
231 | } while |
232 | (!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS)); |
233 | aDocumentPos = anIS.tellg(); // position of root label |
234 | |
235 | BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections); |
236 | for (; anIterS.More(); anIterS.Next()) { |
237 | BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue(); |
238 | if (aCurSection.IsPostRead() == Standard_False) { |
239 | anIS.seekg ((streampos) aCurSection.Offset()); |
240 | if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS)) |
241 | ReadShapeSection (aCurSection, anIS); |
242 | else |
243 | ReadSection (aCurSection, theNewDocument, anIS); |
244 | } |
245 | } |
246 | } else { //aFileVer < 3 |
247 | aDocumentPos = anIS.tellg(); // position of root label |
248 | |
249 | // retrieve SHAPESECTION_POS string |
250 | char aShapeSecLabel[SIZEOFSHAPELABEL + 1]; |
251 | aShapeSecLabel[SIZEOFSHAPELABEL] = 0x00; |
252 | anIS.read ((char*)&aShapeSecLabel, SIZEOFSHAPELABEL);// SHAPESECTION_POS |
253 | TCollection_AsciiString aShapeLabel(aShapeSecLabel); |
254 | // detect if a file was written in old fashion (version 2 without shapes) |
255 | // and if so then skip reading ShapeSection |
256 | if (aShapeLabel.Length() > 0) { |
257 | // version 2+(with shapes) and higher goes here |
258 | if(aShapeLabel.Length() <= 0 || aShapeLabel != SHAPESECTION_POS) { |
259 | WriteMessage (aMethStr + "error: Format failure"); |
260 | myReaderStatus = PCDM_RS_FormatFailure; |
261 | return; |
262 | } |
263 | |
264 | // retrieve ShapeSection Position |
265 | Standard_Integer aShapeSectionPos; // go to ShapeSection |
266 | anIS.read ((char*)&aShapeSectionPos, sizeof(Standard_Integer)); |
267 | |
268 | #if DO_INVERSE |
269 | aShapeSectionPos = InverseInt (aShapeSectionPos); |
270 | #endif |
0797d9d3 |
271 | #ifdef OCCT_DEBUG |
7fd59977 |
272 | cout <<"aShapeSectionPos = " <<aShapeSectionPos <<endl; |
273 | #endif |
274 | if(aShapeSectionPos) { |
275 | aDocumentPos = anIS.tellg(); |
276 | anIS.seekg((streampos) aShapeSectionPos); |
277 | |
105aae76 |
278 | CheckShapeSection(aShapeSectionPos, anIS); |
7fd59977 |
279 | // Read Shapes |
280 | BinLDrivers_DocumentSection aCurSection; |
281 | ReadShapeSection (aCurSection, anIS, Standard_False); |
282 | } |
283 | } |
284 | } // end of reading Sections or shape section |
285 | |
286 | // Return to read of the Document structure |
60be1f9b |
287 | anIS.seekg(aDocumentPos); |
7fd59977 |
288 | |
289 | // read the header (tag) of the root label |
290 | Standard_Integer aTag; |
291 | anIS.read ((char*)&aTag, sizeof(Standard_Integer)); |
292 | |
293 | // read sub-tree of the root label |
294 | Standard_Integer nbRead = ReadSubTree (anIS, aData->Root()); |
295 | myPAtt.Destroy(); // free buffer |
296 | myRelocTable.Clear(); |
297 | myMapUnsupported.Clear(); |
298 | |
299 | if (nbRead > 0) { |
300 | // attach data to the document |
301 | aDoc->SetData (aData); |
302 | TDocStd_Owner::SetDocument (aData, aDoc); |
303 | aDoc->SetComments(aHeaderData->Comments()); |
304 | myReaderStatus = PCDM_RS_OK; |
305 | } |
306 | |
307 | // Read Sections (post-reading type) |
308 | if (aFileVer >= 3) { |
309 | BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections); |
310 | for (; anIterS.More(); anIterS.Next()) { |
311 | BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue(); |
312 | if (aCurSection.IsPostRead()) { |
313 | anIS.seekg ((streampos) aCurSection.Offset()); |
314 | ReadSection (aCurSection, theNewDocument, anIS); |
315 | } |
316 | } |
317 | } |
318 | } |
319 | |
320 | //======================================================================= |
321 | //function : ReadSubTree |
322 | //purpose : |
323 | //======================================================================= |
324 | |
325 | Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree |
326 | (Standard_IStream& theIS, |
327 | const TDF_Label& theLabel) |
328 | { |
329 | Standard_Integer nbRead = 0; |
330 | static TCollection_ExtendedString aMethStr |
331 | ("BinLDrivers_DocumentRetrievalDriver: "); |
332 | |
333 | // Read attributes: |
334 | theIS >> myPAtt; |
335 | while (theIS && myPAtt.TypeId() > 0 && // not an end marker ? |
336 | myPAtt.Id() > 0) { // not a garbage ? |
337 | // get a driver according to TypeId |
338 | Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt.TypeId()); |
339 | if (!aDriver.IsNull()) { |
340 | // create transient attribute |
341 | nbRead++; |
342 | Standard_Integer anID = myPAtt.Id(); |
343 | Handle(TDF_Attribute) tAtt; |
344 | Standard_Boolean isBound = myRelocTable.IsBound(anID); |
345 | if (isBound) |
346 | tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID)); |
347 | else |
348 | tAtt = aDriver->NewEmpty(); |
349 | if (tAtt->Label().IsNull()) |
350 | theLabel.AddAttribute (tAtt); |
351 | else |
352 | WriteMessage (aMethStr + |
353 | "warning: attempt to attach attribute " + |
354 | aDriver->TypeName() + " to a second label"); |
355 | |
356 | Standard_Boolean ok = aDriver->Paste (myPAtt, tAtt, myRelocTable); |
357 | if (!ok) { |
358 | // error converting persistent to transient |
359 | WriteMessage (aMethStr + "warning: failure reading attribute " + |
360 | aDriver->TypeName()); |
361 | } |
362 | else if (!isBound) |
363 | myRelocTable.Bind (anID, tAtt); |
364 | } |
365 | else if (!myMapUnsupported.Contains(myPAtt.TypeId())) |
366 | WriteMessage (aMethStr + "warning: type ID not registered in header: " |
367 | + myPAtt.TypeId()); |
368 | |
369 | // read next attribute |
370 | theIS >> myPAtt; |
371 | } |
372 | if (!theIS || myPAtt.TypeId() != BinLDrivers_ENDATTRLIST) { |
373 | // unexpected EOF or garbage data |
374 | WriteMessage (aMethStr + "error: unexpected EOF or garbage data"); |
375 | myReaderStatus = PCDM_RS_UnrecognizedFileFormat; |
376 | return -1; |
377 | } |
378 | |
379 | // Read children: |
380 | // read the tag of a child label |
381 | Standard_Integer aTag = BinLDrivers_ENDLABEL; |
382 | theIS.read ((char*) &aTag, sizeof(Standard_Integer)); |
383 | #if DO_INVERSE |
384 | aTag = InverseInt (aTag); |
385 | #endif |
386 | while (theIS && aTag >= 0) { // not an end marker ? |
387 | // create sub-label |
388 | TDF_Label aLab = theLabel.FindChild (aTag, Standard_True); |
389 | |
390 | // read sub-tree |
391 | Standard_Integer nbSubRead = ReadSubTree(theIS, aLab); |
392 | // check for error |
393 | if (nbSubRead == -1) |
394 | return -1; |
395 | nbRead += nbSubRead; |
396 | |
397 | // read the tag of the next child |
398 | theIS.read ((char*) &aTag, sizeof(Standard_Integer)); |
399 | #if DO_INVERSE |
400 | aTag = InverseInt (aTag); |
401 | #endif |
402 | } |
403 | if (aTag != BinLDrivers_ENDLABEL) { |
404 | // invalid end label marker |
405 | WriteMessage (aMethStr + "error: invalid end label marker"); |
406 | myReaderStatus = PCDM_RS_UnrecognizedFileFormat; |
407 | return -1; |
408 | } |
409 | |
410 | return nbRead; |
411 | } |
412 | |
413 | //======================================================================= |
414 | //function : AttributeDrivers |
415 | //purpose : |
416 | //======================================================================= |
417 | |
418 | Handle(BinMDF_ADriverTable) BinLDrivers_DocumentRetrievalDriver::AttributeDrivers |
419 | (const Handle(CDM_MessageDriver)& theMessageDriver) |
420 | { |
421 | return BinLDrivers::AttributeDrivers (theMessageDriver); |
422 | } |
423 | |
424 | //======================================================================= |
425 | //function : ReadInfoSection |
426 | //purpose : Read the info section of theFile, return a file |
427 | // position corresponding to the info section end |
428 | //======================================================================= |
429 | |
430 | Storage_Position BinLDrivers_DocumentRetrievalDriver::ReadInfoSection |
431 | (const TCollection_AsciiString& theFileName, |
432 | Handle(Storage_HeaderData)& theData) |
433 | { |
434 | TCollection_ExtendedString aMsg |
435 | ( "BinLDrivers_DocumentRetrievalDriver: error: "); |
436 | |
437 | FSD_BinaryFile aFileDriver; |
438 | Storage_Position aPos = 0; |
439 | if (aFileDriver.Open( theFileName, Storage_VSRead ) == Storage_VSOk) |
440 | { |
441 | Storage_Schema aSchema; |
442 | theData = aSchema.ReadHeaderSection( aFileDriver ); |
443 | |
444 | if (theData->ErrorStatus() == Storage_VSOk) |
445 | aPos = aFileDriver.Tell(); |
446 | else |
447 | WriteMessage( aMsg + theData->ErrorStatusExtension() ); |
448 | } |
449 | else |
450 | WriteMessage( aMsg + "can not open file " + theFileName); |
451 | |
452 | aFileDriver.Close(); |
453 | |
454 | return aPos; |
455 | } |
456 | |
457 | //======================================================================= |
458 | //function : WriteMessage |
459 | //purpose : write theMessage to the MessageDriver of |
460 | // theApplication |
461 | //======================================================================= |
462 | |
463 | void BinLDrivers_DocumentRetrievalDriver::WriteMessage |
464 | (const TCollection_ExtendedString& theMsg) |
465 | { |
466 | if (!myMsgDriver.IsNull()) |
467 | myMsgDriver->Write (theMsg.ToExtString()); |
468 | } |
469 | |
470 | //======================================================================= |
471 | //function : ReadSection |
472 | //purpose : |
473 | //======================================================================= |
474 | |
475 | void BinLDrivers_DocumentRetrievalDriver::ReadSection |
476 | (BinLDrivers_DocumentSection& /*theSection*/, |
477 | const Handle(CDM_Document)& /*theDocument*/, |
478 | Standard_IStream& /*theIS*/) |
479 | { |
480 | // empty; should be redefined in subclasses |
481 | } |
482 | |
483 | //======================================================================= |
484 | //function : ReadShapeSection |
485 | //purpose : |
486 | //======================================================================= |
487 | |
488 | void BinLDrivers_DocumentRetrievalDriver::ReadShapeSection |
489 | (BinLDrivers_DocumentSection& theSection, |
490 | Standard_IStream& /*theIS*/, |
491 | const Standard_Boolean isMess) |
492 | |
493 | { |
494 | if(isMess && theSection.Length()) { |
495 | const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: "); |
496 | WriteMessage (aMethStr + "warning: Geometry is not supported by Lite schema. "); |
497 | } |
498 | } |
499 | |
500 | //======================================================================= |
501 | //function : CheckShapeSection |
502 | //purpose : |
503 | //======================================================================= |
504 | void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection( |
505 | const Storage_Position& ShapeSectionPos, |
506 | Standard_IStream& IS) |
507 | { |
d41f6af3 |
508 | if (!IS.eof()) |
509 | { |
105aae76 |
510 | const std::streamoff endPos = IS.rdbuf()->pubseekoff(0L, std::ios_base::end, std::ios_base::in); |
0797d9d3 |
511 | #ifdef OCCT_DEBUG |
7fd59977 |
512 | cout << "endPos = " << endPos <<endl; |
513 | #endif |
514 | if(ShapeSectionPos != endPos) { |
515 | const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: "); |
516 | WriteMessage (aMethStr + "warning: Geometry is not supported by Lite schema. "); |
517 | } |
518 | } |
519 | } |
520 | |
521 | //======================================================================= |
522 | //function : PropagateDocumentVersion |
523 | //purpose : |
524 | //======================================================================= |
525 | void BinLDrivers_DocumentRetrievalDriver::PropagateDocumentVersion(const Standard_Integer theDocVersion ) |
526 | { |
527 | BinMDataStd::SetDocumentVersion(theDocVersion); |
528 | } |
d9ff84e8 |
529 | |
530 | //======================================================================= |
531 | //function : CheckDocumentVersion |
532 | //purpose : |
533 | //======================================================================= |
534 | Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion( |
535 | const Standard_Integer theFileVersion, |
536 | const Standard_Integer theCurVersion) |
537 | { |
538 | if (theFileVersion < 2 || theFileVersion > theCurVersion) { |
539 | // file was written with another version |
540 | return Standard_False; |
541 | } |
542 | return Standard_True; |
543 | } |
544 | |