0032455: Data Exchange - replace OSD_OpenStream() usage with OSD_FileSystem::DefaultF...
[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>
ad3f20c6 30#include <OSD_FileSystem.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>
d5c71e20 43#include <TDF_Tool.hxx>
7fd59977 44#include <TDocStd_Document.hxx>
14eea829 45#include <TDocStd_FormatVersion.hxx>
7fd59977 46#include <TDocStd_Owner.hxx>
7e785937 47#include <Message_ProgressScope.hxx>
d5c71e20 48#include <PCDM_ReaderFilter.hxx>
6d8f9f4a 49
7fd59977 50
92efcf78 51IMPLEMENT_STANDARD_RTTIEXT(BinLDrivers_DocumentRetrievalDriver,PCDM_RetrievalDriver)
52
7fd59977 53#define SHAPESECTION_POS "SHAPE_SECTION_POS:"
d5c71e20 54#define ENDSECTION_POS ":"
7fd59977 55#define SIZEOFSHAPELABEL 18
56
57#define DATATYPE_MIGRATION
58//#define DATATYPE_MIGRATION_DEB
59//=======================================================================
60//function : BinLDrivers_DocumentRetrievalDriver
61//purpose : Constructor
62//=======================================================================
63
64BinLDrivers_DocumentRetrievalDriver::BinLDrivers_DocumentRetrievalDriver ()
65{
66 myReaderStatus = PCDM_RS_OK;
67}
68
7fd59977 69//=======================================================================
70//function : Read
71//purpose :
72//=======================================================================
7fd59977 73void BinLDrivers_DocumentRetrievalDriver::Read
74 (const TCollection_ExtendedString& theFileName,
75 const Handle(CDM_Document)& theNewDocument,
6d8f9f4a 76 const Handle(CDM_Application)& theApplication,
d5c71e20 77 const Handle(PCDM_ReaderFilter)& theFilter,
7e785937 78 const Message_ProgressRange& theRange)
4ff92abe 79{
ad3f20c6 80 const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
81 opencascade::std::shared_ptr<std::istream> aFileStream = aFileSystem->OpenIStream (theFileName, std::ios::in | std::ios::binary);
4ff92abe 82
ad3f20c6 83 if (aFileStream.get() != NULL && aFileStream->good())
4ff92abe 84 {
85 Handle(Storage_Data) dData;
ad3f20c6 86 TCollection_ExtendedString aFormat = PCDM_ReadWriter::FileFormat (*aFileStream, dData);
4ff92abe 87
ad3f20c6 88 Read (*aFileStream, dData, theNewDocument, theApplication, theFilter, theRange);
7e785937 89 if (!theRange.More())
6d8f9f4a 90 {
91 myReaderStatus = PCDM_RS_UserBreak;
92 return;
93 }
4ff92abe 94 }
95 else
96 {
97 myReaderStatus = PCDM_RS_OpenError;
98 }
99}
100
101#define MODIFICATION_COUNTER "MODIFICATION_COUNTER: "
102#define REFERENCE_COUNTER "REFERENCE_COUNTER: "
103
104#define START_TYPES "START_TYPES"
105#define END_TYPES "END_TYPES"
106
107//=======================================================================
108//function : Read
109//purpose :
110//=======================================================================
d5c71e20 111void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream& theIStream,
112 const Handle(Storage_Data)& theStorageData,
113 const Handle(CDM_Document)& theDoc,
114 const Handle(CDM_Application)& theApplication,
115 const Handle(PCDM_ReaderFilter)& theFilter,
116 const Message_ProgressRange& theRange)
7fd59977 117{
118 myReaderStatus = PCDM_RS_DriverFailure;
119 myMsgDriver = theApplication -> MessageDriver();
120
121 const TCollection_ExtendedString aMethStr
122 ("BinLDrivers_DocumentRetrievalDriver: ");
123
124 Handle(TDocStd_Document) aDoc =
4ff92abe 125 Handle(TDocStd_Document)::DownCast(theDoc);
7fd59977 126 if (aDoc.IsNull()) {
0797d9d3 127#ifdef OCCT_DEBUG
83ae3591 128 myMsgDriver->Send (aMethStr + "error: null document", Message_Fail);
7fd59977 129#endif
130 myReaderStatus = PCDM_RS_NoDocument;
131 return;
132 }
133
4ff92abe 134 // 1. the information section
7fd59977 135 Handle(Storage_HeaderData) aHeaderData;
4ff92abe 136
137 if (!theStorageData.IsNull())
138 {
139 aHeaderData = theStorageData->HeaderData();
140 }
141
142 if (!aHeaderData.IsNull())
143 {
144 for (Standard_Integer i = 1; i <= aHeaderData->UserInfo().Length(); i++)
145 {
146 const TCollection_AsciiString& aLine = aHeaderData->UserInfo().Value(i);
147
148 if(aLine.Search(REFERENCE_COUNTER) != -1)
149 {
150 theDoc->SetReferenceCounter (aLine.Token(" ", 2).IntegerValue());
151 }
152 else if(aLine.Search(MODIFICATION_COUNTER) != -1)
153 {
154 theDoc->SetModifications (aLine.Token(" ", 2).IntegerValue());
155 }
156 }
7fd59977 157 }
158
159 // 1.a Version of writer
160 if (!aHeaderData->StorageVersion().IsIntegerValue()) {
161 // file has no format version
83ae3591 162 myMsgDriver->Send (aMethStr + "error: file has no format version", Message_Fail);
7fd59977 163 myReaderStatus = PCDM_RS_FormatFailure;
164 return;
165 }
9f45d35b 166 TDocStd_FormatVersion aFileVer = static_cast<TDocStd_FormatVersion>(aHeaderData->StorageVersion().IntegerValue());
167 TDocStd_FormatVersion aCurrVer = TDocStd_Document::CurrentStorageFormatVersion();
7fd59977 168 // maintain one-way compatibility starting from version 2+
d9ff84e8 169 if (!CheckDocumentVersion(aFileVer, aCurrVer)) {
170 myReaderStatus = PCDM_RS_NoVersion;
7fd59977 171 // file was written with another version
83ae3591 172 myMsgDriver->Send (aMethStr + "error: wrong file version: " +
173 aHeaderData->StorageVersion() + " while current is " +
716cf4d9 174 TDocStd_Document::CurrentStorageFormatVersion(), Message_Fail);
7fd59977 175 return;
176 }
177
178 // 1.b Retrieve the Types table
179 TColStd_SequenceOfAsciiString aTypeNames; //Sequence of types in file
180 const TColStd_SequenceOfAsciiString& aUserInfo = aHeaderData->UserInfo();
181 Standard_Boolean begin = Standard_False;
182 Standard_Integer i;
183 for (i=1; i <= aUserInfo.Length(); i++) {
7fd59977 184 TCollection_AsciiString aStr = aUserInfo(i);
185 if (aStr == START_TYPES)
186 begin = Standard_True;
187 else if (aStr == END_TYPES)
188 break;
189 else if (begin) {
14eea829 190 if ( aFileVer < TDocStd_FormatVersion_VERSION_8) {
7fd59977 191#ifdef DATATYPE_MIGRATION
83ae3591 192 TCollection_AsciiString newName;
193 if(Storage_Schema::CheckTypeMigration(aStr, newName)) {
0797d9d3 194#ifdef OCCT_DEBUG
04232180 195 std::cout << "CheckTypeMigration:OldType = " <<aStr << " Len = "<<aStr.Length()<<std::endl;
196 std::cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<std::endl;
7fd59977 197#endif
83ae3591 198 aStr = newName;
199 }
7fd59977 200#endif
201 }
202 aTypeNames.Append (aStr);
203 }
204 }
205 if (myDrivers.IsNull())
206 myDrivers = AttributeDrivers (myMsgDriver);
207 myDrivers->AssignIds (aTypeNames);
208
209 // recognize types not supported by drivers
210 myMapUnsupported.Clear();
211 for (i=1; i <= aTypeNames.Length(); i++)
212 if (myDrivers->GetDriver(i).IsNull())
213 myMapUnsupported.Add(i);
214 if (!myMapUnsupported.IsEmpty()) {
83ae3591 215 myMsgDriver->Send (aMethStr + "warning: "
216 "the following attributes have no driver:", Message_Warning);
7fd59977 217 for (i=1; i <= aTypeNames.Length(); i++)
218 if (myMapUnsupported.Contains(i))
83ae3591 219 myMsgDriver->Send (aTypeNames(i), Message_Warning);
7fd59977 220 }
221
7fd59977 222 // 2. Read document contents
7fd59977 223 // 2a. Retrieve data from the stream:
224 myRelocTable.Clear();
fe21f796 225 myRelocTable.SetHeaderData(aHeaderData);
7fd59977 226 mySections.Clear();
227 myPAtt.Init();
d5c71e20 228 Handle(TDF_Data) aData = (!theFilter.IsNull() && theFilter->IsAppendMode()) ? aDoc->GetData() : new TDF_Data();
04232180 229 std::streampos aDocumentPos = -1;
7fd59977 230
d5c71e20 231 Message_ProgressScope aPS (theRange, "Reading data", 3);
232 Standard_Boolean aQuickPart = IsQuickPart (aFileVer);
6d8f9f4a 233
7fd59977 234 // 2b. Read the TOC of Sections
14eea829 235 if (aFileVer >= TDocStd_FormatVersion_VERSION_3) {
7fd59977 236 BinLDrivers_DocumentSection aSection;
237 do {
b34d86cb 238 BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream, aFileVer);
7fd59977 239 mySections.Append(aSection);
d5c71e20 240 } while (!aSection.Name().IsEqual (aQuickPart ? ENDSECTION_POS : SHAPESECTION_POS) && !theIStream.eof());
5ecc46c0 241
242 if (theIStream.eof()) {
243 // There is no shape section in the file.
83ae3591 244 myMsgDriver->Send (aMethStr + "error: shape section is not found", Message_Fail);
5ecc46c0 245 myReaderStatus = PCDM_RS_ReaderException;
246 return;
247 }
248
4ff92abe 249 aDocumentPos = theIStream.tellg(); // position of root label
7fd59977 250
251 BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
252 for (; anIterS.More(); anIterS.Next()) {
253 BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
254 if (aCurSection.IsPostRead() == Standard_False) {
04232180 255 theIStream.seekg ((std::streampos) aCurSection.Offset());
d5c71e20 256 if (aCurSection.Name().IsEqual (SHAPESECTION_POS))
6d8f9f4a 257 {
7e785937 258 ReadShapeSection (aCurSection, theIStream, false, aPS.Next());
6d8f9f4a 259 if (!aPS.More())
260 {
261 myReaderStatus = PCDM_RS_UserBreak;
262 return;
263 }
6d8f9f4a 264 }
d5c71e20 265 else if (!aCurSection.Name().IsEqual (ENDSECTION_POS))
6d8f9f4a 266 ReadSection (aCurSection, theDoc, theIStream);
7fd59977 267 }
268 }
269 } else { //aFileVer < 3
4ff92abe 270 aDocumentPos = theIStream.tellg(); // position of root label
7fd59977 271
272 // retrieve SHAPESECTION_POS string
273 char aShapeSecLabel[SIZEOFSHAPELABEL + 1];
274 aShapeSecLabel[SIZEOFSHAPELABEL] = 0x00;
4ff92abe 275 theIStream.read ((char*)&aShapeSecLabel, SIZEOFSHAPELABEL);// SHAPESECTION_POS
7fd59977 276 TCollection_AsciiString aShapeLabel(aShapeSecLabel);
277 // detect if a file was written in old fashion (version 2 without shapes)
278 // and if so then skip reading ShapeSection
279 if (aShapeLabel.Length() > 0) {
280 // version 2+(with shapes) and higher goes here
281 if(aShapeLabel.Length() <= 0 || aShapeLabel != SHAPESECTION_POS) {
83ae3591 282 myMsgDriver->Send (aMethStr + "error: Format failure", Message_Fail);
7fd59977 283 myReaderStatus = PCDM_RS_FormatFailure;
284 return;
285 }
286
287 // retrieve ShapeSection Position
288 Standard_Integer aShapeSectionPos; // go to ShapeSection
4ff92abe 289 theIStream.read ((char*)&aShapeSectionPos, sizeof(Standard_Integer));
7fd59977 290
ff1f0c9a 291#ifdef DO_INVERSE
7fd59977 292 aShapeSectionPos = InverseInt (aShapeSectionPos);
293#endif
0797d9d3 294#ifdef OCCT_DEBUG
04232180 295 std::cout <<"aShapeSectionPos = " <<aShapeSectionPos <<std::endl;
7fd59977 296#endif
297 if(aShapeSectionPos) {
83ae3591 298 aDocumentPos = theIStream.tellg();
04232180 299 theIStream.seekg((std::streampos) aShapeSectionPos);
7fd59977 300
83ae3591 301 CheckShapeSection(aShapeSectionPos, theIStream);
302 // Read Shapes
303 BinLDrivers_DocumentSection aCurSection;
7e785937 304 ReadShapeSection (aCurSection, theIStream, Standard_False, aPS.Next());
6d8f9f4a 305 if (!aPS.More())
306 {
307 myReaderStatus = PCDM_RS_UserBreak;
308 return;
309 }
7fd59977 310 }
311 }
312 } // end of reading Sections or shape section
313
314 // Return to read of the Document structure
4ff92abe 315 theIStream.seekg(aDocumentPos);
7fd59977 316
317 // read the header (tag) of the root label
318 Standard_Integer aTag;
4ff92abe 319 theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
7fd59977 320
d5c71e20 321 if (aQuickPart)
322 myPAtt.SetIStream (theIStream); // for reading shapes data from the stream directly
323 EnableQuickPartReading (myMsgDriver, aQuickPart);
324
7fd59977 325 // read sub-tree of the root label
d5c71e20 326 if (!theFilter.IsNull())
327 theFilter->StartIteration();
328 Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), theFilter, aQuickPart, aPS.Next());
6d8f9f4a 329 if (!aPS.More())
330 {
331 myReaderStatus = PCDM_RS_UserBreak;
332 return;
333 }
7e785937 334
bf954475 335 Clear();
6d8f9f4a 336 if (!aPS.More())
337 {
338 myReaderStatus = PCDM_RS_UserBreak;
339 return;
340 }
341 aPS.Next();
7fd59977 342
343 if (nbRead > 0) {
344 // attach data to the document
d5c71e20 345 if (theFilter.IsNull() || !theFilter->IsAppendMode())
346 {
347 aDoc->SetData(aData);
348 TDocStd_Owner::SetDocument(aData, aDoc);
349 aDoc->SetComments(aHeaderData->Comments());
350 }
7fd59977 351 myReaderStatus = PCDM_RS_OK;
352 }
353
354 // Read Sections (post-reading type)
14eea829 355 if (aFileVer >= TDocStd_FormatVersion_VERSION_3) {
4ff92abe 356 BinLDrivers_VectorOfDocumentSection::Iterator aSectIter (mySections);
357 for (; aSectIter.More(); aSectIter.Next()) {
358 BinLDrivers_DocumentSection& aCurSection = aSectIter.ChangeValue();
7fd59977 359 if (aCurSection.IsPostRead()) {
04232180 360 theIStream.seekg ((std::streampos) aCurSection.Offset());
83ae3591 361 ReadSection (aCurSection, theDoc, theIStream);
7fd59977 362 }
363 }
364 }
365}
366
367//=======================================================================
368//function : ReadSubTree
369//purpose :
370//=======================================================================
371
372Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
d5c71e20 373(Standard_IStream& theIS,
374 const TDF_Label& theLabel,
375 const Handle(PCDM_ReaderFilter)& theFilter,
376 const Standard_Boolean& theQuickPart,
377 const Message_ProgressRange& theRange)
7fd59977 378{
379 Standard_Integer nbRead = 0;
b34d86cb 380 TCollection_ExtendedString aMethStr
d5c71e20 381 ("BinLDrivers_DocumentRetrievalDriver: ");
7fd59977 382
7e785937 383 Message_ProgressScope aPS(theRange, "Reading sub tree", 2, true);
6d8f9f4a 384
d5c71e20 385 bool aSkipAttrs = Standard_False;
386 if (!theFilter.IsNull() && theFilter->IsPartTree())
387 aSkipAttrs = !theFilter->IsPassed();
388
389 if (theQuickPart)
390 {
391 uint64_t aLabelSize = 0;
392 theIS.read((char*)&aLabelSize, sizeof(uint64_t));
393#if DO_INVERSE
394 aLabelSize = InverseUint64(aLabelSize);
395#endif
396 // no one sub-label is needed, so, skip everything
397 if (aSkipAttrs && !theFilter->IsSubPassed())
398 {
399 aLabelSize -= sizeof (uint64_t);
400 theIS.seekg (aLabelSize, std::ios_base::cur);
401 if (!theFilter.IsNull())
402 theFilter->Up();
403 return 0;
404 }
405 }
406
7fd59977 407 // Read attributes:
d5c71e20 408 for (theIS >> myPAtt;
409 theIS && myPAtt.TypeId() > 0 && // not an end marker ?
410 myPAtt.Id() > 0 && // not a garbage ?
411 !theIS.eof();
412 theIS >> myPAtt)
6d8f9f4a 413 {
414 if (!aPS.More())
415 {
416 myReaderStatus = PCDM_RS_UserBreak;
417 return -1;
418 }
d5c71e20 419 if (aSkipAttrs)
420 {
421 if (myPAtt.IsDirect()) // skip direct written stream
422 {
423 uint64_t aStreamSize = 0;
424 theIS.read ((char*)&aStreamSize, sizeof (uint64_t));
425 aStreamSize -= sizeof (uint64_t); // size is already passed, so, reduce it by size
426 theIS.seekg (aStreamSize, std::ios_base::cur);
427 }
428 continue;
429 }
430
7fd59977 431 // get a driver according to TypeId
d5c71e20 432 Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver(myPAtt.TypeId());
7fd59977 433 if (!aDriver.IsNull()) {
434 // create transient attribute
7fd59977 435 Standard_Integer anID = myPAtt.Id();
436 Handle(TDF_Attribute) tAtt;
437 Standard_Boolean isBound = myRelocTable.IsBound(anID);
438 if (isBound)
439 tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID));
440 else
441 tAtt = aDriver->NewEmpty();
60fddce4 442
d5c71e20 443 if (!theFilter.IsNull() && !theFilter->IsPassed (tAtt->DynamicType())) {
444 if (myPAtt.IsDirect()) // skip direct written stream
445 {
446 uint64_t aStreamSize = 0;
447 theIS.read ((char*)&aStreamSize, sizeof (uint64_t));
448 aStreamSize -= sizeof (uint64_t); // size is already passed, so, reduce it by size
449 theIS.seekg (aStreamSize, std::ios_base::cur);
450 }
451 continue;
452 }
453 nbRead++;
454
7fd59977 455 if (tAtt->Label().IsNull())
60fddce4 456 {
d5c71e20 457 if (!theFilter.IsNull() && theFilter->Mode() != PCDM_ReaderFilter::AppendMode_Forbid && theLabel.IsAttribute(tAtt->ID()))
458 {
459 if (theFilter->Mode() == PCDM_ReaderFilter::AppendMode_Protect)
460 continue; // do not overwrite the existing attribute
461 if (theFilter->Mode() == PCDM_ReaderFilter::AppendMode_Overwrite)
462 theLabel.ForgetAttribute(tAtt->ID()); // forget old attribute to write a new one
463 }
60fddce4 464 try
465 {
d5c71e20 466 theLabel.AddAttribute(tAtt);
60fddce4 467 }
468 catch (const Standard_DomainError&)
469 {
470 // For attributes that can have arbitrary GUID (e.g. TDataStd_Integer), exception
471 // will be raised in valid case if attribute of that type with default GUID is already
472 // present on the same label; the reason is that actual GUID will be read later.
473 // To avoid this, set invalid (null) GUID to the newly added attribute (see #29669)
474 static const Standard_GUID fbidGuid;
d5c71e20 475 tAtt->SetID(fbidGuid);
476 theLabel.AddAttribute(tAtt);
60fddce4 477 }
478 }
7fd59977 479 else
d5c71e20 480 myMsgDriver->Send(aMethStr +
481 "warning: attempt to attach attribute " +
482 aDriver->TypeName() + " to a second label", Message_Warning);
7fd59977 483
d5c71e20 484 Standard_Boolean ok = aDriver->Paste(myPAtt, tAtt, myRelocTable);
7fd59977 485 if (!ok) {
486 // error converting persistent to transient
d5c71e20 487 myMsgDriver->Send(aMethStr + "warning: failure reading attribute " +
488 aDriver->TypeName(), Message_Warning);
7fd59977 489 }
490 else if (!isBound)
d5c71e20 491 myRelocTable.Bind(anID, tAtt);
7fd59977 492 }
493 else if (!myMapUnsupported.Contains(myPAtt.TypeId()))
d5c71e20 494 myMsgDriver->Send(aMethStr + "warning: type ID not registered in header: "
495 + myPAtt.TypeId(), Message_Warning);
7fd59977 496
7fd59977 497 }
498 if (!theIS || myPAtt.TypeId() != BinLDrivers_ENDATTRLIST) {
499 // unexpected EOF or garbage data
d5c71e20 500 myMsgDriver->Send(aMethStr + "error: unexpected EOF or garbage data", Message_Fail);
7fd59977 501 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
502 return -1;
503 }
504
505 // Read children:
506 // read the tag of a child label
507 Standard_Integer aTag = BinLDrivers_ENDLABEL;
d5c71e20 508 theIS.read((char*)&aTag, sizeof(Standard_Integer));
ff1f0c9a 509#ifdef DO_INVERSE
d5c71e20 510 aTag = InverseInt(aTag);
7fd59977 511#endif
d5c71e20 512
5ecc46c0 513 while (theIS && aTag >= 0 && !theIS.eof()) { // not an end marker ?
7fd59977 514 // create sub-label
d5c71e20 515 TDF_Label aLab = theLabel.FindChild(aTag, Standard_True);
6d8f9f4a 516 if (!aPS.More())
517 {
518 myReaderStatus = PCDM_RS_UserBreak;
519 return -1;
520 }
7fd59977 521
7e785937 522
7fd59977 523 // read sub-tree
d5c71e20 524 if (!theFilter.IsNull())
525 theFilter->Down (aTag);
526 Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, theFilter, theQuickPart, aPS.Next());
7fd59977 527 // check for error
528 if (nbSubRead == -1)
529 return -1;
530 nbRead += nbSubRead;
531
532 // read the tag of the next child
d5c71e20 533 theIS.read((char*)&aTag, sizeof(Standard_Integer));
ff1f0c9a 534#ifdef DO_INVERSE
d5c71e20 535 aTag = InverseInt(aTag);
7fd59977 536#endif
537 }
6d8f9f4a 538
7fd59977 539 if (aTag != BinLDrivers_ENDLABEL) {
540 // invalid end label marker
d5c71e20 541 myMsgDriver->Send(aMethStr + "error: invalid end label marker", Message_Fail);
7fd59977 542 myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
543 return -1;
544 }
d5c71e20 545 if (!theFilter.IsNull())
546 theFilter->Up();
7fd59977 547
548 return nbRead;
549}
550
551//=======================================================================
552//function : AttributeDrivers
553//purpose :
554//=======================================================================
555
556Handle(BinMDF_ADriverTable) BinLDrivers_DocumentRetrievalDriver::AttributeDrivers
83ae3591 557 (const Handle(Message_Messenger)& theMessageDriver)
7fd59977 558{
559 return BinLDrivers::AttributeDrivers (theMessageDriver);
560}
561
7fd59977 562//=======================================================================
563//function : ReadSection
564//purpose :
565//=======================================================================
566
567void BinLDrivers_DocumentRetrievalDriver::ReadSection
568 (BinLDrivers_DocumentSection& /*theSection*/,
569 const Handle(CDM_Document)& /*theDocument*/,
570 Standard_IStream& /*theIS*/)
571{
572 // empty; should be redefined in subclasses
573}
574
575//=======================================================================
576//function : ReadShapeSection
577//purpose :
578//=======================================================================
579
580void BinLDrivers_DocumentRetrievalDriver::ReadShapeSection
581 (BinLDrivers_DocumentSection& theSection,
6d8f9f4a 582 Standard_IStream& /*theIS*/,
583 const Standard_Boolean isMess,
7e785937 584 const Message_ProgressRange &/*theRange*/)
7fd59977 585
586{
587 if(isMess && theSection.Length()) {
588 const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: ");
83ae3591 589 myMsgDriver->Send (aMethStr + "warning: Geometry is not supported by Lite schema. ", Message_Warning);
7fd59977 590 }
591}
592
593//=======================================================================
594//function : CheckShapeSection
595//purpose :
596//=======================================================================
d5c71e20 597void BinLDrivers_DocumentRetrievalDriver::CheckShapeSection
598 (const Storage_Position& ShapeSectionPos, Standard_IStream& IS)
7fd59977 599{
d41f6af3 600 if (!IS.eof())
601 {
d5c71e20 602 const std::streamoff endPos = IS.rdbuf()->pubseekoff (0L, std::ios_base::end, std::ios_base::in);
0797d9d3 603#ifdef OCCT_DEBUG
04232180 604 std::cout << "endPos = " << endPos <<std::endl;
7fd59977 605#endif
606 if(ShapeSectionPos != endPos) {
607 const TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver: ");
83ae3591 608 myMsgDriver->Send (aMethStr + "warning: Geometry is not supported by Lite schema. ", Message_Warning);
7fd59977 609 }
610 }
611}
612
bf954475 613//=======================================================================
614//function : Clear
615//purpose :
616//=======================================================================
617void BinLDrivers_DocumentRetrievalDriver::Clear()
618{
619 myPAtt.Destroy(); // free buffer
620 myRelocTable.Clear();
621 myMapUnsupported.Clear();
622}
623
d9ff84e8 624//=======================================================================
625//function : CheckDocumentVersion
626//purpose :
627//=======================================================================
d5c71e20 628Standard_Boolean BinLDrivers_DocumentRetrievalDriver::CheckDocumentVersion
629 (const Standard_Integer theFileVersion, const Standard_Integer theCurVersion)
d9ff84e8 630{
9f45d35b 631 if (theFileVersion < TDocStd_FormatVersion_LOWER || theFileVersion > theCurVersion) {
d9ff84e8 632 // file was written with another version
633 return Standard_False;
634 }
635 return Standard_True;
636}
d5c71e20 637
638//=======================================================================
639//function : IsQuickPart
640//purpose :
641//=======================================================================
642Standard_Boolean BinLDrivers_DocumentRetrievalDriver::IsQuickPart (const Standard_Integer theFileVer)
643{
644 return theFileVer >= TDocStd_FormatVersion_VERSION_12;
645}