]> OCCT Git - occt-copy.git/commitdiff
0026981: OCAF - read a BinOcaf document from ะก++ stream consequentially CR26981
authoribs <ibs@opencascade.com>
Thu, 3 Dec 2015 11:19:32 +0000 (14:19 +0300)
committeribs <ibs@opencascade.com>
Mon, 14 Dec 2015 07:55:17 +0000 (10:55 +0300)
read all the sections of BinOcaf document (that has version >= 3) consequentially

src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx
src/PCDM/PCDM.cxx
src/PCDM/PCDM_ReadWriter.cxx

index e5cdfd19ce2f61f0f0730d81b86dfe40f440f1b9..e6e8be64a1f8bf85765cdd32dab99bcf06f5e10a 100644 (file)
@@ -244,30 +244,42 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
   // 2a. Retrieve data from the stream:
   myRelocTable.Clear();
   mySections.Clear();
-  myPAtt.Init();
   Handle(TDF_Data) aData = new TDF_Data();
   streampos aDocumentPos = -1;
+  Standard_Integer nbRead = -1;
 
   // 2b. Read the TOC of Sections
   if (aFileVer >= 3) {
     BinLDrivers_DocumentSection aSection;
-    do {
+    NCollection_Sequence <BinLDrivers_DocumentSection> aSectionSeq;
+    do
+    {
       BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream);
-      mySections.Append(aSection);
-    } while
-      (!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS));
-    aDocumentPos = theIStream.tellg(); // position of root label
+      if (aSectionSeq.IsEmpty())
+      {
+        aSectionSeq.Append(aSection);
+      }
+      else
+      {
+        NCollection_Sequence <BinLDrivers_DocumentSection>::Iterator anIterS (aSectionSeq);
+        for (; anIterS.More(); anIterS.Next())
+        {
+          BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
+
+          if (aCurSection.Offset() > aSection.Offset())
+          {
+            anIterS.Previous(); // do one step back to get the possibility to do correct insertion
+            aSectionSeq.InsertAfter (anIterS, aSection);
+            break;
+          }
+        }
+      }
+    } while (!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS));
 
-    BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
+    NCollection_Sequence <BinLDrivers_DocumentSection>::Iterator anIterS (aSectionSeq);
     for (; anIterS.More(); anIterS.Next()) {
       BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue();
-      if (aCurSection.IsPostRead() == Standard_False) {
-        theIStream.seekg ((streampos) aCurSection.Offset());
-        if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS)) 
-          ReadShapeSection (aCurSection, theIStream);
-        else
-          ReadSection (aCurSection, theDoc, theIStream); 
-      }
+      mySections.Append(aCurSection); // fill mySection
     }
   } else { //aFileVer < 3
     aDocumentPos = theIStream.tellg(); // position of root label
@@ -307,20 +319,42 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
        ReadShapeSection (aCurSection, theIStream, Standard_False);
       }
     }
-  } // end of reading Sections or shape section
 
-  // Return to read of the Document structure
-  theIStream.seekg(aDocumentPos);
+    // Return to read of the Document structure
+    theIStream.seekg(aDocumentPos);
+
+  } // end of reading Sections or shape section
 
   // read the header (tag) of the root label
   Standard_Integer aTag;
   theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
 
   // read sub-tree of the root label
-  Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root());
-  myPAtt.Destroy();    // free buffer
-  myRelocTable.Clear();
-  myMapUnsupported.Clear();
+  if (aFileVer >= 3)
+  {
+    nbRead = ReadSubTree (theIStream, aData->Root(), Standard_True);
+
+    BinLDrivers_VectorOfDocumentSection::Iterator aSectIter (mySections);
+    for (; aSectIter.More(); aSectIter.Next())
+    {
+      BinLDrivers_DocumentSection& aCurSection = aSectIter.ChangeValue();
+      if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS))
+      {
+        ReadShapeSection (aCurSection, theIStream);
+      }
+      else
+      {
+        ReadSection (aCurSection, theDoc, theIStream);
+      }
+    }
+
+    UpdateTree();
+  }
+  else
+  {
+    // read sub-tree of the root label
+    nbRead = ReadSubTree (theIStream, aData->Root());
+  }
     
   if (nbRead > 0) {
     // attach data to the document
@@ -330,17 +364,9 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
     myReaderStatus = PCDM_RS_OK;
   }
 
-  // Read Sections (post-reading type)
-  if (aFileVer >= 3) {
-    BinLDrivers_VectorOfDocumentSection::Iterator aSectIter (mySections);
-    for (; aSectIter.More(); aSectIter.Next()) {
-      BinLDrivers_DocumentSection& aCurSection = aSectIter.ChangeValue();
-      if (aCurSection.IsPostRead()) {
-       theIStream.seekg ((streampos) aCurSection.Offset());
-       ReadSection (aCurSection, theDoc, theIStream); 
-      }
-    }
-  }
+  myPAttList.Clear();
+  myRelocTable.Clear();
+  myMapUnsupported.Clear();
 }
 
 //=======================================================================
