]> OCCT Git - occt.git/commitdiff
0029217: Application Framework - nonsense API method XmlLDrivers::SetStorageVersion()
authorvro <vro@opencascade.com>
Wed, 2 Dec 2020 06:38:28 +0000 (09:38 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 3 Dec 2020 15:51:08 +0000 (18:51 +0300)
1. Unification of usage of a storage version of an OCAF document by XML and binary file formats.
2. A new format version enumeration in TDocStd package: TDocStd_FormatVersion.
3. Removal of unnecessary methods for storage version like XmlLDrivers::StorageVersion() and BinLDrivers::StorageVersion().
4. Support of old documents (storage version <= 9) in binary file format (came from ESA).

New files:
- TDocStd_FormatVersion.hxx: a new storage format version enumeration for an OCAF document.

Modified files:
- CDM_Document.hxx and cxx: removal of storage format version property (moved to TDocStd_Document).
- TDocStd_Document.hxx and cxx: a storage format version property (moved from CDM_Document).
- BinLDrivers_DocumentSection.hxx and cxx: support of old document storage version in binary file format.
- BinDrivers_DocumentStorageDriver.hxx and cxx,
- BinLDrivers_DocumentStorageDriver.hxx and cxx,
- BinLDrivers_DocumentRetrievalDriver.cxx,
- XmlLDrivers_DocumentRetrievalDriver.cxx,
- XmlLDrivers_DocumentStorageDriver.cxx: usage of document storage version from TDocStd_Document in storage and retrieval drivers.
- DDocStd_ApplicationCommands.cxx: draw-command name StorageVersion is replaced by StorageFormatVersion (to be the same everywhere). A corresponding script is corrected too.

New test:
- bugs caf bug29217: a test case for old document storage version in binary file format. It checks several attributes saved by the version TDocStd_FormatVersion_VERSION_7 (old) and the latest version.

Modified test:
- caf presentation M1: the test used a file in the current folder, not in {imagedir} like all other tests.
- bugs caf bug28691

Documentation:
- dox/upgrade/upgrade.md

// All remarks are fixed.

26 files changed:
dox/upgrade/upgrade.md
src/BinDrivers/BinDrivers.cxx
src/BinDrivers/BinDrivers.hxx
src/BinDrivers/BinDrivers_DocumentStorageDriver.cxx
src/BinDrivers/BinDrivers_DocumentStorageDriver.hxx
src/BinLDrivers/BinLDrivers.cxx
src/BinLDrivers/BinLDrivers.hxx
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentSection.cxx
src/BinLDrivers/BinLDrivers_DocumentSection.hxx
src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentStorageDriver.hxx
src/CDM/CDM_Document.cxx
src/CDM/CDM_Document.hxx
src/DDocStd/DDocStd_ApplicationCommands.cxx
src/TDocStd/FILES
src/TDocStd/TDocStd_Document.cxx
src/TDocStd/TDocStd_Document.hxx
src/TDocStd/TDocStd_FormatVersion.hxx [new file with mode: 0644]
src/XmlLDrivers/XmlLDrivers.cxx
src/XmlLDrivers/XmlLDrivers.hxx
src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx
src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx
tests/bugs/caf/bug28691
tests/bugs/caf/bug29217 [new file with mode: 0644]
tests/caf/presentation/M1

index 7a8e804c2e9c34d6e421ff41615ebd88d804db63..80b8cbc9a69fdd7bc1b6ebe9aa388f28d240653d 100644 (file)
@@ -2177,3 +2177,15 @@ For example:
 gives different result.
 In current version ST1 - surface trimmed only along V, U trim is removed;
 After modification ST1 - surface trimmed along U and V, U trim is kept.
+
+@subsection upgrade_760_storageformatversion Storage format version of OCAF document
+
+The methods *XmlLDrivers::StorageVersion()* and *BinLDrivers::StorageVersion()* were removed.
+Since now *TDocStd_Document* manupulates the storage format version of a document for both XML and binary file formats.
+For this the methods *StorageFormatVersion()* and *ChangeStorageFormatVersion()* were moved from *CDM_Document* to *TDocStd_Document*.
+The methods are used to get and set the storage format version of a document.
+A new enumeration *TDocStd_FormatVersion* lists the storage format versions of a document. By default, the document uses the latest (current) storage format version.
+In order to save a document in an older storage format version, call the method *ChangeStorageFormatVersion()* with one of the values from the enumeration.
+This value will be used by storage drivers of a corresponding OCAF file format (XML or binary) and the document will be saved
+following the rules of the specified storage format version (corresponding to an older version of Open CASCADE Technology).
+This way an application based on an old version of Open CASCADE Technology may read documents saved by new applications (based on newer version of Open CASCADE Technology).
index 59a5a15920abeedda6bb91a2f391f1152bd7cc54..1ea43b93f094c44d1e4ac995502658501f6a9aad 100644 (file)
@@ -95,14 +95,4 @@ Handle(BinMDF_ADriverTable) BinDrivers::AttributeDrivers
   return aTable;
 }
 
-//=======================================================================
-//function : StorageVersion
-//purpose  : 
-//=======================================================================
-
-TCollection_AsciiString BinDrivers::StorageVersion()
-{
-  return BinLDrivers::StorageVersion();
-}
-
 PLUGIN(BinDrivers)
index fc749052765c873b1361c7bb549917d4eb835b29..79413b560df79acfd55b8d8dd632ef38ed131a98 100644 (file)
@@ -38,9 +38,6 @@ public:
 
   //! Creates the table of drivers of types supported
   Standard_EXPORT static Handle(BinMDF_ADriverTable) AttributeDrivers (const Handle(Message_Messenger)& MsgDrv);
