From 12ae1d238e88524d9fea7c299e4c84e1db5b3a62 Mon Sep 17 00:00:00 2001 From: ibs Date: Thu, 3 Dec 2015 14:19:32 +0300 Subject: [PATCH] =?utf8?q?0026981:=20OCAF=20-=20read=20a=20BinOcaf=20docum?= =?utf8?q?ent=20from=20=D0=A1++=20stream=20consequentially?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit read all the sections of BinOcaf document (that has version >= 3) consequentially --- .../BinLDrivers_DocumentRetrievalDriver.cxx | 196 +++++++++++++----- .../BinLDrivers_DocumentRetrievalDriver.hxx | 10 +- src/PCDM/PCDM.cxx | 12 +- src/PCDM/PCDM_ReadWriter.cxx | 16 +- 4 files changed, 172 insertions(+), 62 deletions(-) diff --git a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx index e5cdfd19ce..e6e8be64a1 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx @@ -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 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 ::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 ::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::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 : diff --git a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx index 4b2a11d60e..b8583b35cc 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx +++ b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -83,8 +84,11 @@ protected: //! Read the tree from the stream to - 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 myPAttList; Handle(CDM_MessageDriver) myMsgDriver; TColStd_MapOfInteger myMapUnsupported; BinLDrivers_VectorOfDocumentSection mySections; diff --git a/src/PCDM/PCDM.cxx b/src/PCDM/PCDM.cxx index 5c36817e33..0553bc5e00 100644 --- a/src/PCDM/PCDM.cxx +++ b/src/PCDM/PCDM.cxx @@ -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()) diff --git a/src/PCDM/PCDM_ReadWriter.cxx b/src/PCDM/PCDM_ReadWriter.cxx index b42b8a83a8..bf10730fa0 100644 --- a/src/PCDM/PCDM_ReadWriter.cxx +++ b/src/PCDM/PCDM_ReadWriter.cxx @@ -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++) -- 2.39.5