@@ -350,28 +376,39 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
 
 Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
                          (Standard_IStream& theIS,
-                          const TDF_Label&  theLabel)
+                          const TDF_Label&  theLabel,
+                          const Standard_Boolean theReadOnly)
 {
   Standard_Integer nbRead = 0;
   static TCollection_ExtendedString aMethStr
     ("BinLDrivers_DocumentRetrievalDriver: ");
 
   // Read attributes:
-  theIS >> myPAtt;
-  while (theIS && myPAtt.TypeId() > 0 &&             // not an end marker ?
-         myPAtt.Id() > 0) {                          // not a garbage ?
+  myPAttList.Prepend(new BinObjMgt_Persistent());
+
+  BinObjMgt_Persistent* myPAtt = myPAttList.First();
+  theIS >> *myPAtt;
+
+  while (theIS && myPAtt->TypeId() > 0 &&             // not an end marker ?
+         myPAtt->Id() > 0) {                          // not a garbage ?
     // get a driver according to TypeId
-    Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt.TypeId());
+    Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (myPAtt->TypeId());
     if (!aDriver.IsNull()) {
       // create transient attribute
       nbRead++;
-      Standard_Integer anID = myPAtt.Id();
+      Standard_Integer anID = myPAtt->Id();
       Handle(TDF_Attribute) tAtt;
       Standard_Boolean isBound = myRelocTable.IsBound(anID);
       if (isBound)
         tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID));
       else
+      {
         tAtt = aDriver->NewEmpty();
+        if (theReadOnly)
+        {
+          myRelocTable.Bind (anID, tAtt);
+        }
+      }
       if (tAtt->Label().IsNull())
        theLabel.AddAttribute (tAtt);
       else
@@ -379,29 +416,51 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
                      "warning: attempt to attach attribute " +
                      aDriver->TypeName() + " to a second label");
 
-      Standard_Boolean ok = aDriver->Paste (myPAtt, tAtt, myRelocTable);
-      if (!ok) {
-        // error converting persistent to transient
-        WriteMessage (aMethStr + "warning: failure reading attribute " +
-                      aDriver->TypeName());
+      if (!theReadOnly)
+      {
+        Standard_Boolean ok = aDriver->Paste (*myPAtt, tAtt, myRelocTable);
+        if (!ok) {
+          // error converting persistent to transient
+          WriteMessage (aMethStr + "warning: failure reading attribute " +
+            aDriver->TypeName());
+        }
+        else if (!isBound)
+          myRelocTable.Bind (anID, tAtt);
       }
-      else if (!isBound)
-        myRelocTable.Bind (anID, tAtt);
     }
-    else if (!myMapUnsupported.Contains(myPAtt.TypeId()))
+    else if (!myMapUnsupported.Contains(myPAtt->TypeId()))
       WriteMessage (aMethStr + "warning: type ID not registered in header: "
-                    + myPAtt.TypeId());
+                    + myPAtt->TypeId());
 
     // read next attribute
-    theIS >> myPAtt;
+    if (theReadOnly)
+    {
+      myPAttList.Prepend(new BinObjMgt_Persistent());
+      myPAtt = myPAttList.First();
+    }
+
+    theIS >> *myPAtt;
   }
-  if (!theIS || myPAtt.TypeId() != BinLDrivers_ENDATTRLIST) {
+  if (!theIS || myPAtt->TypeId() != BinLDrivers_ENDATTRLIST) {
+    if (theReadOnly)
+    {
+      delete myPAttList.First();
+      myPAttList.RemoveFirst();
+    }
+    
     // unexpected EOF or garbage data
     WriteMessage (aMethStr + "error: unexpected EOF or garbage data");
     myReaderStatus = PCDM_RS_UnrecognizedFileFormat;
     return -1;
   }
 
+  if (theReadOnly)
+  {
+    // remove last added dummy element (at first position)
+    delete myPAttList.First();
+    myPAttList.RemoveFirst();
+  }
+
   // Read children:
   // read the tag of a child label
   Standard_Integer aTag = BinLDrivers_ENDLABEL;
@@ -414,7 +473,7 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
     TDF_Label aLab = theLabel.FindChild (aTag, Standard_True);
 
     // read sub-tree
-    Standard_Integer nbSubRead = ReadSubTree(theIS, aLab);
+    Standard_Integer nbSubRead = ReadSubTree(theIS, aLab, theReadOnly);
     // check for error
     if (nbSubRead == -1)
       return -1;
@@ -436,6 +495,43 @@ Standard_Integer BinLDrivers_DocumentRetrievalDriver::ReadSubTree
   return nbRead;
 }
 
