1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0029901: Support save to and restore from Stream interface in TObj package

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.
This commit is contained in:
vro
2020-12-11 18:13:25 +03:00
committed by bugmaster
parent c6685c65fd
commit a8d3a0b102
7 changed files with 402 additions and 101 deletions

View 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;
}
}

View 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

View 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

View 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 ();