]> OCCT Git - occt.git/commitdiff
0029901: Support save to and restore from Stream interface in TObj package
authorvro <vro@opencascade.com>
Fri, 11 Dec 2020 15:13:25 +0000 (18:13 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 17 Dec 2020 18:05:03 +0000 (21:05 +0300)
Storage and retrieval of a document by means of a stream is distributed to TObj model.
Modified files:
-TObj_Model.hxx, cxx - the virtual methods Load() and SaveAs() obtained a stream as an argument instead of a file name.
-TObj_Application.hxx, cxx - same extension: the virtual methods LoadDocument() and SaveDocument() use a stream to open and save a document.
-TObjDRAW.cxx - draw-commands TObjSave and TObjLoad are extended for -stream parameter, which allows usage of a file input or output stream instead of a file name.

A new test:
- bugs caf bug29901 - it creates a simple TObj-model, saves it on disk using a file stream, loads it by means of a file stream and checks the content.

Modified test:
- bugs caf bug28425 - just improved to proper manipulate a test-file on disk.

src/TObj/TObj_Application.cxx
src/TObj/TObj_Application.hxx
src/TObj/TObj_Model.cxx
src/TObj/TObj_Model.hxx
src/TObjDRAW/TObjDRAW.cxx
tests/bugs/caf/bug28425
tests/bugs/caf/bug29901 [new file with mode: 0644]

index 81e9279a4b9bf560e22231fab4f129578b70a81e..0fdad6123e9bbd086932a6cb4b95b2c609389c8c 100644 (file)
@@ -81,36 +81,29 @@ Standard_Boolean TObj_Application::SaveDocument
                         (const Handle(TDocStd_Document)&   theSourceDoc,
                          const TCollection_ExtendedString& theTargetFile)
 {
-  myIsError = Standard_False;
-  PCDM_StoreStatus aStatus = SaveAs (theSourceDoc, theTargetFile);
-  myIsError = aStatus != PCDM_SS_OK;
+  const PCDM_StoreStatus aStatus = SaveAs (theSourceDoc, theTargetFile);
+  myIsError = (aStatus != PCDM_SS_OK);
   if (myIsError)
-  {
-    switch (aStatus)
-    {
-    case PCDM_SS_DriverFailure:
-      ErrorMessage (Message_Msg("TObj_Appl_SDriverFailure") << theTargetFile);
-      break;
-    case PCDM_SS_WriteFailure:
-      ErrorMessage (Message_Msg("TObj_Appl_SWriteFailure") << theTargetFile);
-      break;
-    case PCDM_SS_Failure:
-      ErrorMessage (Message_Msg("TObj_Appl_SFailure") << theTargetFile);
-      break;
-    case PCDM_SS_Doc_IsNull:
-      ErrorMessage (Message_Msg("TObj_Appl_SDocIsNull") << theTargetFile);
-      break;
-    case PCDM_SS_No_Obj:
-      ErrorMessage (Message_Msg("TObj_Appl_SNoObj") << theTargetFile);
-      break;
-    case PCDM_SS_Info_Section_Error:
-      ErrorMessage (Message_Msg("TObj_Appl_SInfoSectionError") << theTargetFile);
-      break;
-    default:
-      ErrorMessage (Message_Msg("TObj_Appl_SUnknownFailure") << theTargetFile);
-      break;
-    }
-  }
+    SetError (aStatus, theTargetFile);
+
+  // Release free memory
+  Standard::Purge();
+  return myIsError ? Standard_False : Standard_True;
+}
+
+//=======================================================================
+//function : SaveDocument
+//purpose  : Saving the OCAF document to a stream
+//=======================================================================
+
+Standard_Boolean TObj_Application::SaveDocument
+                        (const Handle(TDocStd_Document)& theSourceDoc,
+                         Standard_OStream&               theOStream)
+{
+  const PCDM_StoreStatus aStatus = SaveAs (theSourceDoc, theOStream);
+  myIsError = (aStatus != PCDM_SS_OK);
+  if (myIsError)
+    SetError (aStatus, "");
 
   // Release free memory
   Standard::Purge();
@@ -126,7 +119,6 @@ Standard_Boolean TObj_Application::LoadDocument
                         (const TCollection_ExtendedString& theSourceFile,
                          Handle(TDocStd_Document)&         theTargetDoc)
 {
-  myIsError = Standard_False;
   PCDM_ReaderStatus aStatus = PCDM_RS_ReaderException;
   {
     try
@@ -138,67 +130,43 @@ Standard_Boolean TObj_Application::LoadDocument
       ErrorMessage (Message_Msg("TObj_Appl_Exception") << 
                     anException.GetMessageString());
 #endif
-      (void)anException;
+      (void) anException;
     }
   }
-  myIsError = aStatus != PCDM_RS_OK;
+  myIsError = (aStatus != PCDM_RS_OK);
   if (myIsError)
+    SetError (aStatus, theSourceFile);
+
+  // Release free memory
+  Standard::Purge();
+  return myIsError ? Standard_False : Standard_True;
+}
+
+//=======================================================================
+//function : LoadDocument
+//purpose  : Loading the OCAF document from a stream
+//=======================================================================
+
+Standard_Boolean TObj_Application::LoadDocument
+                        (Standard_IStream&         theIStream,
+                         Handle(TDocStd_Document)& theTargetDoc)
+{
+  PCDM_ReaderStatus aStatus = PCDM_RS_ReaderException;
   {
-    switch (aStatus)
+    try
     {
-    case PCDM_RS_UnknownDocument:
-      ErrorMessage (Message_Msg("TObj_Appl_RUnknownDocument") << theSourceFile);
-      break;
-    case PCDM_RS_AlreadyRetrieved:
-      ErrorMessage (Message_Msg("TObj_Appl_RAlreadyRetrieved") << theSourceFile);
-      break;
-    case PCDM_RS_AlreadyRetrievedAndModified:
-      ErrorMessage (Message_Msg("TObj_Appl_RAlreadyRetrievedAndModified") << theSourceFile);
-      break;
-    case PCDM_RS_NoDriver:
-      ErrorMessage (Message_Msg("TObj_Appl_RNoDriver") << theSourceFile);
-      break;
-    case PCDM_RS_UnknownFileDriver:
-      ErrorMessage (Message_Msg("TObj_Appl_RNoDriver") << theSourceFile);
-      break;
-    case PCDM_RS_OpenError:
-      ErrorMessage (Message_Msg("TObj_Appl_ROpenError") << theSourceFile);
-      break;
-    case PCDM_RS_NoVersion:
-      ErrorMessage (Message_Msg("TObj_Appl_RNoVersion") << theSourceFile);
-      break;
-    case PCDM_RS_NoModel:
-      ErrorMessage (Message_Msg("TObj_Appl_RNoModel") << theSourceFile);
-      break;
-    case PCDM_RS_NoDocument:
-      ErrorMessage (Message_Msg("TObj_Appl_RNoDocument") << theSourceFile);
-      break;
-    case PCDM_RS_FormatFailure:
-      ErrorMessage (Message_Msg("TObj_Appl_RFormatFailure") << theSourceFile);
-      break;
-    case PCDM_RS_TypeNotFoundInSchema:
-      ErrorMessage (Message_Msg("TObj_Appl_RTypeNotFound") << theSourceFile);
-      break;
-    case PCDM_RS_UnrecognizedFileFormat:
-      ErrorMessage (Message_Msg("TObj_Appl_RBadFileFormat") << theSourceFile);
-      break;
-    case PCDM_RS_MakeFailure:
-      ErrorMessage (Message_Msg("TObj_Appl_RMakeFailure") << theSourceFile);
-      break;
-    case PCDM_RS_PermissionDenied:
-      ErrorMessage (Message_Msg("TObj_Appl_RPermissionDenied") << theSourceFile);
-      break;
-    case PCDM_RS_DriverFailure:
-      ErrorMessage (Message_Msg("TObj_Appl_RDriverFailure") << theSourceFile);
-      break;
-    case PCDM_RS_ReaderException:
-      ErrorMessage (Message_Msg("TObj_Appl_RException") << theSourceFile);
-      break;
-    default:
-      ErrorMessage (Message_Msg("TObj_Appl_RUnknownFail") << theSourceFile);
-      break;
+      aStatus = Open (theIStream, theTargetDoc);
+    }
+    catch (Standard_Failure const& anException) {
+#ifdef OCCT_DEBUG
+      ErrorMessage(Message_Msg("TObj_Appl_Exception") << anException.GetMessageString());
+#endif
+      (void) anException;
     }
   }
+  myIsError = (aStatus != PCDM_RS_OK);
+  if (myIsError)
+    SetError (aStatus, "");
 
   // Release free memory
   Standard::Purge();
@@ -243,3 +211,99 @@ void TObj_Application::DumpJson (Standard_OStream& theOStream, Standard_Integer
 
   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDocStd_Application)
 }
+
+//=======================================================================
+//function : SetError
+//purpose  : Sets an error occured on storage of a document.
+//=======================================================================
+
+void TObj_Application::SetError (const PCDM_StoreStatus theStatus, const TCollection_ExtendedString& theInfo)
+{
+  switch (theStatus)
+  {
+    case PCDM_SS_DriverFailure:
+      ErrorMessage(Message_Msg("TObj_Appl_SDriverFailure") << theInfo);
+      break;
+    case PCDM_SS_WriteFailure:
+      ErrorMessage(Message_Msg("TObj_Appl_SWriteFailure") << theInfo);
+      break;
+    case PCDM_SS_Failure:
+      ErrorMessage(Message_Msg("TObj_Appl_SFailure") << theInfo);
+      break;
+    case PCDM_SS_Doc_IsNull:
+      ErrorMessage(Message_Msg("TObj_Appl_SDocIsNull") << theInfo);
+      break;
+    case PCDM_SS_No_Obj:
+      ErrorMessage(Message_Msg("TObj_Appl_SNoObj") << theInfo);
+      break;
+    case PCDM_SS_Info_Section_Error:
+      ErrorMessage(Message_Msg("TObj_Appl_SInfoSectionError") << theInfo);
+      break;
+    default:
+      ErrorMessage(Message_Msg("TObj_Appl_SUnknownFailure") << theInfo);
+      break;
+  }
+}
+
+//=======================================================================
+//function : SetError
+//purpose  : Sets an error occured on reading of a document.
+//=======================================================================
+
+void TObj_Application::SetError(const PCDM_ReaderStatus theStatus, const TCollection_ExtendedString& theInfo)
+{
+  switch (theStatus)
+  {
+    case PCDM_RS_UnknownDocument:
+      ErrorMessage(Message_Msg("TObj_Appl_RUnknownDocument") << theInfo);
+      break;
+    case PCDM_RS_AlreadyRetrieved:
+      ErrorMessage(Message_Msg("TObj_Appl_RAlreadyRetrieved") << theInfo);
+      break;
+    case PCDM_RS_AlreadyRetrievedAndModified:
+      ErrorMessage(Message_Msg("TObj_Appl_RAlreadyRetrievedAndModified") << theInfo);
+      break;
+    case PCDM_RS_NoDriver:
+      ErrorMessage(Message_Msg("TObj_Appl_RNoDriver") << theInfo);
+      break;
+    case PCDM_RS_UnknownFileDriver:
+      ErrorMessage(Message_Msg("TObj_Appl_RNoDriver") << theInfo);
+      break;
+    case PCDM_RS_OpenError:
+      ErrorMessage(Message_Msg("TObj_Appl_ROpenError") << theInfo);
+      break;
+    case PCDM_RS_NoVersion:
+      ErrorMessage(Message_Msg("TObj_Appl_RNoVersion") << theInfo);
+      break;
+    case PCDM_RS_NoModel:
+      ErrorMessage(Message_Msg("TObj_Appl_RNoModel") << theInfo);
+      break;
+    case PCDM_RS_NoDocument:
+      ErrorMessage(Message_Msg("TObj_Appl_RNoDocument") << theInfo);
+      break;
+    case PCDM_RS_FormatFailure:
+      ErrorMessage(Message_Msg("TObj_Appl_RFormatFailure") << theInfo);
+      break;
+    case PCDM_RS_TypeNotFoundInSchema:
+      ErrorMessage(Message_Msg("TObj_Appl_RTypeNotFound") << theInfo);
+      break;
+    case PCDM_RS_UnrecognizedFileFormat:
+      ErrorMessage(Message_Msg("TObj_Appl_RBadFileFormat") << theInfo);
+      break;
+    case PCDM_RS_MakeFailure:
+      ErrorMessage(Message_Msg("TObj_Appl_RMakeFailure") << theInfo);
+      break;
+    case PCDM_RS_PermissionDenied:
+      ErrorMessage(Message_Msg("TObj_Appl_RPermissionDenied") << theInfo);
+      break;
+    case PCDM_RS_DriverFailure:
+      ErrorMessage(Message_Msg("TObj_Appl_RDriverFailure") << theInfo);
+      break;
+    case PCDM_RS_ReaderException:
+      ErrorMessage(Message_Msg("TObj_Appl_RException") << theInfo);
+      break;
+    default:
+      ErrorMessage(Message_Msg("TObj_Appl_RUnknownFail") << theInfo);
+      break;
+  }
+}
index 8c44bf001a246288188eec8bee75a7f77e072598..f619955f1588ea40f7475dc2aeaad1ceaf550c07 100644 (file)
@@ -44,14 +44,24 @@ public:
 
   //! Saving the OCAF document to a file
   Standard_EXPORT virtual Standard_Boolean SaveDocument
-                         (const Handle(TDocStd_Document)&   theSourceDoc,
-                          const TCollection_ExtendedString& theTargetFile);
+                        (const Handle(TDocStd_Document)&   theSourceDoc,
+                         const TCollection_ExtendedString& theTargetFile);
+
+  //! Saving the OCAF document to a stream
+  Standard_EXPORT virtual Standard_Boolean SaveDocument
+                        (const Handle(TDocStd_Document)&   theSourceDoc,
+                         Standard_OStream&                 theOStream);
 
   //! Loading the OCAF document from a file
   Standard_EXPORT virtual Standard_Boolean LoadDocument
                          (const TCollection_ExtendedString& theSourceFile,
                           Handle(TDocStd_Document)&         theTargetDoc);
 
+  //! Loading the OCAF document from a stream
+  Standard_EXPORT virtual Standard_Boolean LoadDocument
+                        (Standard_IStream&                 theIStream,
+                         Handle(TDocStd_Document)&         theTargetDoc);
+
   //! Create the OCAF document from scratch
   virtual Standard_EXPORT Standard_Boolean CreateNewDocument
                          (Handle(TDocStd_Document)&         theDoc,
@@ -99,6 +109,12 @@ public:
   //! the static instance of the object (or derive your own application)
   Standard_EXPORT TObj_Application();
 
+  //! Sets an error occured on storage of a document.
+  void SetError (const PCDM_StoreStatus theStatus, const TCollection_ExtendedString& theInfo);
+
+  //! Sets an error occured on reading of a document.
+  void SetError (const PCDM_ReaderStatus theStatus, const TCollection_ExtendedString& theInfo);
+
  private:
   /**
   * Fields
index 86dfb3709089ae5b821b2889eb8541b336c05de2..4b6f97a18de11065bc240b15a8d01cbf04c1187a 100644 (file)
@@ -212,6 +212,102 @@ Standard_Boolean TObj_Model::Load (const TCollection_ExtendedString& theFile)
   return aStatus;
 }
 
+//=======================================================================
+//function : Load
+//purpose  : Load the OCAF model from a stream. If case of failure,
+//           it initializes the model by empty data.
+//=======================================================================
+
+Standard_Boolean TObj_Model::Load (Standard_IStream& theIStream)
+{
+  Handle(TDocStd_Document) aDoc;
+  Standard_Boolean aStatus = Standard_True, isFileLoaded = Standard_False;
+  const Handle(TObj_Application) anApplication = GetApplication();
+
+  // Current model
+  const Handle(TObj_Model) me = this;
+  TObj_Assistant::SetCurrentModel (me);
+  TObj_Assistant::ClearTypeMap();
+
+  // Retrieve TDocStd_Document from the stream.
+  Messenger()->Send (Message_Msg ("TObj_M_LoadDocument"), Message_Info);
+  aStatus = anApplication->LoadDocument (theIStream, aDoc);
+  if (aStatus)
+  {
+    // Check for validity of the model read:
+    // if it had wrong type, it has not been not properly restored
+    TDF_Label aLabel = GetLabel();
+    Standard_Boolean isValid = (!aLabel.IsNull() && !aDoc.IsNull());
+    try
+    {
+      isValid = (isValid && aLabel.Data() == aDoc->GetData());
+    }
+    catch (Standard_Failure const&)
+    {
+      isValid = Standard_False;
+    }
+    if (!isValid)
+    {
+      if (!aDoc.IsNull())
+        CloseDocument (aDoc);
+      myLabel.Nullify();
+      Messenger()->Send (Message_Msg ("TObj_M_WrongFile"), Message_Alarm);
+      aStatus = Standard_False;
+    }
+    isFileLoaded = isValid;
+  }
+  else
+  {
+    // release document from session
+    // no message is needed as it has been put in anApplication->LoadDocument()
+    if (!aDoc.IsNull()) 
+      CloseDocument (aDoc);
+    myLabel.Nullify();
+
+    aStatus = anApplication->CreateNewDocument (aDoc, GetFormat());
+    if (aStatus)
+    {
+      // Put model in a new attribute on root label
+      TDF_Label aLabel = aDoc->Main();
+      Handle(TObj_TModel) anAtr = new TObj_TModel;
+      aLabel.AddAttribute (anAtr);
+      anAtr->Set (me);
+      // Record that label in the model object, and initialise the new model
+      SetLabel (aLabel);
+    }
+  }
+
+  // Initialise the new model
+  if (aStatus)
+  {
+    Standard_Boolean isInitOk = Standard_False;
+    try
+    {
+      isInitOk = initNewModel (!isFileLoaded);
+    }
+    catch (Standard_Failure const& anException) {
+#ifdef OCCT_DEBUG
+      TCollection_ExtendedString aString(anException.DynamicType()->Name());
+      aString = aString + ": " + anException.GetMessageString();
+      Messenger()->Send (Message_Msg ("TObj_Appl_Exception") << aString);
+#endif
+      (void) anException;
+      Messenger()->Send (Message_Msg ("TObj_M_WrongFile"), Message_Alarm);
+    }
+    if (!isInitOk)
+    {
+      if (!aDoc.IsNull()) 
+        CloseDocument (aDoc);
+      myLabel.Nullify();
+      aStatus = Standard_False;
+    }
+  }
+
+  TObj_Assistant::UnSetCurrentModel();
+  TObj_Assistant::ClearTypeMap();
+  return aStatus;
+}
+
 //=======================================================================
 //function : GetFile
 //purpose  : Returns the full file name this model is to be saved to, 
@@ -300,6 +396,40 @@ Standard_Boolean TObj_Model::SaveAs (const TCollection_ExtendedString& theFile)
   return aStatus;
 }
 
+//=======================================================================
+//function : SaveAs
+//purpose  : Save the model to a stream
+//=======================================================================
+
+Standard_Boolean TObj_Model::SaveAs (Standard_OStream& theOStream)
+{
+    TObj_Assistant::ClearTypeMap();
+    // OCAF document
+    Handle(TDocStd_Document) aDoc = TDocStd_Document::Get(GetLabel());
+    if (aDoc.IsNull())
+        return Standard_False;
+
+    // store transaction mode
+    Standard_Boolean aTrMode = aDoc->ModificationMode();
+    aDoc->SetModificationMode(Standard_False);
+    // store all trancienmt fields of object in OCAF document if any
+    Handle(TObj_ObjectIterator) anIterator;
+    for (anIterator = GetObjects(); anIterator->More(); anIterator->Next())
+    {
+        Handle(TObj_Object) anOCAFObj = anIterator->Value();
+        if (anOCAFObj.IsNull())
+            continue;
+        anOCAFObj->BeforeStoring();
+    } // end of for(anIterator = ...)
+      // set transaction mode back
+    aDoc->SetModificationMode(aTrMode);
+
+    // call Application->SaveAs()
+    Standard_Boolean aStatus = GetApplication()->SaveDocument(aDoc, theOStream);
+    TObj_Assistant::ClearTypeMap();
+    return aStatus;
+}
+
 //=======================================================================
 //function : Close
 //purpose  : Close the model and free related OCAF document
index 066869935e7df6180a7af793ba3866e8c0ea61d4..ebcc13f8a936a1fcd12d86e7a18714247a8f5c8f 100644 (file)
@@ -83,14 +83,21 @@ class TObj_Model : public Standard_Transient
   /**
   * Implementation of Load/Save for OCAF based models
   */
-  
+
   //! Load the OCAF model from a file. If the filename is empty or file does
   //! not exists, it just initializes model by empty data.
   Standard_EXPORT virtual Standard_Boolean Load (const TCollection_ExtendedString& theFile);
 
+  //! Load the OCAF model from a stream. If case of failure,
+  //! it initializes the model by empty data.
+  Standard_EXPORT virtual Standard_Boolean Load (Standard_IStream& theIStream);
+
   //! Save the model to a file
   Standard_EXPORT virtual Standard_Boolean SaveAs (const TCollection_ExtendedString& theFile);
 
+  //! Save the model to a stream
+  Standard_EXPORT virtual Standard_Boolean SaveAs (Standard_OStream& theOStream);
+
   //! Save the model to the same file
   Standard_EXPORT Standard_Boolean Save ();
 
index 12b4e3fab78d611d355edb7a8a50efbae945adb4..17342d5d3a632c97a26949d07ed7178e4dee4aed 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <BinTObjDrivers.hxx>
 #include <XmlTObjDrivers.hxx>
+#include <OSD_OpenFile.hxx>
 
 #include <stdio.h>
 
@@ -188,13 +189,31 @@ static Handle(TObj_Model) getModelByName( const char* theName )
 //=======================================================================
 static Standard_Integer saveModel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  if (argc < 2) {di<<"Use "<< argv[0] << "nameDoc [fileName]\n";return 1;}
+  if (argc < 2) {di<<"Use "<< argv[0] << "nameDoc [fileName] [-stream]\n";return 1;}
   
   Handle(TObj_Model) aModel = getModelByName(argv[1]);
   if ( aModel.IsNull() ) return 1;
   Standard_Boolean isSaved = Standard_False; 
   if (argc > 2 )
-    isSaved = aModel->SaveAs( TCollection_ExtendedString (argv[2], Standard_True) );
+  {
+    Standard_Boolean anUseStream(Standard_False);
+    for (Standard_Integer i = 3; i < argc && !anUseStream; i++)
+    {
+      if (!strcmp(argv[i], "-stream"))
+      {
+        di << "standard SEEKABLE stream is used\n";
+        anUseStream = Standard_True;
+      }
+    }
+    if (anUseStream)
+    {
+      std::ofstream aFileStream;
+      OSD_OpenStream (aFileStream, argv[2], std::ios::out | std::ios::binary);
+      isSaved = aModel->SaveAs (aFileStream);
+    }
+    else
+      isSaved = aModel->SaveAs ( TCollection_ExtendedString (argv[2], Standard_True) );
+  }
   else
     isSaved = aModel->Save();
   
@@ -211,8 +230,18 @@ static Standard_Integer saveModel (Draw_Interpretor& di, Standard_Integer argc,
 //=======================================================================
 static Standard_Integer loadModel (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
 {
-  if (argc < 3) {di<<"Use "<< argv[0] << "nameDoc fileName\n";return 1;}
-  
+  if (argc < 3) {di<<"Use "<< argv[0] << "nameDoc fileName [-stream]\n";return 1;}
+
+  Standard_Boolean anUseStream = Standard_False;
+  for (Standard_Integer i = 3; i < argc && !anUseStream; i++)
+  {
+    if (!strcmp(argv[i], "-stream"))
+    {
+      di << "standard SEEKABLE stream is used\n";
+      anUseStream = Standard_True;
+    }
+  }
+
   Standard_Boolean isLoaded = Standard_False;
   Handle(TObj_Model) aModel = getModelByName(argv[1]);
   TCollection_ExtendedString aPath(argv[2], Standard_True);
@@ -220,11 +249,19 @@ static Standard_Integer loadModel (Draw_Interpretor& di, Standard_Integer argc,
   {
     // create new
     aModel = new TObjDRAW_Model();
-    isLoaded = aModel->Load(aPath);
+    if (anUseStream)
+    {
+      std::ifstream aFileStream;
+      OSD_OpenStream (aFileStream, aPath, std::ios::in | std::ios::binary);
+      isLoaded = aModel->Load (aFileStream);
+    }
+    else
+      isLoaded = aModel->Load (aPath);
+
     if ( isLoaded )
     {
       Handle(TDocStd_Document) D = aModel->GetDocument();
-      Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(D);
+      Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument (D);
     
       TDataStd_Name::Set(D->GetData()->Root(),argv[1]);
       Draw::Set(argv[1],DD);
@@ -234,8 +271,7 @@ static Standard_Integer loadModel (Draw_Interpretor& di, Standard_Integer argc,
   {
     isLoaded = aModel->Load(aPath);
   }
-  
-  
+
   if (!isLoaded) {
     di << "Error: Document not loaded\n";
     return 1;
@@ -506,10 +542,10 @@ void TObjDRAW::Init(Draw_Interpretor& di)
   di.Add ("TObjNew","DocName \t: Create new TObj model with document named DocName",
                   __FILE__, newModel, g);
 
-  di.Add ("TObjSave","DocName [Path] \t: Save Model with DocName",
+  di.Add ("TObjSave","DocName [Path] [-stream] \t: Save Model with DocName [by file path] [into a file stream]",
                   __FILE__, saveModel, g);
 
-  di.Add ("TObjLoad","DocName Path \t: Load model DocName from file Path",
+  di.Add ("TObjLoad","DocName Path [-stream] \t: Load model DocName from file Path [file stream]",
                   __FILE__, loadModel, g);
 
   di.Add ("TObjClose","DocName\t: Close model DocName",
index 320b8513fb0c1f03c7d6a373313e34d0ce0fb49e..8b8835bca44b8a7f94dbf364a987f42edc2114a5 100644 (file)
@@ -7,6 +7,8 @@ puts ""
 ############################################################
 
 pload QAcommands
+set aTestFileBin $imagedir/${casename}.cbf
+set aTestFileXml $imagedir/${casename}.xml
 
 vertex v 1 2 3
 box b 10 20 30
@@ -21,9 +23,9 @@ if { [regexp "SOLID" $info] != 1 } {
 } else {
     puts "OK: order of shapes is correct"
 }
-SaveAs D1 test.cbf
+SaveAs D1 ${aTestFileBin}
 Close D1
-Open test.cbf D2
+Open ${aTestFileBin} D2
 GetNewShapes D2 0:1 s
 set info [whatis s_1]
 if { [regexp "SOLID" $info] != 1 } {
@@ -43,9 +45,9 @@ if { [regexp "SOLID" $info] != 1 } {
 } else {
     puts "OK: order of shapes is correct"
 }
-SaveAs D1 test.xml
+SaveAs D1 ${aTestFileXml}
 Close D1
-Open test.xml D2
+Open ${aTestFileXml} D2
 GetNewShapes D2 0:1 s
 set info [whatis s_1]
 if { [regexp "SOLID" $info] != 1 } {
diff --git a/tests/bugs/caf/bug29901 b/tests/bugs/caf/bug29901
new file mode 100644 (file)
index 0000000..8018945
--- /dev/null
@@ -0,0 +1,46 @@
+puts "============"
+puts "0029901: Support save to and restore from Stream interface in TObj package"
+puts "============"
+
+set status 0
+set BugNumber 29901
+pload TOBJ
+
+# Create a new document
+TObjNew TD1
+TObjAddObj TD1 obj1
+TObjSetVal TD1 obj1 ${BugNumber}
+
+# Save the document
+set aFile $imagedir/${test_image}-[file tail [info script]].cbf
+catch {[file delete ${aFile}]}
+catch {TObjSave TD1 ${aFile} -stream}
+if { ![file exists ${aFile}] } {
+   set status 1
+   puts "There is not ${aFile} file; TObjSave command: Error"
+   puts "bug${BugNumber}: ERROR"
+} else {
+   puts "Save the document to ${aFile} file"
+}
+
+TObjClose TD1
+unset TD1
+
+# Restore the document
+if [catch { TObjLoad TD2 ${aFile} -stream} catch_result] {
+   puts "bug${BugNumber}: ERROR"
+}
+
+# check stored single integer value
+set retInt [TObjGetVal TD2 obj1 -i]
+if { $retInt != ${BugNumber} } {
+    set status 1
+    puts "bug${BugNumber}: check stored single integer value; ERROR"
+}
+
+if { ${status} != 0 } {
+   puts "Faulty bug${BugNumber}"
+} else {
+   puts "OK bug${BugNumber}"
+}
+