]> OCCT Git - occt.git/commitdiff
0033616: Application Framework - Using filter while reading XBF may result in unresol...
authoranv <anv@opencascade.com>
Thu, 29 Feb 2024 13:50:52 +0000 (13:50 +0000)
committerVadim Glukhikh <vadim.glukhikh@opencascade.com>
Thu, 28 Mar 2024 13:55:46 +0000 (13:55 +0000)
- Added tracking of unresolved links for TreeNodes;
- Test case added.

src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx
tests/bugs/xde/bug33616 [new file with mode: 0644]

index 52a83fe71f99eee03ce7e924844b775d76810e1c..b6e36ed491d39bf50a2bfa432499f33ef822ae75 100644 (file)
@@ -33,6 +33,7 @@
 #include <Storage_Schema.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
+#include <TDataStd_TreeNode.hxx>
 #include <TDF_Attribute.hxx>
 #include <TDF_Data.hxx>
 #include <TDF_Label.hxx>
@@ -324,7 +325,16 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   // read sub-tree of the root label
   if (!theFilter.IsNull())
     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()) 
   {
     myReaderStatus = PCDM_RS_UserBreak;
@@ -373,6 +383,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
   const TDF_Label& theLabel,
   const Handle(PCDM_ReaderFilter)& theFilter,
   const Standard_Boolean& theQuickPart,
+  const Standard_Boolean theReadMissing,
   const Message_ProgressRange& theRange)
 {
   Standard_Integer nbRead = 0;
@@ -393,7 +404,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
     aLabelSize = InverseUint64(aLabelSize);
 #endif
     // no one sub-label is needed, so, skip everything
-    if (aSkipAttrs && !theFilter->IsSubPassed())
+    if (aSkipAttrs && !theFilter->IsSubPassed() && myUnresolvedLinks.IsEmpty())
     {
       aLabelSize -= sizeof (uint64_t);
       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:
   for (theIS >> myPAtt;
     theIS && myPAtt.TypeId() > 0 &&             // not an end marker ?
@@ -415,6 +431,12 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
       myReaderStatus = PCDM_RS_UserBreak;
       return -1;
     }
+    if (myUnresolvedLinks.Remove(myPAtt.Id()) && aSkipAttrs)
+    {
+      aSkipAttrs = Standard_False;
+      theIS.seekg(anAttStartPosition, std::ios_base::beg);
+      continue;
+    }
     if (aSkipAttrs)
     {
       if (myPAtt.IsDirect()) // skip direct written stream
@@ -487,7 +509,17 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
           aDriver->TypeName(), Message_Warning);
       }
       else if (!isBound)
+      {
         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()))
       myMsgDriver->Send(aMethStr + "warning: type ID not registered in header: "
@@ -522,7 +554,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
     // read sub-tree
     if (!theFilter.IsNull())
       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
     if (nbSubRead == -1)
       return -1;
index 03eaaaa7201a2ef8d90f47ab04a4735eb55e6652..fc1652cd496478b894b65d6b96187ad14612bc32 100644 (file)
@@ -80,6 +80,7 @@ protected:
      const TDF_Label& theData, 
      const Handle(PCDM_ReaderFilter)& theFilter,
      const Standard_Boolean& theQuickPart,
+     const Standard_Boolean theReadMissing,
      const Message_ProgressRange& theRanges = Message_ProgressRange());
   
   
@@ -125,6 +126,7 @@ private:
   BinObjMgt_Persistent myPAtt;
   TColStd_MapOfInteger myMapUnsupported;
   BinLDrivers_VectorOfDocumentSection mySections;
+  NCollection_Map<Standard_Integer> myUnresolvedLinks;
 
 
 };
diff --git a/tests/bugs/xde/bug33616 b/tests/bugs/xde/bug33616
new file mode 100644 (file)
index 0000000..a65200a
--- /dev/null
@@ -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