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