-  
-  //! returns "1"
-  Standard_EXPORT static TCollection_AsciiString StorageVersion();
 };
 
 #endif // _BinDrivers_HeaderFile
index 9d19ce66dcc21f030db2554b2aa161cdc33e42e7..fda11dfff19c42e8f16849204961ff675c83fb0a 100644 (file)
@@ -100,6 +100,7 @@ void BinDrivers_DocumentStorageDriver::SetWithTriangles (const Handle(Message_Me
 void BinDrivers_DocumentStorageDriver::WriteShapeSection
                                (BinLDrivers_DocumentSection&   theSection,
                                 Standard_OStream&              theOS,
+                                const Standard_Integer         theDocVer,
                                 const Message_ProgressRange&   theRange)
 {
   const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
@@ -120,5 +121,5 @@ void BinDrivers_DocumentStorageDriver::WriteShapeSection
   }
    
   // Write the section info in the TOC.
-  theSection.Write (theOS, aShapesSectionOffset);
+  theSection.Write (theOS, aShapesSectionOffset, theDocVer);
 }
index f75067af7ab7128b911e2f6e9ff4e9ebf06b86d7..b230145680d0558db303d53217c6eaca222eabc0 100644 (file)
@@ -46,6 +46,7 @@ public:
   Standard_EXPORT virtual void WriteShapeSection
     (BinLDrivers_DocumentSection& theDocSection, 
      Standard_OStream& theOS, 
+     const Standard_Integer theDocVer,
      const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
 
   //! Return true if shape should be stored with triangles.
index 1d6774271fdafe893e1e2ae77161edb7e8c33142..63c5b5dfac3cf91e000f37d8f55825d4f5bc5f83 100644 (file)
@@ -33,7 +33,6 @@
 //#include <BinMNaming.hxx>
 static Standard_GUID BinLStorageDriver  ("13a56835-8269-11d5-aab2-0050044b1af1");
 static Standard_GUID BinLRetrievalDriver("13a56836-8269-11d5-aab2-0050044b1af1");
-#define CURRENT_DOCUMENT_VERSION 10
 
 //=======================================================================
 //function : Factory
@@ -93,15 +92,4 @@ Handle(BinMDF_ADriverTable) BinLDrivers::AttributeDrivers
   return aTable;
 }
 
-//=======================================================================
-//function : StorageVersion
-//purpose  : 
-//=======================================================================
-
-TCollection_AsciiString BinLDrivers::StorageVersion()
-{
-  TCollection_AsciiString aVersionStr (CURRENT_DOCUMENT_VERSION);
-  return aVersionStr;
-}
-
 PLUGIN(BinLDrivers)
index 839745981786191b72d1118df40939a4a978565e..0a0251ba60945b3350d21c95cb671a8ba796e7c4 100644 (file)
@@ -40,9 +40,6 @@ public:
 
   //! Creates a table of the supported drivers' types
   Standard_EXPORT static Handle(BinMDF_ADriverTable) AttributeDrivers (const Handle(Message_Messenger)& MsgDrv);
-  
-  //! returns last storage version
-  Standard_EXPORT static TCollection_AsciiString StorageVersion();
 };
 
 #endif // _BinLDrivers_HeaderFile
index ad2e6ff3bf485a640f0fda7ded5eb00cb6ea4c0c..c8c26991c19b8b33d0e5d9d6964971143827e4d0 100644 (file)
@@ -168,14 +168,14 @@ void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream&
     return;
   }
   Standard_Integer aFileVer = aHeaderData->StorageVersion().IntegerValue();
-  Standard_Integer aCurrVer = BinLDrivers::StorageVersion().IntegerValue();
+  Standard_Integer aCurrVer = TDocStd_Document::CurrentStorageFormatVersion();
   // maintain one-way compatibility starting from version 2+
   if (!CheckDocumentVersion(aFileVer, aCurrVer)) {
     myReaderStatus = PCDM_RS_NoVersion;
     // file was written with another version
     myMsgDriver->Send (aMethStr + "error: wrong file version: " +
                  aHeaderData->StorageVersion() + " while current is " +
-                 BinLDrivers::StorageVersion(), Message_Fail);
+                 TDocStd_Document::CurrentStorageFormatVersion(), Message_Fail);
     return;
   }
 
index e3a7c90dcfca058a4eef335af744f60224f919f4..b51ba2fa7d457f6fe065e422c9028d34afb85dac 100644 (file)
@@ -14,6 +14,7 @@
 // commercial license or contractual agreement.
 
 #include <BinLDrivers_DocumentSection.hxx>
+#include <TDocStd_FormatVersion.hxx>
 #include <FSD_FileHeader.hxx>
 #include <BinMDataStd.hxx>
 
@@ -109,7 +110,8 @@ void BinLDrivers_DocumentSection::SetLength (const uint64_t theLength)
 //purpose  : 
 //=======================================================================
 
-void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream)
+void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream,
+                                            const Standard_Integer theDocFormatVersion)
 {
   char aBuf[512];
 
@@ -147,7 +149,14 @@ void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream)
     aBufSz[0] = 0;
     aBufSz[1] = 0;
     aBufSz[2] = 0;
-    theStream.write (&aBuf[0], 3*sizeof(uint64_t));
+    if (theDocFormatVersion <= TDocStd_FormatVersion_VERSION_9)
+    {
+      theStream.write(&aBuf[0], 3*sizeof(Standard_Integer));
+    }
+    else
+    {
+      theStream.write(&aBuf[0], 3*sizeof(uint64_t));
+    }
   }
 }
 