+//=======================================================================
+//function : UpdateTree
+//purpose  :
+//=======================================================================
+void BinLDrivers_DocumentRetrievalDriver::UpdateTree()
+{
+  static TCollection_ExtendedString aMethStr ("BinLDrivers_DocumentRetrievalDriver::UpdateTree: ");
+
+  NCollection_List<BinObjMgt_Persistent*>::Iterator anAttIter (myPAttList);
+  for (; anAttIter.More(); anAttIter.Next())
+  {
+    BinObjMgt_Persistent* aCurPatt = anAttIter.Value();
+
+    // get a driver according to TypeId
+    Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver (aCurPatt->TypeId());
+
+    if (!aDriver.IsNull())
+    {
+      // create transient attribute
+      Standard_Integer anID = aCurPatt->Id();
+      Handle(TDF_Attribute) tAtt = Handle(TDF_Attribute)::DownCast(myRelocTable.Find(anID));
+
+      if (!aDriver->Paste (*aCurPatt, tAtt, myRelocTable))
+      {
+        // error converting persistent to transient
+        WriteMessage (aMethStr + "warning: failure reading attribute " + aDriver->TypeName());
+      }
+    }
+    else if (!myMapUnsupported.Contains(aCurPatt->TypeId()))
+    {
+      WriteMessage (aMethStr + "warning: type ID not registered in header: " + aCurPatt->TypeId());
+    }
+
+    delete aCurPatt;
+  }
+}
+
 //=======================================================================
 //function : AttributeDrivers
 //purpose  :
index 4b2a11d60e540fc4768ad013bb3df2084a6da802..b8583b35cc8416321c928cbabf9e7fc9907508fa 100644 (file)
@@ -23,6 +23,7 @@
 #include <BinObjMgt_RRelocationTable.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <BinLDrivers_VectorOfDocumentSection.hxx>
+#include <NCollection_List.hxx>
 #include <PCDM_RetrievalDriver.hxx>
 #include <Standard_Integer.hxx>
 #include <Standard_IStream.hxx>
@@ -83,8 +84,11 @@ protected:
 
   
   //! Read the tree from the stream <theIS> to <theLabel>
-  Standard_EXPORT virtual Standard_Integer ReadSubTree (Standard_IStream& theIS, const TDF_Label& theData);
-  
+  Standard_EXPORT virtual Standard_Integer ReadSubTree (Standard_IStream& theIS, const TDF_Label& theData, const Standard_Boolean theReadOnly = Standard_False);
+  // Translate of each label of prepared tree by OnlyReadSubTree method 
+  // from persistent being to transient one
+  Standard_EXPORT virtual void UpdateTree();
   
   //! define the procedure of reading a section to file.
   Standard_EXPORT virtual void ReadSection (BinLDrivers_DocumentSection& theSection, const Handle(CDM_Document)& theDoc, Standard_IStream& theIS);
@@ -113,7 +117,7 @@ protected:
 private:
 
 
-  BinObjMgt_Persistent myPAtt;
+  NCollection_List<BinObjMgt_Persistent*> myPAttList;
   Handle(CDM_MessageDriver) myMsgDriver;
   TColStd_MapOfInteger myMapUnsupported;
   BinLDrivers_VectorOfDocumentSection mySections;
index 5c36817e33d0294247a1976ac63f0cc4b50ceba3..0553bc5e00049c98c6afa7415c5f60f6791a10b2 100644 (file)
@@ -120,12 +120,16 @@ PCDM_TypeOfFileDriver PCDM::FileDriverType (Standard_IStream& theIStream, PCDM_B
     // read magic number from the file
     aReadMagicNumber = Storage_BaseDriver::ReadMagicNumber (theIStream);
 
-    if (!theIStream.good())
+    // don not seek for FSD_BinaryFile
+    if (aReadMagicNumber != FSD_BinaryFile::MagicNumber())
     {
-      theIStream.clear();
-    }
+      if (!theIStream.good())
+      {
+        theIStream.clear();
+      }
 
-    theIStream.seekg(aDocumentPos);
+      theIStream.seekg(aDocumentPos);
+    }
   }
 
   if(aReadMagicNumber == FSD_CmpFile::MagicNumber())
index b42b8a83a8a5fab800198fb339fe0b0716e3abfa..bf10730fa02a284693d53cc282943fc4033dade5 100644 (file)
@@ -163,16 +163,22 @@ TCollection_ExtendedString PCDM_ReadWriter::FileFormat (Standard_IStream& theISt
   TCollection_ExtendedString aFormat;
 
   Storage_BaseDriver* aFileDriver;
-  if (PCDM::FileDriverType (theIStream, aFileDriver) == PCDM_TOFD_Unknown)
+
+  PCDM_TypeOfFileDriver aFileDriverType = PCDM::FileDriverType (theIStream, aFileDriver);
+  if (aFileDriverType == PCDM_TOFD_Unknown)
   {
     return ::TryXmlDriverType (theIStream);
   }
   
   // the stream starts with a magic number, FileDriverType has read
-  // them already but returned the stream pos to initial state,
-  // thus we should read them before reading of info section
-  aFileDriver->ReadMagicNumber(theIStream);
-
+  // them already but returned the stream pos to initial state
+  // (except FSD_BinaryFile), thus we should read them before
+  // reading of info section
+  if (aFileDriverType != PCDM_TOFD_CmpFile)
+  {
+    aFileDriver->ReadMagicNumber(theIStream);
+  }
+  
   aFileDriver->ReadCompleteInfo (theIStream, theData);
 
   for (Standard_Integer i = 1; i <= theData->HeaderData()->UserInfo().Length(); i++)