1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-03 14:10:33 +03:00

0026229: Add the possibility in OCAF to open/save a document from/to a stream object

TDocStd_Application class extended to open/save a document of XmlOcaf and BinOcaf format
from/to standard SEEKABLE stream object which should support SEEK functionality.

Open and SaveAs DRAW commands got new additional argument "-stream" to turn on using of stream functionality.

The main changes for BinOcaf format applied in:
FSD_BinaryFile class (static method using standard stream added)
BinLDrivers_DocumentRetrievalDriver and BinLDrivers_DocumentStorageDriver classes use standard stream object as an argument

The main changes for XmlOcaf format applied in:
LDOMParser and LDOM_XmlWriter classes  use standard stream object as an argument

Unused class FSD_Archive and its siblings removed from MFC samples.
This commit is contained in:
ibs
2015-11-27 13:03:25 +03:00
committed by bugmaster
parent 77dbd1f155
commit 4ff92abe44
72 changed files with 2011 additions and 2462 deletions

View File

@@ -26,6 +26,7 @@
#include <CDM_MessageDriver.hxx>
#include <FSD_BinaryFile.hxx>
#include <FSD_FileHeader.hxx>
#include <OSD_OpenFile.hxx>
#include <PCDM_ReadWriter.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Type.hxx>
@@ -78,19 +79,39 @@ void BinLDrivers_DocumentStorageDriver::Write
SetIsError(Standard_False);
SetStoreStatus(PCDM_SS_OK);
myMsgDriver = theDocument -> Application() -> MessageDriver();
myFileName = theFileName;
std::ofstream aFileStream;
OSD_OpenStream (aFileStream, theFileName, std::ios::out | std::ios::binary);
if (aFileStream.is_open() && aFileStream.good())
{
Write (theDocument, aFileStream);
}
else
{
SetIsError (Standard_True);
SetStoreStatus(PCDM_SS_WriteFailure);
}
}
//=======================================================================
//function : Write
//purpose :
//=======================================================================
void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)& theDoc, Standard_OStream& theOStream)
{
myMsgDriver = theDoc->Application()->MessageDriver();
myMapUnsupported.Clear();
Handle(TDocStd_Document) aDoc =
Handle(TDocStd_Document)::DownCast(theDocument);
Handle(TDocStd_Document)::DownCast(theDoc);
if (aDoc.IsNull()) {
SetIsError(Standard_True);
SetStoreStatus(PCDM_SS_Doc_IsNull);
}
else {
// Open the file
TCollection_AsciiString aFileName (theFileName);
// First pass: collect empty labels, assign IDs to the types
if (myDrivers.IsNull())
myDrivers = AttributeDrivers (myMsgDriver);
@@ -98,7 +119,8 @@ void BinLDrivers_DocumentStorageDriver::Write
FirstPass (aData->Root());
// 1. Write info section (including types table)
WriteInfoSection(theDocument, aFileName);
WriteInfoSection (aDoc, theOStream);
myTypesMap.Clear();
if (IsError())
{
@@ -106,73 +128,58 @@ void BinLDrivers_DocumentStorageDriver::Write
return;
}
#if defined(_WIN32)
ofstream anOS ((const wchar_t*) theFileName.ToExtString(), ios::in | ios::binary | ios::ate);
#elif !defined(IRIX) // 10.10.2005
ofstream anOS (aFileName.ToCString(), ios::in | ios::binary | ios::ate);
#else
ofstream anOS (aFileName.ToCString(), ios::ate);
//ofstream anOS (aFileName.ToCString(), ios::out| ios::binary | ios::ate);
#endif
#ifdef OCCT_DEBUG
const Standard_Integer aP = (Standard_Integer) anOS.tellp();
cout << "POS = " << aP <<endl;
#endif
//#endif
if (anOS) {
// 2. Write the Table of Contents of Sections
BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
for (; anIterS.More(); anIterS.Next())
anIterS.ChangeValue().WriteTOC (anOS);
BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
for (; anIterS.More(); anIterS.Next())
anIterS.ChangeValue().WriteTOC (theOStream);
// Shapes Section is the last one, it indicates the end of the table.
BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
Standard_False);
aShapesSection.WriteTOC (anOS);
// Shapes Section is the last one, it indicates the end of the table.
BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
Standard_False);
aShapesSection.WriteTOC (theOStream);
// 3. Write document contents
// (Storage data to the stream)
myRelocTable.Clear();
myPAtt.Init();
// (Storage data to the stream)
myRelocTable.Clear();
myPAtt.Init();
// Write Doc structure
WriteSubTree (aData->Root(), anOS); // Doc is written
// Write Doc structure
WriteSubTree (aData->Root(), theOStream); // Doc is written
// 4. Write Shapes section
WriteShapeSection(aShapesSection, anOS);
WriteShapeSection (aShapesSection, theOStream);
// Write application-defined sections
for (anIterS.Init (mySections); anIterS.More(); anIterS.Next()) {
BinLDrivers_DocumentSection& aSection = anIterS.ChangeValue();
const Standard_Size aSectionOffset = (Standard_Size) anOS.tellp();
WriteSection (aSection.Name(), theDocument, anOS);
aSection.Write (anOS, aSectionOffset);
}
// End of processing: close structures and check the status
myPAtt.Destroy(); // free buffer
myEmptyLabels.Clear();
myMapUnsupported.Clear();
if (!myRelocTable.Extent()) {
// No objects written
#ifdef OCCT_DEBUG
WriteMessage ("BinLDrivers_DocumentStorageDriver, no objects written");
#endif
SetIsError(Standard_True);
SetStoreStatus(PCDM_SS_No_Obj);
}
myRelocTable.Clear();
// Write application-defined sections
for (anIterS.Init (mySections); anIterS.More(); anIterS.Next()) {
BinLDrivers_DocumentSection& aSection = anIterS.ChangeValue();
const Standard_Size aSectionOffset = (Standard_Size) theOStream.tellp();
WriteSection (aSection.Name(), aDoc, theOStream);
aSection.Write (theOStream, aSectionOffset);
}
if (!anOS) {
// End of processing: close structures and check the status
myPAtt.Destroy(); // free buffer
myEmptyLabels.Clear();
myMapUnsupported.Clear();
if (!myRelocTable.Extent()) {
// No objects written
#ifdef OCCT_DEBUG
WriteMessage ("BinLDrivers_DocumentStorageDriver, no objects written");
#endif
SetIsError(Standard_True);
SetStoreStatus(PCDM_SS_No_Obj);
}
myRelocTable.Clear();
if (!theOStream) {
// A problem with the stream
#ifdef OCCT_DEBUG
TCollection_ExtendedString anErrorStr ("Error: ");
WriteMessage (anErrorStr + "BinLDrivers_DocumentStorageDriver, Problem with the file stream, rdstate="
+ (Standard_Integer )anOS.rdstate());
+ (Standard_Integer )theOStream.rdstate());
#endif
SetIsError(Standard_True);
SetStoreStatus(PCDM_SS_WriteFailure);
@@ -361,77 +368,119 @@ void BinLDrivers_DocumentStorageDriver::FirstPass
#define START_TYPES "START_TYPES"
#define END_TYPES "END_TYPES"
void BinLDrivers_DocumentStorageDriver::WriteInfoSection
(const Handle(CDM_Document)& theDocument,
const TCollection_AsciiString& theFileName)
void BinLDrivers_DocumentStorageDriver::WriteInfoSection
(const Handle(CDM_Document)& theDoc,
Standard_OStream& theOStream)
{
FSD_BinaryFile aFileDriver;
if (aFileDriver.Open( theFileName, Storage_VSWrite ) != Storage_VSOk) {
WriteMessage (TCollection_ExtendedString("Error: Cannot open file ") +
theFileName);
SetIsError(Standard_True);
return;
}
// Magic number
theOStream.write (FSD_BinaryFile::MagicNumber(), strlen(FSD_BinaryFile::MagicNumber()));
FSD_FileHeader aHeader;
if (aFileDriver.BeginWriteInfoSection() == Storage_VSOk)
{
// add format
Handle(Storage_Data) theData = new Storage_Data;
PCDM_ReadWriter::WriteFileFormat( theData, theDocument );
PCDM_ReadWriter::Writer()->WriteReferenceCounter(theData,theDocument);
PCDM_ReadWriter::Writer()->WriteReferences(theData,theDocument,theFileName);
PCDM_ReadWriter::Writer()->WriteExtensions(theData,theDocument);
PCDM_ReadWriter::Writer()->WriteVersion(theData,theDocument);
aHeader.testindian = -1;
aHeader.binfo = -1;
aHeader.einfo = -1;
aHeader.bcomment = -1;
aHeader.ecomment = -1;
aHeader.btype = -1;
aHeader.etype = -1;
aHeader.broot = -1;
aHeader.eroot = -1;
aHeader.bref = -1;
aHeader.eref = -1;
aHeader.bdata = -1;
aHeader.edata = -1;
}
// add the types table
theData->AddToUserInfo(START_TYPES);
Standard_Integer i;
for (i = 1; i <= myTypesMap.Extent(); i++) {
Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver(i);
if (!aDriver.IsNull()) {
const TCollection_AsciiString& aTypeName = aDriver->TypeName();
theData->AddToUserInfo(aTypeName);
}
// aHeader.testindian
{
union {
char ti2[4];
Standard_Integer aResult;
} aWrapUnion;
aWrapUnion.ti2[0] = 1;
aWrapUnion.ti2[1] = 2;
aWrapUnion.ti2[2] = 3;
aWrapUnion.ti2[3] = 4;
aHeader.testindian = aWrapUnion.aResult;
}
// info section
aHeader.binfo = (Standard_Integer)theOStream.tellp();
// header section
aHeader.einfo = aHeader.binfo + FSD_BinaryFile::WriteHeader (theOStream, aHeader, Standard_True);
// add format
Handle(Storage_Data) theData = new Storage_Data;
PCDM_ReadWriter::WriteFileFormat (theData, theDoc);
PCDM_ReadWriter::Writer()->WriteReferenceCounter (theData, theDoc);
PCDM_ReadWriter::Writer()->WriteReferences (theData, theDoc, myFileName);
PCDM_ReadWriter::Writer()->WriteExtensions (theData, theDoc);
PCDM_ReadWriter::Writer()->WriteVersion (theData, theDoc);
// add the types table
theData->AddToUserInfo(START_TYPES);
for (Standard_Integer i = 1; i <= myTypesMap.Extent(); i++)
{
Handle(BinMDF_ADriver) aDriver = myDrivers->GetDriver(i);
if (!aDriver.IsNull())
{
const TCollection_AsciiString& aTypeName = aDriver->TypeName();
theData->AddToUserInfo (aTypeName);
}
theData->AddToUserInfo(END_TYPES);
// add document comments
TColStd_SequenceOfExtendedString aComments;
theDocument->Comments(aComments);
for (i = 1; i <= aComments.Length(); i++)
theData->AddToComments(aComments(i));
// Info
aFileDriver.WriteInfo
(1, // nbObj
BinLDrivers::StorageVersion(),
Storage_Schema::ICreationDate(),
TCollection_AsciiString(SchemaName(),'?'),
1, // schemaVersion
theData->ApplicationName(),
theData->ApplicationVersion(),
theData->DataType(),
theData->UserInfo()
);
// we write a complete header section: info and comments
aFileDriver.EndWriteInfoSection();
aFileDriver.BeginWriteCommentSection();
aFileDriver.WriteComment(theData->Comments());// <=== !!! szy - it was missed
aFileDriver.EndWriteCommentSection();
// here the location of info and comment sections is written
aFileDriver.EndWriteDataSection();
}
else {
WriteMessage(TCollection_ExtendedString("Error: Problem writing header "
"into file ") + theFileName);
SetIsError(Standard_True);
theData->AddToUserInfo(END_TYPES);
Standard_Integer aObjNb = 1;
Standard_Integer aShemaVer = 1;
aHeader.einfo += FSD_BinaryFile::WriteInfo (theOStream,
aObjNb,
BinLDrivers::StorageVersion(),
Storage_Schema::ICreationDate(),
TCollection_AsciiString(SchemaName(),'?'),
aShemaVer,
theData->ApplicationName(),
theData->ApplicationVersion(),
theData->DataType(),
theData->UserInfo(),
Standard_True); // only count the size of the section
// calculate comment section
TColStd_SequenceOfExtendedString aComments;
theDoc->Comments(aComments);
for (Standard_Integer i = 1; i <= aComments.Length(); i++)
{
theData->AddToComments (aComments(i));
}
#ifdef OCCT_DEBUG
const Standard_Integer aP = (Standard_Integer) aFileDriver.Tell();
cout << "POS = " << aP <<endl;
#endif
aFileDriver.Close();
aHeader.bcomment = aHeader.einfo;
aHeader.ecomment = aHeader.bcomment + FSD_BinaryFile::WriteComment(theOStream, theData->Comments(), Standard_True);
aHeader.edata = aHeader.ecomment;
// write header information
FSD_BinaryFile::WriteHeader (theOStream, aHeader);
// write info section
FSD_BinaryFile::WriteInfo (theOStream,
aObjNb,
BinLDrivers::StorageVersion(),
Storage_Schema::ICreationDate(),
TCollection_AsciiString(SchemaName(),'?'),
aShemaVer,
theData->ApplicationName(),
theData->ApplicationVersion(),
theData->DataType(),
theData->UserInfo());
// write the comments
FSD_BinaryFile::WriteComment(theOStream, theData->Comments());
}
//=======================================================================