@@ -157,24 +166,47 @@ void BinLDrivers_DocumentSection::WriteTOC (Standard_OStream& theStream)
 //=======================================================================
 
 void BinLDrivers_DocumentSection::Write (Standard_OStream&   theStream,
-                                         const uint64_t theOffset)
+                                         const uint64_t theOffset,
+                                         const Standard_Integer theDocFormatVersion)
 {
   const uint64_t aSectionEnd = (uint64_t) theStream.tellp();
   theStream.seekp((std::streamsize)myValue[0]);
   myValue[0] = theOffset;
   myValue[1] = aSectionEnd - theOffset;
-  uint64_t aVal[3] = {
-    myValue[0],
-    myValue[1],
-    uint64_t(myIsPostRead ? 1 : 0)
-  };
+  if (theDocFormatVersion <= TDocStd_FormatVersion_VERSION_9)
+  {
+    // Check the limits for a 4-bytes integer.
+    if (myValue[0] > INT_MAX || myValue[1] > INT_MAX)
+      throw Standard_OutOfRange("BinLDrivers_DocumentSection::Write : file size is too big, needs int64.");
+
+    // Old documents stored file position as 4-bytes values.
+    int32_t aValInt[3] = {
+      int32_t(myValue[0]),
+      int32_t(myValue[1]),
+      int32_t(myIsPostRead ? 1 : 0)
+    };
 #if DO_INVERSE
-  aVal[0] = InverseUint64(aVal[0]);
-  aVal[1] = InverseUint64(aVal[1]);
-  aVal[2] = InverseUint64(aVal[2]);
+    aValInt[0] = InverseInt(aValInt[0]);
+    aValInt[1] = InverseInt(aValInt[1]);
+    aValInt[2] = InverseInt(aValInt[2]);
 #endif
+    theStream.write((char *)&aValInt[0], 3*sizeof(int32_t));
+  }
+  else
+  {
+    uint64_t aVal[3] = {
+      myValue[0],
+      myValue[1],
+      uint64_t(myIsPostRead ? 1 : 0)
+    };
+#if DO_INVERSE
+    aVal[0] = InverseUint64(aVal[0]);
+    aVal[1] = InverseUint64(aVal[1]);
+    aVal[2] = InverseUint64(aVal[2]);
+#endif
+    theStream.write((char *)&aVal[0], 3*sizeof(uint64_t));
+  }
 
-  theStream.write((char *)&aVal[0], 3*sizeof(uint64_t));
   theStream.seekp((std::streamsize)aSectionEnd);
 }
 
@@ -186,7 +218,7 @@ void BinLDrivers_DocumentSection::Write (Standard_OStream&   theStream,
 void BinLDrivers_DocumentSection::ReadTOC
                                 (BinLDrivers_DocumentSection& theSection,
                                  Standard_IStream&            theStream,
-                                 const Standard_Integer theDocFormatVersion)
+                                 const Standard_Integer       theDocFormatVersion)
 {
   char aBuf[512];
   Standard_Integer aNameBufferSize;
@@ -199,11 +231,11 @@ void BinLDrivers_DocumentSection::ReadTOC
     theSection.myName = (Standard_CString)&aBuf[0];
 
     uint64_t aValue[3];
-    if (theDocFormatVersion <= 9)
+    if (theDocFormatVersion <= TDocStd_FormatVersion_VERSION_9)
     {
       // Old documents stored file position as 4-bytes values.
-      Standard_Integer aValInt[3];
-      theStream.read ((char *)&aValInt[0], 3*sizeof(Standard_Integer));
+      int32_t aValInt[3];
+      theStream.read ((char *)&aValInt[0], 3*sizeof(int32_t));
 #if DO_INVERSE
       aValue[0] = InverseInt (aValInt[0]);
       aValue[1] = InverseInt (aValInt[1]);
index c701634e79e2e40d95dad02cba5c0dde7efc2733..b3cf472c957386efabc76bd1b9c710da9db47fbb 100644 (file)
@@ -66,11 +66,13 @@ public:
   Standard_EXPORT void SetLength (const uint64_t theLength);
   
   //! Create a Section entry in the Document TOC (list of sections)
-  Standard_EXPORT void WriteTOC (Standard_OStream& theOS);
+  Standard_EXPORT void WriteTOC (Standard_OStream& theOS,
+                                 const Standard_Integer theDocFormatVersion);
   
   //! Save Offset and Length data into the Section entry
   //! in the Document TOC (list of sections)
-  Standard_EXPORT void Write (Standard_OStream& theOS, const uint64_t theOffset);
+  Standard_EXPORT void Write (Standard_OStream& theOS, const uint64_t theOffset,
+                              const Standard_Integer theDocFormatVersion);
   
   //! Fill a DocumentSection instance from the data that are read
   //! from TOC.
index 0e5b7db18b9ca4f5b99f52a60077bcd131126126..a682929815c5537ef7d8827746f062a201bd03b1 100644 (file)
@@ -123,17 +123,16 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
         return;
     }
 
-
-
 //  2. Write the Table of Contents of Sections
+    const Standard_Integer aDocVer = aDoc->StorageFormatVersion();
     BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
     for (; anIterS.More(); anIterS.Next())
-      anIterS.ChangeValue().WriteTOC (theOStream);
+      anIterS.ChangeValue().WriteTOC (theOStream, aDocVer);
 
     // Shapes Section is the last one, it indicates the end of the table.
     BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
                                                 Standard_False);
-    aShapesSection.WriteTOC (theOStream);
+    aShapesSection.WriteTOC (theOStream, aDocVer);
 
 //  3. Write document contents
     // (Storage data to the stream)
@@ -152,7 +151,7 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
     }
 
 //  4. Write Shapes section
