1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00

0033616: Application Framework - Using filter while reading XBF may result in unresolved links

- Added tracking of unresolved links for TreeNodes;
- Test case added.
This commit is contained in:
anv 2024-03-08 16:55:07 +00:00 committed by oan
parent 526c883afe
commit 91a32b3f31
3 changed files with 48 additions and 3 deletions

View File

@ -33,6 +33,7 @@
#include <Storage_Schema.hxx> #include <Storage_Schema.hxx>
#include <TCollection_AsciiString.hxx> #include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx> #include <TCollection_ExtendedString.hxx>
#include <TDataStd_TreeNode.hxx>
#include <TDF_Attribute.hxx> #include <TDF_Attribute.hxx>
#include <TDF_Data.hxx> #include <TDF_Data.hxx>
#include <TDF_Label.hxx> #include <TDF_Label.hxx>
@ -324,7 +325,16 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
// read sub-tree of the root label // read sub-tree of the root label
if (!theFilter.IsNull()) if (!theFilter.IsNull())
theFilter->StartIteration(); theFilter->StartIteration();
Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), theFilter, aQuickPart, aPS.Next()); const auto aStreamStartPosition = theIStream.tellg();
Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root(), theFilter, aQuickPart, Standard_False, aPS.Next());
if (!myUnresolvedLinks.IsEmpty())
{
// In case we have skipped some linked TreeNodes before getting to
// their children.
theFilter->StartIteration();
theIStream.seekg(aStreamStartPosition, std::ios_base::beg);
nbRead += ReadSubTree(theIStream, aData->Root(), theFilter, aQuickPart, Standard_True, aPS.Next());
}
if (!aPS.More()) if (!aPS.More())
{ {
myReaderStatus = PCDM_RS_UserBreak; myReaderStatus = PCDM_RS_UserBreak;
@ -373,6 +383,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
const TDF_Label& theLabel, const TDF_Label& theLabel,
const Handle(PCDM_ReaderFilter)& theFilter, const Handle(PCDM_ReaderFilter)& theFilter,
const Standard_Boolean& theQuickPart, const Standard_Boolean& theQuickPart,
const Standard_Boolean theReadMissing,
const Message_ProgressRange& theRange) const Message_ProgressRange& theRange)
{ {
Standard_Integer nbRead = 0; Standard_Integer nbRead = 0;
@ -393,7 +404,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
aLabelSize = InverseUint64(aLabelSize); aLabelSize = InverseUint64(aLabelSize);
#endif #endif
// no one sub-label is needed, so, skip everything // no one sub-label is needed, so, skip everything
if (aSkipAttrs && !theFilter->IsSubPassed()) if (aSkipAttrs && !theFilter->IsSubPassed() && myUnresolvedLinks.IsEmpty())
{ {
aLabelSize -= sizeof (uint64_t); aLabelSize -= sizeof (uint64_t);
theIS.seekg (aLabelSize, std::ios_base::cur); theIS.seekg (aLabelSize, std::ios_base::cur);
@ -403,6 +414,11 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
} }
} }
if (theReadMissing)
{
aSkipAttrs = Standard_True;
}
const auto anAttStartPosition = theIS.tellg();
// Read attributes: // Read attributes:
for (theIS >> myPAtt; for (theIS >> myPAtt;
theIS && myPAtt.TypeId() > 0 && // not an end marker ? theIS && myPAtt.TypeId() > 0 && // not an end marker ?
@ -415,6 +431,12 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
myReaderStatus = PCDM_RS_UserBreak; myReaderStatus = PCDM_RS_UserBreak;
return -1; return -1;
} }
if (myUnresolvedLinks.Remove(myPAtt.Id()) && aSkipAttrs)
{
aSkipAttrs = Standard_False;
theIS.seekg(anAttStartPosition, std::ios_base::beg);
continue;
}
if (aSkipAttrs) if (aSkipAttrs)
{ {
if (myPAtt.IsDirect()) // skip direct written stream if (myPAtt.IsDirect()) // skip direct written stream
@ -487,7 +509,17 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
aDriver->TypeName(), Message_Warning); aDriver->TypeName(), Message_Warning);
} }
else if (!isBound) else if (!isBound)
{
myRelocTable.Bind(anID, tAtt); myRelocTable.Bind(anID, tAtt);
Handle(TDataStd_TreeNode) aNode = Handle(TDataStd_TreeNode)::DownCast(tAtt);
if (!theFilter.IsNull() && !aNode.IsNull() && !aNode->Father().IsNull() && aNode->Father()->IsNew())
{
Standard_Integer anUnresolvedLink;
myPAtt.SetPosition(BP_HEADSIZE);
myPAtt >> anUnresolvedLink;
myUnresolvedLinks.Add(anUnresolvedLink);
}
}
} }
else if (!myMapUnsupported.Contains(myPAtt.TypeId())) else if (!myMapUnsupported.Contains(myPAtt.TypeId()))
myMsgDriver->Send(aMethStr + "warning: type ID not registered in header: " myMsgDriver->Send(aMethStr + "warning: type ID not registered in header: "
@ -522,7 +554,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
// read sub-tree // read sub-tree
if (!theFilter.IsNull()) if (!theFilter.IsNull())
theFilter->Down (aTag); theFilter->Down (aTag);
Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, theFilter, theQuickPart, aPS.Next()); Standard_Integer nbSubRead = ReadSubTree (theIS, aLab, theFilter, theQuickPart, theReadMissing, aPS.Next());
// check for error // check for error
if (nbSubRead == -1) if (nbSubRead == -1)
return -1; return -1;

View File

@ -80,6 +80,7 @@ protected:
const TDF_Label& theData, const TDF_Label& theData,
const Handle(PCDM_ReaderFilter)& theFilter, const Handle(PCDM_ReaderFilter)& theFilter,
const Standard_Boolean& theQuickPart, const Standard_Boolean& theQuickPart,
const Standard_Boolean theReadMissing,
const Message_ProgressRange& theRanges = Message_ProgressRange()); const Message_ProgressRange& theRanges = Message_ProgressRange());
@ -125,6 +126,7 @@ private:
BinObjMgt_Persistent myPAtt; BinObjMgt_Persistent myPAtt;
TColStd_MapOfInteger myMapUnsupported; TColStd_MapOfInteger myMapUnsupported;
BinLDrivers_VectorOfDocumentSection mySections; BinLDrivers_VectorOfDocumentSection mySections;
NCollection_Map<Standard_Integer> myUnresolvedLinks;
}; };

11
tests/bugs/xde/bug33616 Normal file
View File

@ -0,0 +1,11 @@
puts "========"
puts "0033616: Data Exchange - Using filter while reading XBF may result in unresolved links"
puts "========"
pload ALL
XOpen [locate_data_file bug28905_as1-oc-214.xbf] D -read0:1:1:2:1
XGetShape sh D 0:1:1:2:1
checknbshapes sh -solid 1
Close D