-    WriteShapeSection (aShapesSection, theOStream, aPS.Next());
+    WriteShapeSection (aShapesSection, theOStream, aDocVer, aPS.Next());
     if (!aPS.More())
     {
        SetIsError(Standard_True);
@@ -165,7 +164,7 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)&  theD
       BinLDrivers_DocumentSection& aSection = anIterS.ChangeValue();
       const Standard_Size aSectionOffset = (Standard_Size) theOStream.tellp();
       WriteSection (aSection.Name(), aDoc, theOStream);
-      aSection.Write (theOStream, aSectionOffset);
+      aSection.Write (theOStream, aSectionOffset, aDocVer);
     }
 
     // End of processing: close structures and check the status
@@ -469,9 +468,11 @@ void BinLDrivers_DocumentStorageDriver::WriteInfoSection
   theData->SetApplicationVersion(theDoc->Application()->Version());
   theData->SetApplicationName(theDoc->Application()->Name());
 
+  Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast(theDoc);
+  const Standard_Integer aDocVer = aDoc->StorageFormatVersion();
   aHeader.einfo += FSD_BinaryFile::WriteInfo (theOStream,
                                               aObjNb,
-                                              BinLDrivers::StorageVersion(),
+                                              aDocVer,
                                               Storage_Schema::ICreationDate(),
                                               "", // schema name
                                               aShemaVer,
@@ -500,7 +501,7 @@ void BinLDrivers_DocumentStorageDriver::WriteInfoSection
   // write info section
   FSD_BinaryFile::WriteInfo (theOStream,
                              aObjNb,
-                             BinLDrivers::StorageVersion(),
+                             aDocVer,
                              Storage_Schema::ICreationDate(),
                              "", // schema name
                              aShemaVer,
@@ -546,8 +547,9 @@ void BinLDrivers_DocumentStorageDriver::WriteSection
 void BinLDrivers_DocumentStorageDriver::WriteShapeSection
                                 (BinLDrivers_DocumentSection&   theSection,
                                  Standard_OStream&              theOS,
+                                 const Standard_Integer         theDocVer,
                                  const Message_ProgressRange& /*theRange*/)
 {
   const Standard_Size aShapesSectionOffset = (Standard_Size) theOS.tellp();
-  theSection.Write (theOS, aShapesSectionOffset);
+  theSection.Write (theOS, aShapesSectionOffset, theDocVer);
 }
index 6281700f6ec15e33095a051f57a4512ca0ece9f6..096afdbc1f13bb931eef924309310269e854d20a 100644 (file)
@@ -80,13 +80,14 @@ protected:
                                      const Message_ProgressRange& theRange = Message_ProgressRange());
   
   //! define the procedure of writing a section to file.
-  Standard_EXPORT virtual void WriteSection (const TCollection_AsciiString& theName,
-                                             const Handle(CDM_Document)& theDoc
-                                             Standard_OStream& theOS);
+  Standard_EXPORT virtual void WriteSection (const TCollection_AsciiString& /*theName*/,
+                                             const Handle(CDM_Document)&    /*theDoc*/
+                                             Standard_OStream&              /*theOS*/);
   
   //! defines the procedure of writing a shape  section to file
   Standard_EXPORT virtual void WriteShapeSection (BinLDrivers_DocumentSection& theDocSection,
                                                   Standard_OStream& theOS,
+                                                  const Standard_Integer theDocVer,
                                                   const Message_ProgressRange& theRange = Message_ProgressRange());
 
   Handle(BinMDF_ADriverTable) myDrivers;
index 123d43b6c1b483330facc65c9707627fb6c0d7d7..c91c9190df4640a25116372f380f6810d5395ada 100644 (file)
@@ -54,8 +54,7 @@ CDM_Document::CDM_Document():
   myRequestedNameIsDefined      (Standard_False),
   myRequestedPreviousVersionIsDefined(Standard_False),
   myFileExtensionWasFound       (Standard_False),
-  myDescriptionWasFound         (Standard_False),
-  myStorageFormatVersion        (0)
+  myDescriptionWasFound         (Standard_False)
 {}
 
 
@@ -1150,25 +1149,6 @@ void CDM_Document::SetReferenceCounter (const Standard_Integer aReferenceCounter
   myActualReferenceIdentifier=aReferenceCounter;
 }
 
-//=======================================================================
-//function : StorageFormatVersion
-//purpose  : 
-//=======================================================================
-Standard_Integer CDM_Document::StorageFormatVersion() const
-{
-  return myStorageFormatVersion;
-}
-
-//! 
-//=======================================================================
-//function : ChangeStorageFormatVersion
-//purpose  : Sets <theVersion> of the format to be used to store the document
-//=======================================================================
-void CDM_Document::ChangeStorageFormatVersion(const Standard_Integer theVersion)
-{
-  myStorageFormatVersion = theVersion;
-}
-
 //=======================================================================
 //function : DumpJson
 //purpose  : 
@@ -1214,6 +1194,4 @@ void CDM_Document::DumpJson (Standard_OStream& theOStream, Standard_Integer theD
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDescriptionWasFound)
 
   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myApplication.get())
-
-  OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myStorageFormatVersion)
 }
index 31506813a76201ed3180e8be4bd1c1597bd5b172..4be2f56c5ad5e8f9cd9b101ac27fe5a2c74e3cc6 100644 (file)
@@ -329,12 +329,6 @@ Standard_OStream& operator << (Standard_OStream& anOStream);
 
   Standard_EXPORT void SetReferenceCounter (const Standard_Integer aReferenceCounter);
 
-  //! Returns version of the format to be used to store the document
-  Standard_EXPORT Standard_Integer StorageFormatVersion() const;
-
-  //! Sets <theVersion> of the format to be used to store the document
-  Standard_EXPORT void ChangeStorageFormatVersion(const Standard_Integer theVersion);
-
   //! Dumps the content of me into the stream
   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
@@ -387,7 +381,6 @@ private:
   Standard_Boolean myFileExtensionWasFound;
   Standard_Boolean myDescriptionWasFound;
   Handle(CDM_Application) myApplication;
-  Standard_Integer myStorageFormatVersion;
 };
 
 
index dd789a89c560589435d7543821e02f7b80616f05..04bab120a90bccc60315800faaf535c51fd8d1f8 100644 (file)
@@ -482,31 +482,31 @@ static Standard_Integer DDocStd_PrintComments (Draw_Interpretor& di,
 }
 
 //=======================================================================
-//function : SetStorageVerison
+//function : SetStorageFormatVerison
 //purpose  : 
 //=======================================================================
-static Standard_Integer DDocStd_SetStorageVersion (Draw_Interpretor& ,
-                                                   Standard_Integer nb,
-                                                   const char** a)
+static Standard_Integer DDocStd_SetStorageFormatVersion (Draw_Interpretor& ,
+                                                         Standard_Integer nb,
+                                                         const char** a)
 {  
   if (nb == 3)
   {
     Handle(TDocStd_Document) D;
     if (!DDocStd::GetDocument(a[1], D)) return 1;
     const int version = atoi(a[2]);
-    D->ChangeStorageFormatVersion(version);
+    D->ChangeStorageFormatVersion((TDocStd_FormatVersion) version);
     return 0;
   }
   return 1;
 }
 
 //=======================================================================
-//function : GetStorageVerison
+//function : GetStorageFormatVerison
 //purpose  : 
 //=======================================================================
-static Standard_Integer DDocStd_GetStorageVersion (Draw_Interpretor& di,
-                                                   Standard_Integer nb,
-                                                   const char** a)
+static Standard_Integer DDocStd_GetStorageFormatVersion (Draw_Interpretor& di,
+                                                         Standard_Integer nb,
+                                                         const char** a)
 { 
   if (nb == 2) {
     Handle(TDocStd_Document) D;
@@ -576,10 +576,12 @@ void DDocStd::ApplicationCommands(Draw_Interpretor& theCommands)
                  "PrintComments Doc",
                  __FILE__, DDocStd_PrintComments, g);
 
-  theCommands.Add("GetStorageVersion",
-                 "GetStorageVersion Doc",
-                 __FILE__, DDocStd_GetStorageVersion, g);
-  theCommands.Add("SetStorageVersion",
-                 "SetStorageVersion Doc Version",
-                 __FILE__, DDocStd_SetStorageVersion, g);
+  theCommands.Add("GetStorageFormatVersion",
+                 "GetStorageFormatVersion Doc"
+          "\nStorage format versions are defined in TDocStd_FormatVersion.hxx file by an enumeration",
+                 __FILE__, DDocStd_GetStorageFormatVersion, g);
+  theCommands.Add("SetStorageFormatVersion",
+                 "SetStorageFormatVersion Doc Version"
+          "\nStorage format versions are defined in TDocStd_FormatVersion.hxx file by an enumeration",
+                 __FILE__, DDocStd_SetStorageFormatVersion, g);
 }
index 7af3a419434b9a806dcd3b790f62c8e1fc8c74af..6741dbf672f2e124020f8b3609e3fca3ec464643 100644 (file)
@@ -37,3 +37,4 @@ TDocStd_XLinkRoot.hxx
 TDocStd_XLinkRoot.lxx
 TDocStd_XLinkTool.cxx
 TDocStd_XLinkTool.hxx
+TDocStd_FormatVersion.hxx
index e72d5cacb0638a0440209b8c37fcddd7093f2a2f..b3798214f101b0e73c513ef38202e86a6907a0c8 100644 (file)
@@ -83,7 +83,8 @@ myUndoLimit(0),
 myUndoTransaction ("UNDO"),
 mySaveTime(0),
 myIsNestedTransactionMode(0),
-mySaveEmptyLabels(Standard_False)
+mySaveEmptyLabels(Standard_False),
+myStorageFormatVersion(TDocStd_FormatVersion_CURRENT)
 {
   myUndoTransaction.Initialize (myData);
   TDocStd_Owner::SetDocument(myData,this);
@@ -903,6 +904,33 @@ void TDocStd_Document::BeforeClose()
   ClearUndos();
 }
 
+//=======================================================================
+//function : StorageFormatVersion
+//purpose  : 
+//=======================================================================
+TDocStd_FormatVersion TDocStd_Document::StorageFormatVersion() const
+{
+  return myStorageFormatVersion;
+}
+
+//=======================================================================
+//function : ChangeStorageFormatVersion
+//purpose  : Sets <theVersion> of the format to be used to store the document
+//=======================================================================
+void TDocStd_Document::ChangeStorageFormatVersion(const TDocStd_FormatVersion theVersion)
+{
+  myStorageFormatVersion = theVersion;
+}
+
+//=======================================================================
+//function : CurrentStorageFormatVersion
+//purpose  : Returns current storage format verison of the document.
+//=======================================================================
+TDocStd_FormatVersion TDocStd_Document::CurrentStorageFormatVersion()
+{
+  return TDocStd_FormatVersion_CURRENT;
+}
+
 //=======================================================================
 //function : DumpJson
 //purpose  : 
@@ -943,4 +971,5 @@ void TDocStd_Document::DumpJson (Standard_OStream& theOStream, Standard_Integer
 
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOnlyTransactionModification)
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mySaveEmptyLabels)
+  OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream,  myStorageFormatVersion)
 }
index 2454a6525234f6cd523b3d32c78e8e2c1a6114f1..97c64d7b38363ef4b7d6ea7a46280d86527c5517 100644 (file)
@@ -28,6 +28,7 @@
 #include <CDM_Document.hxx>
 #include <TDF_LabelMap.hxx>
 #include <Standard_Address.hxx>
+#include <TDocStd_FormatVersion.hxx>
 class TDF_Data;
 class TDF_Delta;
 class TDF_Label;
@@ -248,6 +249,15 @@ public:
   //! Prepares document for closing
   Standard_EXPORT virtual void BeforeClose();
 
+  //! Returns version of the format to be used to store the document
+  Standard_EXPORT TDocStd_FormatVersion StorageFormatVersion() const;
+
+  //! Sets version of the format to be used to store the document
+  Standard_EXPORT void ChangeStorageFormatVersion(const TDocStd_FormatVersion theVersion);
+
+  //! Returns current storage format verison of the document.
+  Standard_EXPORT static TDocStd_FormatVersion CurrentStorageFormatVersion();
+
   //! Dumps the content of me into the stream
   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
@@ -290,6 +300,7 @@ private:
   TDF_DeltaList myUndoFILO;
   Standard_Boolean myOnlyTransactionModification;
   Standard_Boolean mySaveEmptyLabels;
+  TDocStd_FormatVersion myStorageFormatVersion;
 
 };
 
diff --git a/src/TDocStd/TDocStd_FormatVersion.hxx b/src/TDocStd/TDocStd_FormatVersion.hxx
new file mode 100644 (file)
index 0000000..4c75d19
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _TDocStdFormatVersion_HeaderFile
+#define _TDocStdFormatVersion_HeaderFile
+
+//! Storage format versions of OCAF documents in XML and binary file formats.
+
+//! Reading of new documents by old applications.
+//! Open CASCADE Technology evolves and file format of OCAF document evolves too. Does it mean that an application based on an old version of Open CASCADE Technology
+//! cannot read an OCAF document saved by an application using a newer version of Open CASCADE Technology?
+//! Let us consider this question in detail and see when it is possible.
+//! Storage version of OCAF document is stored in TDocStd_Document class and accessible via StorageFormatVersion() method.
+//! In order to change it, call the method ChangeStorageFormatVersion(). In order to save a document in older version
+//! (corresponding to an earlier version of Open CASCADE Technology),
+//! change the storage version (by means of TDocStd_Document::ChangeStorageFormatVersion()) and save the document(via TDocStd_Application::SaveAs()).
+//! It will be stored using the rules of an old version of Open CASCADE Technology.
+//! What to do if you need to improve the file format of an OCAF document, and in the same time,
+//! you would like the current application already sent to the users to read the new documents?
+//! Here it is an example of a similar case, which might give you an idea how to implement it.
+//! Example.
+//! In order to improve speed of writing and reading of OCAF document in XML file format a developer decided to perform the following improvements in OCAF:
+//!  - Removal of GUID of a TDataStd_TreeNode attribute, if it is default. Indeed, it seems reasonable not to write a GUID into XML file if it is default.
+//!    It derceases size of file and speeds-up writing and reading of the file. The same approach concerns several other attributes with default GUIDs.
+//!  - Compression of TDataStd_ExtStringArray attribute. It uses a new line for each value of the array abbreviated by XML tags.
+//!    If all values were put into one line separated by a comma or any other separator, it would decrease the file size, speed-up reading and writing.
+//! It is obvious that an old application, which does not know about an opportunity for a TDataStd_TreeNode attribute to have no GUID in XML file,
+//! may fail to read such an improved XML file. It means that we should 'teach' Open CASCADE Technology of later versions to write document in an old format. How to do it?
+//!  - First, we increase the storage format version of the document (in this TDocStd_FormatVerison.hxx file).
+//!  - Then, we introduce a code in XmlMDataStd_TreeNodeDriver::Paste(), which checks the document storage version and if it is one of the previous versions,
+//!    it writes the GUID in any case (in spite of it is default).
+//!  - For a TDataStd_ExtStringArray we do the same : we check the document storage version and if it is one of the previous versions,
+//!    we write values of the array in old manner : one per line surrounding each value by XML tags.
+//!    For details, please see XmlMDataStd_ExtStringArrayDriver::Paste().
+//! This way we obtain an opportunity to save OCAF document in an old file format, while for new applications we keep an improvement
+//! (smaller files on disk, reading and writing of the XML files is faster).
+enum TDocStd_FormatVersion
+{
+  TDocStd_FormatVersion_VERSION_2 = 2, //!< First supported version
+
+  TDocStd_FormatVersion_VERSION_3,     //!< (OCCT 6.3.0) 
+                                       //!<   XML: Adding DeltaOnModification functionality to set of Standard attributes [#0019403]
+                                       //!<   BIN: Add Delta to numbers data, changes in ShapeSection [#0019986, #0019403]
+
+  TDocStd_FormatVersion_VERSION_4,     //!< (OCCT 6.3.1) 
+                                       //!<   XML: Naming mechanism improvement [#0021004]
+                                       //!<   BIN: entry, ContextLabel for tree [#0021004]
+
+  TDocStd_FormatVersion_VERSION_5,     //!< (OCCT 6.3.1) 
+                                       //!<   XML: Separation of OCAF to Lite and Standard parts completion [#0021093]
+                                       //!<   BIN: Convert old format to new [#0021093]
+
+  TDocStd_FormatVersion_VERSION_6,     //!< (OCCT 6.5.0)  
+                                       //!<   XML: Add location [#0022192]
+                                       //!<   BIN: Add location [#0022192]
+
+  TDocStd_FormatVersion_VERSION_7,     //!< (OCCT 6.7.0)  
+                                       //!<   XML: Add orientation [#0023766]
+                                       //!<   BIN: Add orientation, type migration [#0023766]
+
+  TDocStd_FormatVersion_VERSION_8,     //!< (OCCT 7.0.0)  
+                                       //!<   XML: Replace TPrsStd_AISPresentation attribute with TDataXtd_Presentation [#0026290]
+                                       //!<   BIN: Stop convert old format [#0026290]
+
+  TDocStd_FormatVersion_VERSION_9,     //!< (OCCT 7.1.0) 
+                                       //!<   BIN: Add GUIDs, Process user defined guid [#0027932]
+
+  TDocStd_FormatVersion_VERSION_10,    //!< (OCCT 7.2.0) 
+                                       //!<   BIN: ReadTOC changed to handle 64-bit file length [#0028736]
+
+  TDocStd_FormatVersion_CURRENT = TDocStd_FormatVersion_VERSION_10 //!< The latest version. 
+};
+
+#endif // _TDocStdFormatVersion_HeaderFile
index 28b44691ac1b8dcdcfd172eb26a0012e911b181b..d5ab23eba9d6d400e235cc436886853adda8cd81 100644 (file)
@@ -33,8 +33,6 @@
 static Standard_GUID XmlLStorageDriver  ("13a56820-8269-11d5-aab2-0050044b1af1");
 static Standard_GUID XmlLRetrievalDriver("13a56822-8269-11d5-aab2-0050044b1af1");
 
-static int CURRENT_DOCUMENT_VERSION(9);
-
 //=======================================================================
 //function : Factory
 //purpose  : PLUGIN FACTORY
@@ -123,15 +121,5 @@ Handle(XmlMDF_ADriverTable) XmlLDrivers::AttributeDrivers
   return aTable;
 }
 
-//=======================================================================
-//function : StorageVersion
-//purpose  : Document storage version
-//=======================================================================
-
-int XmlLDrivers::StorageVersion()
-{
-  return CURRENT_DOCUMENT_VERSION;
-}
-
 // Declare entry point PLUGINFACTORY
 PLUGIN(XmlLDrivers)
index 171426217354eeb2aedf3c2dc29e4403d3161cb4..72c1dcc0ae0a3e28a5350c3cf71c1fd4666a1dda 100644 (file)
@@ -41,8 +41,6 @@ public:
   Standard_EXPORT static void DefineFormat (const Handle(TDocStd_Application)& theApp);
 
   Standard_EXPORT static Handle(XmlMDF_ADriverTable) AttributeDrivers (const Handle(Message_Messenger)& theMsgDriver);
-  
-  Standard_EXPORT static int StorageVersion();
 };
 
 #endif // _XmlLDrivers_HeaderFile
index 35bf5d345211d68f7ea6c6b7ffa6f5f841fcda43..fa8784f69b8bfa925b8050b2f9ea5029d15590bf 100644 (file)
@@ -270,12 +270,12 @@ void XmlLDrivers_DocumentRetrievalDriver::ReadFromDomDocument
     
     // oan: OCC22305 - check a document verison and if it's greater than
     // current version of storage driver set an error status and return
-    if( aCurDocVersion > XmlLDrivers::StorageVersion() )
+    if( aCurDocVersion > TDocStd_Document::CurrentStorageFormatVersion() )
     {
       TCollection_ExtendedString aMsg =
         TCollection_ExtendedString ("error: wrong file version: ") +
                                     aDocVerStr  + " while current is " +
-                                    XmlLDrivers::StorageVersion();
+                                    TDocStd_Document::CurrentStorageFormatVersion();
       myReaderStatus = PCDM_RS_NoVersion;
       if(!aMsgDriver.IsNull()) 
         aMsgDriver->Send(aMsg.ToExtString(), Message_Fail);
index bfcfdf1bea91c0e1b0d392746d495e4459239fd8..955f24cf638a788a66bcbe67fc9c4ed19573f4be 100644 (file)
@@ -269,18 +269,16 @@ Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument
 //  anInfoElem.setAttribute("appv", anAppVersion.ToCString());
 
   // Document version
-  Standard_Integer aFormatVersion(XmlLDrivers::StorageVersion());// the last version of the format
-  if (theDocument->StorageFormatVersion() > 0) 
+  Handle(TDocStd_Document) aDoc = Handle(TDocStd_Document)::DownCast (theDocument);
+  Standard_Integer aFormatVersion = TDocStd_Document::CurrentStorageFormatVersion(); // the last version of the format
+  if (TDocStd_Document::CurrentStorageFormatVersion() < aDoc->StorageFormatVersion())
   {
-    if (XmlLDrivers::StorageVersion() < theDocument->StorageFormatVersion())
-    {
-      TCollection_ExtendedString anErrorString("Unacceptable storage format version, the last verson is used");
-      aMessageDriver->Send(anErrorString.ToExtString(), Message_Warning);     
-    }
-    else            
-      aFormatVersion = theDocument->StorageFormatVersion();
+    TCollection_ExtendedString anErrorString("Unacceptable storage format version, the last verson is used");
+    aMessageDriver->Send (anErrorString.ToExtString(), Message_Warning);     
   }
-  anInfoElem.setAttribute("DocVersion", aFormatVersion);
+  else            
+    aFormatVersion = aDoc->StorageFormatVersion();
+  anInfoElem.setAttribute ("DocVersion", aFormatVersion);
  
   // User info with Copyright
   TColStd_SequenceOfAsciiString aUserInfo;
index 979a0796cf80ca1f92df623bd0261d90ac395eef..d0e6d2c153761ca5fcfef7845829ba3ad53849ee 100644 (file)
@@ -1,10 +1,8 @@
 puts "============"
 puts "OCC28691"
+puts "Storage of Ocaf documents in XML file format in old document version"
 puts "============"
 puts ""
-###################################################################################################################
-# Storage of Ocaf documents in XML file format in old document version
-###################################################################################################################
 
 NewDocument D XmlOcaf
 SetExtStringArray D 0:1 0 1 3 Hello hallo Bonjour
@@ -15,7 +13,7 @@ AISSet D 0:1 NS
 
 SaveAs D ${FileV9}
 
-SetStorageVersion D 7
+SetStorageFormatVersion D 7
 SaveAs D ${FileV7}
 
 Close D
diff --git a/tests/bugs/caf/bug29217 b/tests/bugs/caf/bug29217
new file mode 100644 (file)
index 0000000..d4b214b
--- /dev/null
@@ -0,0 +1,92 @@
+puts "============"
+puts "OCC29217"
+puts "Storage of Ocaf documents in BIN file format in old document version"
+puts "============"
+puts ""
+
+NewDocument D BinOcaf
+SetExtStringArray D 0:1 0 1 3 Hello hallo Bonjour
+set FileV7 ${imagedir}/bug29217_doc7.cbf
+set FileV10 ${imagedir}/bug29217_doc10.cbf
+SetNode D 0:1
+AISSet D 0:1 NS
+
+SaveAs D ${FileV10}
+
+SetStorageFormatVersion D 7
+SaveAs D ${FileV7}
+
+Close D
+
+puts "Testing for BIN file format in new version document"
+
+Open ${FileV10} D10
+
+set info [Attributes D10 0:1]
+if { [regexp "TDataStd_ExtStringArray" ${info}] != 1 } {
+    puts "Error : there is not TDataStd_ExtStringArray attribute in new version document"
+} else {
+    puts "OK : there is TDataStd_ExtStringArray attribute in new version document"
+}
+if { [regexp "TDataStd_TreeNode" ${info}] != 1 } {
+    puts "Error : there is not TDataStd_TreeNode attribute in new version document"
+} else {
+    puts "OK : there is TDataStd_TreeNode attribute in new version document"
+}
+if { [regexp "TDataXtd_Presentation" ${info}] != 1 } {
+    puts "Error : there is not TDataXtd_Presentation attribute in new version document"
+} else {
+    puts "OK : there is TDataXtd_Presentation attribute in new version document"
+}
+set info [GetExtStringArray D10 0:1]
+if { [regexp "Hello" ${info}] != 1 } {
+    puts "Error : there is not \"Hello\" word in TDataStd_ExtStringArray attribute in new version document"
+} else {
+    puts "OK : there is \"Hello\" word in TDataStd_ExtStringArray attribute in new version document"
+}
+if { [regexp "hallo" ${info}] != 1 } {
+    puts "Error : there is not \"hallo\" word in TDataStd_ExtStringArray attribute in new version document"
+} else {
+    puts "OK : there is \"hallo\" word in TDataStd_ExtStringArray attribute in new version document"
+}
+if { [regexp "Bonjour" ${info}] != 1 } {
+    puts "Error : there is not \"Bonjour\" word in TDataStd_ExtStringArray attribute in new version document"
+} else {
+    puts "OK : there is \"Bonjour\" word in TDataStd_ExtStringArray attribute in new version document"
+}
+
+puts "\nTesting for BIN file format in old version document"
+Open ${FileV7} D7
+
+set info [Attributes D7 0:1]
+if { [regexp "TDataStd_ExtStringArray" ${info}] != 1 } {
+    puts "Error : there is not TDataStd_ExtStringArray attribute in old version document"
+} else {
+    puts "OK : there is TDataStd_ExtStringArray attribute in old version document"
+}
+if { [regexp "TDataStd_TreeNode" ${info}] != 1 } {
+    puts "Error : there is not TDataStd_TreeNode attribute in old version document"
+} else {
+    puts "OK : there is TDataStd_TreeNode attribute in old version document"
+}
+if { [regexp "TDataXtd_Presentation" ${info}] != 1 } {
+    puts "Error : there is not TDataXtd_Presentation attribute in old version document"
+} else {
+    puts "OK : there is TDataXtd_Presentation attribute in old version document"
+}
+set info [GetExtStringArray D7 0:1]
+if { [regexp "Hello" ${info}] != 1 } {
+    puts "Error : there is not \"Hello\" word in TDataStd_ExtStringArray attribute in old version document"
+} else {
+    puts "OK : there is \"Hello\" word in TDataStd_ExtStringArray attribute in old version document"
+}
+if { [regexp "hallo" ${info}] != 1 } {
+    puts "Error : there is not \"hallo\" word in TDataStd_ExtStringArray attribute in old version document"
+} else {
+    puts "OK : there is \"hallo\" word in TDataStd_ExtStringArray attribute in old version document"
+}
+if { [regexp "Bonjour" ${info}] != 1 } {
+    puts "Error : there is not \"Bonjour\" word in TDataStd_ExtStringArray attribute in old version document"
+} else {
+    puts "OK : there is \"Bonjour\" word in TDataStd_ExtStringArray attribute in old version document"
+}
index 3237a7136e5e74a34bf2a382cc504499945be7a7..9723450c65d2518da35af61c8ccaf6b9ff15e7c2 100644 (file)
@@ -14,9 +14,16 @@ AISSet D1 0:1 NS
 AISDisplay D1 0:1
 AISMode D1 0:1 1
 
-SaveAs D1 testmode.xml
+set aFile ${imagedir}/testmode.xml
+file delete ${aFile}
+SaveAs D1 ${aFile}
+if { ![file exists ${aFile}] } {
+       puts "There is not ${aFile} file; SaveAs command: Error"
+       return
+}
+
 Close D1
-Open testmode.xml D2
+Open ${aFile} D2
 AISInitViewer D2
 AISDisplay D2 0:1
 set mode [AISMode D2 0:1]