From c006c985033c666b002f114794f8b0f42d332b37 Mon Sep 17 00:00:00 2001 From: ibs Date: Fri, 27 Nov 2015 13:03:25 +0300 Subject: [PATCH] 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. Conflicts: src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.hxx src/BinLDrivers/BinLDrivers_DocumentStorageDriver.hxx src/CDF/CDF_Application.hxx src/CDM/CDM_Document.hxx src/FSD/FSD_BinaryFile.cxx src/FSD/FSD_BinaryFile.hxx src/FSD/FSD_CmpFile.hxx src/FSD/FSD_File.hxx src/PCDM/PCDM.hxx src/PCDM/PCDM_ReadWriter.hxx src/PCDM/PCDM_Reader.hxx src/PCDM/PCDM_RetrievalDriver.hxx src/PCDM/PCDM_StorageDriver.hxx src/PCDM/PCDM_Writer.hxx src/Standard/Standard_Persistent.hxx src/StdResource/XCAF src/Storage/Storage_BaseDriver.hxx src/Storage/Storage_Data.hxx src/Storage/Storage_HeaderData.hxx src/Storage/Storage_InternalData.hxx src/Storage/Storage_Root.hxx src/Storage/Storage_RootData.hxx src/Storage/Storage_TypeData.hxx src/TDocStd/TDocStd_Application.cxx src/TDocStd/TDocStd_Application.hxx src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.hxx src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.hxx --- .../draw_test_harness/draw_test_harness.md | 10 +- .../BinLDrivers_DocumentRetrievalDriver.cxx | 157 +++-- .../BinLDrivers_DocumentStorageDriver.cxx | 289 +++++---- src/CDF/CDF_Application.cxx | 61 ++ src/DDF/DDF_IOStream.cxx | 9 + src/DDF/DDF_IOStream.hxx | 1 + src/DDocStd/DDocStd_ApplicationCommands.cxx | 59 +- src/FSD/FSD_BinaryFile.cxx | 592 ++++++++++++++++++ src/FSD/FSD_CmpFile.cxx | 10 + src/FSD/FSD_File.cxx | 10 + src/LDOM/LDOMParser.cxx | 48 +- src/LDOM/LDOMParser.hxx | 4 +- src/LDOM/LDOM_XmlReader.cxx | 37 +- src/LDOM/LDOM_XmlReader.hxx | 9 +- src/LDOM/LDOM_XmlWriter.cxx | 477 +++++++------- src/LDOM/LDOM_XmlWriter.hxx | 50 +- src/PCDM/PCDM.cxx | 45 ++ src/PCDM/PCDM_ReadWriter.cxx | 73 +++ src/PCDM/PCDM_RetrievalDriver.cxx | 12 + src/PCDM/PCDM_StorageDriver.cxx | 9 + src/StdResource/XCAF | 23 +- src/Storage/Storage_BaseDriver.cxx | 19 + src/TDocStd/TDocStd_Application.cxx | 126 ++++ .../XmlLDrivers_DocumentRetrievalDriver.cxx | 55 +- .../XmlLDrivers_DocumentStorageDriver.cxx | 79 ++- tests/bugs/caf/bug26229_1 | 44 ++ tests/bugs/caf/bug26229_2 | 44 ++ 27 files changed, 1785 insertions(+), 567 deletions(-) create mode 100644 tests/bugs/caf/bug26229_1 create mode 100644 tests/bugs/caf/bug26229_2 diff --git a/dox/user_guides/draw_test_harness/draw_test_harness.md b/dox/user_guides/draw_test_harness/draw_test_harness.md index 98afd46f33..e8f925d37e 100644 --- a/dox/user_guides/draw_test_harness/draw_test_harness.md +++ b/dox/user_guides/draw_test_harness/draw_test_harness.md @@ -2869,11 +2869,13 @@ Makes a list of documents handled during the session of the application. Syntax: ~~~~~ -Open path docname +Open path docname [-stream] ~~~~~ Retrieves the document of file **docname** in the path **path**. Overwrites the document, if it is already in session. +option -stream activates usage of alternative interface of OCAF persistence working with C++ streams instead of file names. + **Example:** ~~~~~ Open /myPath/myFile.std D @@ -2911,10 +2913,12 @@ Save D Syntax: ~~~~~ -SaveAs docname path +SaveAs docname path [-stream] ~~~~~ -Saves the active document in the file **docname** in the path **path**. Overwrites the file if it already exists. +Saves the active document in the file **docname** in the path **path**. Overwrites the file if it already exists. + +option -stream activates usage of alternative interface of OCAF persistence working with C++ streams instead of file names. **Example:** ~~~~~ diff --git a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx index 9c3781c785..f0bc9df615 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -78,14 +79,41 @@ void BinLDrivers_DocumentRetrievalDriver::Make (const Handle(PCDM_Document)&, //function : Read //purpose : //======================================================================= - -#define START_TYPES "START_TYPES" -#define END_TYPES "END_TYPES" - void BinLDrivers_DocumentRetrievalDriver::Read (const TCollection_ExtendedString& theFileName, const Handle(CDM_Document)& theNewDocument, const Handle(CDM_Application)& theApplication) +{ + std::ifstream aFileStream; + OSD_OpenStream (aFileStream, theFileName, std::ios::in | std::ios::binary); + + if (aFileStream.is_open() && aFileStream.good()) + { + Handle(Storage_Data) dData; + TCollection_ExtendedString aFormat = PCDM_ReadWriter::FileFormat (aFileStream, dData); + + Read (aFileStream, dData, theNewDocument, theApplication); + } + else + { + myReaderStatus = PCDM_RS_OpenError; + } +} + +#define MODIFICATION_COUNTER "MODIFICATION_COUNTER: " +#define REFERENCE_COUNTER "REFERENCE_COUNTER: " + +#define START_TYPES "START_TYPES" +#define END_TYPES "END_TYPES" + +//======================================================================= +//function : Read +//purpose : +//======================================================================= +void BinLDrivers_DocumentRetrievalDriver::Read (Standard_IStream& theIStream, + const Handle(Storage_Data)& theStorageData, + const Handle(CDM_Document)& theDoc, + const Handle(CDM_Application)& theApplication) { myReaderStatus = PCDM_RS_DriverFailure; myMsgDriver = theApplication -> MessageDriver(); @@ -94,7 +122,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read ("BinLDrivers_DocumentRetrievalDriver: "); Handle(TDocStd_Document) aDoc = - Handle(TDocStd_Document)::DownCast(theNewDocument); + Handle(TDocStd_Document)::DownCast(theDoc); if (aDoc.IsNull()) { #ifdef OCCT_DEBUG WriteMessage (aMethStr + "error: null document"); @@ -103,15 +131,29 @@ void BinLDrivers_DocumentRetrievalDriver::Read return; } - TCollection_AsciiString aFileName (theFileName); - - // 1. Read the information section + // 1. the information section Handle(Storage_HeaderData) aHeaderData; - Storage_Position anInfoSectionEnd = ReadInfoSection( aFileName, aHeaderData ); - if (!anInfoSectionEnd) { - WriteMessage (aMethStr + "error: file has invalid header"); - myReaderStatus = PCDM_RS_UnrecognizedFileFormat; - return; + + if (!theStorageData.IsNull()) + { + aHeaderData = theStorageData->HeaderData(); + } + + if (!aHeaderData.IsNull()) + { + for (Standard_Integer i = 1; i <= aHeaderData->UserInfo().Length(); i++) + { + const TCollection_AsciiString& aLine = aHeaderData->UserInfo().Value(i); + + if(aLine.Search(REFERENCE_COUNTER) != -1) + { + theDoc->SetReferenceCounter (aLine.Token(" ", 2).IntegerValue()); + } + else if(aLine.Search(MODIFICATION_COUNTER) != -1) + { + theDoc->SetModifications (aLine.Token(" ", 2).IntegerValue()); + } + } } // 1.a Version of writer @@ -178,23 +220,6 @@ void BinLDrivers_DocumentRetrievalDriver::Read WriteMessage (aTypeNames(i)); } - // Open the file stream -#ifdef _WIN32 - ifstream anIS ((const wchar_t*) theFileName.ToExtString(), ios::in | ios::binary); -#else - ifstream anIS (aFileName.ToCString()); -#endif - - if (!anIS) { - // Can not open file - WriteMessage (aMethStr + "error: can't open file " + theFileName); - myReaderStatus = PCDM_RS_OpenError; - return; - } - - // skip info section - anIS.seekg( (streampos) anInfoSectionEnd ); - // propagate the opened document version to data drivers PropagateDocumentVersion(aFileVer); @@ -211,30 +236,30 @@ void BinLDrivers_DocumentRetrievalDriver::Read if (aFileVer >= 3) { BinLDrivers_DocumentSection aSection; do { - BinLDrivers_DocumentSection::ReadTOC (aSection, anIS); + BinLDrivers_DocumentSection::ReadTOC (aSection, theIStream); mySections.Append(aSection); } while (!aSection.Name().IsEqual((Standard_CString)SHAPESECTION_POS)); - aDocumentPos = anIS.tellg(); // position of root label + aDocumentPos = theIStream.tellg(); // position of root label BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections); for (; anIterS.More(); anIterS.Next()) { BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue(); if (aCurSection.IsPostRead() == Standard_False) { - anIS.seekg ((streampos) aCurSection.Offset()); + theIStream.seekg ((streampos) aCurSection.Offset()); if (aCurSection.Name().IsEqual ((Standard_CString)SHAPESECTION_POS)) - ReadShapeSection (aCurSection, anIS); + ReadShapeSection (aCurSection, theIStream); else - ReadSection (aCurSection, theNewDocument, anIS); + ReadSection (aCurSection, theDoc, theIStream); } } } else { //aFileVer < 3 - aDocumentPos = anIS.tellg(); // position of root label + aDocumentPos = theIStream.tellg(); // position of root label // retrieve SHAPESECTION_POS string char aShapeSecLabel[SIZEOFSHAPELABEL + 1]; aShapeSecLabel[SIZEOFSHAPELABEL] = 0x00; - anIS.read ((char*)&aShapeSecLabel, SIZEOFSHAPELABEL);// SHAPESECTION_POS + theIStream.read ((char*)&aShapeSecLabel, SIZEOFSHAPELABEL);// SHAPESECTION_POS TCollection_AsciiString aShapeLabel(aShapeSecLabel); // detect if a file was written in old fashion (version 2 without shapes) // and if so then skip reading ShapeSection @@ -248,7 +273,7 @@ void BinLDrivers_DocumentRetrievalDriver::Read // retrieve ShapeSection Position Standard_Integer aShapeSectionPos; // go to ShapeSection - anIS.read ((char*)&aShapeSectionPos, sizeof(Standard_Integer)); + theIStream.read ((char*)&aShapeSectionPos, sizeof(Standard_Integer)); #if DO_INVERSE aShapeSectionPos = InverseInt (aShapeSectionPos); @@ -257,26 +282,26 @@ void BinLDrivers_DocumentRetrievalDriver::Read cout <<"aShapeSectionPos = " <Root()); + Standard_Integer nbRead = ReadSubTree (theIStream, aData->Root()); myPAtt.Destroy(); // free buffer myRelocTable.Clear(); myMapUnsupported.Clear(); @@ -291,12 +316,12 @@ void BinLDrivers_DocumentRetrievalDriver::Read // Read Sections (post-reading type) if (aFileVer >= 3) { - BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections); - for (; anIterS.More(); anIterS.Next()) { - BinLDrivers_DocumentSection& aCurSection = anIterS.ChangeValue(); + BinLDrivers_VectorOfDocumentSection::Iterator aSectIter (mySections); + for (; aSectIter.More(); aSectIter.Next()) { + BinLDrivers_DocumentSection& aCurSection = aSectIter.ChangeValue(); if (aCurSection.IsPostRead()) { - anIS.seekg ((streampos) aCurSection.Offset()); - ReadSection (aCurSection, theNewDocument, anIS); + theIStream.seekg ((streampos) aCurSection.Offset()); + ReadSection (aCurSection, theDoc, theIStream); } } } @@ -406,38 +431,6 @@ Handle(BinMDF_ADriverTable) BinLDrivers_DocumentRetrievalDriver::AttributeDriver return BinLDrivers::AttributeDrivers (theMessageDriver); } -//======================================================================= -//function : ReadInfoSection -//purpose : Read the info section of theFile, return a file -// position corresponding to the info section end -//======================================================================= - -Storage_Position BinLDrivers_DocumentRetrievalDriver::ReadInfoSection - (const TCollection_AsciiString& theFileName, - Handle(Storage_HeaderData)& theData) -{ - TCollection_ExtendedString aMsg - ( "BinLDrivers_DocumentRetrievalDriver: error: "); - - FSD_BinaryFile aFileDriver; - Storage_Position aPos = 0; - if (aFileDriver.Open( theFileName, Storage_VSRead ) == Storage_VSOk) - { - Storage_Schema aSchema; - theData = aSchema.ReadHeaderSection( aFileDriver ); - - if (theData->ErrorStatus() == Storage_VSOk) - aPos = aFileDriver.Tell(); - else - WriteMessage( aMsg + theData->ErrorStatusExtension() ); - } - else - WriteMessage( aMsg + "can not open file " + theFileName); - - aFileDriver.Close(); - - return aPos; -} //======================================================================= //function : WriteMessage diff --git a/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx b/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx index 1599144851..872fe023dc 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -68,19 +69,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); @@ -88,7 +109,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()) { @@ -96,73 +118,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 <Root(), anOS); // Doc is written +// Write Doc structure + WriteSubTree (aData->Root(), theOStream); // Doc is written // 4. Write Shapes section - WriteShapeSection(aShapesSection, anOS); - -// 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 + 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) theOStream.tellp(); + WriteSection (aSection.Name(), aDoc, theOStream); + aSection.Write (theOStream, 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"); + WriteMessage ("BinLDrivers_DocumentStorageDriver, no objects written"); #endif - SetIsError(Standard_True); - SetStoreStatus(PCDM_SS_No_Obj); - } - myRelocTable.Clear(); + SetIsError(Standard_True); + SetStoreStatus(PCDM_SS_No_Obj); } + myRelocTable.Clear(); - if (!anOS) { + 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); @@ -351,77 +358,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; + + { + 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; + } + + // 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; } - if (aFileDriver.BeginWriteInfoSection() == Storage_VSOk) + // 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++) { - // 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); - - // 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); - } + 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 <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()); + } //======================================================================= diff --git a/src/CDF/CDF_Application.cxx b/src/CDF/CDF_Application.cxx index bbabfd17f8..e025af9cda 100644 --- a/src/CDF/CDF_Application.cxx +++ b/src/CDF/CDF_Application.cxx @@ -381,6 +381,67 @@ Handle(PCDM_Reader) CDF_Application::Reader (const TCollection_ExtendedString& a return ReaderFromFormat (theFormat); } +//======================================================================= +//function : Read +//purpose : +//======================================================================= +Handle(CDM_Document) CDF_Application::Read (Standard_IStream& theIStream) +{ + Handle(CDM_Document) aDoc; + Handle(Storage_Data) dData; + + TCollection_ExtendedString aFormat; + + try + { + OCC_CATCH_SIGNALS + + aFormat = PCDM_ReadWriter::FileFormat (theIStream, dData); + } + catch (Standard_Failure) + { + myRetrievableStatus = PCDM_RS_FormatFailure; + + Standard_SStream aMsg; + aMsg << Standard_Failure::Caught() << endl; + Standard_Failure::Raise(aMsg); + } + + if (aFormat.IsEmpty()) + { + myRetrievableStatus = PCDM_RS_FormatFailure; + return aDoc; + } + + // 1. use a format name to detect plugin corresponding to the format to continue reading + Handle(PCDM_Reader) aReader = ReaderFromFormat (aFormat); + + // 2. create document with the detected reader + aDoc = aReader->CreateDocument(); + + // 3. read the content of theIStream to aDoc + try + { + OCC_CATCH_SIGNALS + + aReader->Read (theIStream, dData, aDoc, this); + } + catch (Standard_Failure) + { + myRetrievableStatus = aReader->GetStatus(); + if (myRetrievableStatus > PCDM_RS_AlreadyRetrieved) + { + Standard_SStream aMsg; + aMsg << Standard_Failure::Caught() << endl; + Standard_Failure::Raise(aMsg); + } + } + + myRetrievableStatus = aReader->GetStatus(); + + return aDoc; +} + //======================================================================= //function : FindReaderFromFormat //purpose : diff --git a/src/DDF/DDF_IOStream.cxx b/src/DDF/DDF_IOStream.cxx index 46cd875399..00e40935c9 100644 --- a/src/DDF/DDF_IOStream.cxx +++ b/src/DDF/DDF_IOStream.cxx @@ -702,6 +702,15 @@ void DDF_IOStream::ReadInfo(Standard_Integer& nbObj, } } +//======================================================================= +//function : ReadCompleteInfo +//purpose : +//======================================================================= +void DDF_IOStream::ReadCompleteInfo( Standard_IStream& /*theIStream*/, Handle(Storage_Data)& /*theData*/ ) +{ + +} + //======================================================================= //function : EndReadInfoSection //purpose : diff --git a/src/DDF/DDF_IOStream.hxx b/src/DDF/DDF_IOStream.hxx index 38fc0a1b9d..979752d22a 100644 --- a/src/DDF/DDF_IOStream.hxx +++ b/src/DDF/DDF_IOStream.hxx @@ -67,6 +67,7 @@ static Storage_Error IsGoodFileType(istream* anIStream) ; Storage_Error EndWriteInfoSection() ; Storage_Error BeginReadInfoSection() ; void ReadInfo(Standard_Integer& nbObj,TCollection_AsciiString& dbVersion,TCollection_AsciiString& date,TCollection_AsciiString& schemaName,TCollection_AsciiString& schemaVersion,TCollection_ExtendedString& appName,TCollection_AsciiString& appVersion,TCollection_ExtendedString& objectType,TColStd_SequenceOfAsciiString& userInfo) ; + void ReadCompleteInfo (Standard_IStream& theIStream, Handle(Storage_Data)& theData); Storage_Error EndReadInfoSection() ; Storage_Error BeginWriteCommentSection() ; void WriteComment(const TColStd_SequenceOfExtendedString& userComments) ; diff --git a/src/DDocStd/DDocStd_ApplicationCommands.cxx b/src/DDocStd/DDocStd_ApplicationCommands.cxx index c0a9f068a9..b6c70dc90b 100644 --- a/src/DDocStd/DDocStd_ApplicationCommands.cxx +++ b/src/DDocStd/DDocStd_ApplicationCommands.cxx @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -129,7 +130,7 @@ static Standard_Integer DDocStd_Open (Draw_Interpretor& di, Standard_Integer nb, const char** a) { - if (nb == 3) { + if (nb >= 3) { TCollection_ExtendedString path (a[1]); Handle(TDocStd_Application) A; if (!DDocStd::Find(A)) return 1; @@ -139,7 +140,30 @@ static Standard_Integer DDocStd_Open (Draw_Interpretor& di, di <<"document " << insession << " is already in session" << "\n"; return 0; } - PCDM_ReaderStatus theStatus = A->Open(path,D); + PCDM_ReaderStatus theStatus; + + Standard_Boolean anUseStream = Standard_False; + for ( Standard_Integer i = 3; i < nb; i++ ) + { + if (!strcmp (a[i], "-stream")) + { + di << "standard SEEKABLE stream is used\n"; + anUseStream = Standard_True; + break; + } + } + + if (anUseStream) + { + std::ifstream aFileStream; + OSD_OpenStream (aFileStream, path, std::ios::in | std::ios::binary); + + theStatus = A->Open (aFileStream, D); + } + else + { + theStatus = A->Open(path,D); + } if (theStatus == PCDM_RS_OK && !D.IsNull()) { Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(D); TDataStd_Name::Set(D->GetData()->Root(),a[2]); @@ -214,13 +238,36 @@ static Standard_Integer DDocStd_SaveAs (Draw_Interpretor& di, Standard_Integer nb, const char** a) { - if (nb == 3) { + if (nb >= 3) { Handle(TDocStd_Document) D; if (!DDocStd::GetDocument(a[1],D)) return 1; TCollection_ExtendedString path (a[2]); Handle(TDocStd_Application) A; if (!DDocStd::Find(A)) return 1; - PCDM_StoreStatus theStatus = A->SaveAs(D,path); + PCDM_StoreStatus theStatus; + + Standard_Boolean anUseStream = Standard_False; + for ( Standard_Integer i = 3; i < nb; i++ ) + { + if (!strcmp (a[i], "-stream")) + { + di << "standard SEEKABLE stream is used\n"; + anUseStream = Standard_True; + break; + } + } + + if (anUseStream) + { + std::ofstream aFileStream; + OSD_OpenStream (aFileStream, path, std::ios::out | std::ios::binary); + theStatus = A->SaveAs (D, aFileStream); + } + else + { + theStatus = A->SaveAs(D,path); + } + if (theStatus != PCDM_SS_OK ) { switch ( theStatus ) { case PCDM_SS_DriverFailure: { @@ -456,11 +503,11 @@ void DDocStd::ApplicationCommands(Draw_Interpretor& theCommands) __FILE__, DDocStd_NewDocument, g); theCommands.Add("Open", - "Open path docname", + "Open path docname [-stream]", __FILE__, DDocStd_Open, g); theCommands.Add("SaveAs", - "SaveAs DOC path", + "SaveAs DOC path [-stream]", __FILE__, DDocStd_SaveAs, g); theCommands.Add("Save", diff --git a/src/FSD/FSD_BinaryFile.cxx b/src/FSD/FSD_BinaryFile.cxx index bb90cd171f..6bf7e61a05 100644 --- a/src/FSD/FSD_BinaryFile.cxx +++ b/src/FSD/FSD_BinaryFile.cxx @@ -238,6 +238,32 @@ Storage_BaseDriver& FSD_BinaryFile::PutInteger(const Standard_Integer aValue) return *this; } +//======================================================================= +//function : PutInteger +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::PutInteger (Standard_OStream& theOStream, + const Standard_Integer theValue, + const Standard_Boolean theOnlyCount) +{ +#if OCCT_BINARY_FILE_DO_INVERSE + Standard_Integer t = InverseInt (theValue); +#else + Standard_Integer t = theValue; +#endif + + if (!theOnlyCount) + { + theOStream.write ((char*)&t, sizeof(Standard_Integer)); + if (theOStream.fail()) + { + Storage_StreamWriteError::Raise(); + } + } + + return sizeof(Standard_Integer); +} + //======================================================================= //function : PutBoolean //purpose : @@ -304,6 +330,24 @@ Storage_BaseDriver& FSD_BinaryFile::GetReference(Standard_Integer& aValue) return *this; } +//======================================================================= +//function : GetReference +//purpose : ----------------- PUBLIC : GET +//======================================================================= +void FSD_BinaryFile::GetReference(Standard_IStream& theIStream, Standard_Integer& aValue) +{ + theIStream.read ((char*)&aValue, sizeof(Standard_Integer)); + + if (theIStream.gcount() != sizeof(Standard_Integer)) + { + Storage_StreamTypeMismatchError::Raise(); + } + +#if OCCT_BINARY_FILE_DO_INVERSE + aValue = InverseInt (aValue); +#endif +} + //======================================================================= //function : GetCharacter //purpose : @@ -346,6 +390,25 @@ Storage_BaseDriver& FSD_BinaryFile::GetInteger(Standard_Integer& aValue) return *this; } +//======================================================================= +//function : GetInteger +//purpose : +//======================================================================= +void FSD_BinaryFile::GetInteger (Standard_IStream& theIStream, Standard_Integer& theValue) +{ + + theIStream.read ((char*)&theValue, sizeof(Standard_Integer)); + + if (theIStream.gcount() != sizeof(Standard_Integer)) + { + Storage_StreamTypeMismatchError::Raise(); + } + +#if OCCT_BINARY_FILE_DO_INVERSE + theValue = InverseInt (theValue); +#endif +} + //======================================================================= //function : GetBoolean //purpose : @@ -461,6 +524,43 @@ void FSD_BinaryFile::WriteInfo(const Standard_Integer nbObj, } } +//======================================================================= +//function : WriteInfo +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::WriteInfo (Standard_OStream& theOStream, + const Standard_Integer theObjNb, + const TCollection_AsciiString& theStoreVer, + const TCollection_AsciiString& theCreationDate, + const TCollection_AsciiString& theSchemaName, + const TCollection_AsciiString& theSchemaVersion, + const TCollection_ExtendedString& theAppName, + const TCollection_AsciiString& theAppVer, + const TCollection_ExtendedString& theDataType, + const TColStd_SequenceOfAsciiString& theUserInfo, + const Standard_Boolean theOnlyCount) +{ + Standard_Integer anInfoSize = 0; + + anInfoSize += PutInteger (theOStream, theObjNb, theOnlyCount); + anInfoSize += WriteString(theOStream, theStoreVer, theOnlyCount); + anInfoSize += WriteString(theOStream, theCreationDate, theOnlyCount); + anInfoSize += WriteString(theOStream, theSchemaName, theOnlyCount); + anInfoSize += WriteString(theOStream, theSchemaVersion, theOnlyCount); + anInfoSize += WriteExtendedString(theOStream, theAppName, theOnlyCount); + anInfoSize += WriteString(theOStream, theAppVer, theOnlyCount); + anInfoSize += WriteExtendedString(theOStream, theDataType, theOnlyCount); + + Standard_Integer i = theUserInfo.Length(); + anInfoSize += PutInteger(theOStream, i, theOnlyCount); + + for (i = 1; i <= theUserInfo.Length(); i++) { + anInfoSize += WriteString (theOStream, theUserInfo.Value(i), theOnlyCount); + } + + return anInfoSize; +} + //======================================================================= //function : EndWriteInfoSection //purpose : read @@ -473,6 +573,17 @@ Storage_Error FSD_BinaryFile::EndWriteInfoSection() return Storage_VSOk; } +//======================================================================= +//function : EndWriteInfoSection +//purpose : read +//======================================================================= +Storage_Error FSD_BinaryFile::EndWriteInfoSection(Standard_OStream& theOStream) +{ + myHeader.einfo = (Standard_Integer)theOStream.tellp(); + + return Storage_VSOk; +} + //======================================================================= //function : BeginReadInfoSection //purpose : @@ -531,6 +642,118 @@ void FSD_BinaryFile::ReadInfo(Standard_Integer& nbObj, } } +//======================================================================= +//function : ReadInfo +//purpose : +//======================================================================= +void FSD_BinaryFile::ReadCompleteInfo (Standard_IStream& theIStream, Handle(Storage_Data)& theData) +{ + FSD_FileHeader aHeaderPos; + ReadHeader(theIStream, aHeaderPos); + + if (theData.IsNull()) + { + theData = new Storage_Data(); + } + + Handle(Storage_InternalData) iData = theData->InternalData(); + Handle(Storage_TypeData) tData = theData->TypeData(); + Handle(Storage_RootData) rData = theData->RootData(); + Handle(Storage_HeaderData) hData = theData->HeaderData(); + + ReadHeaderData (theIStream, hData); + + Handle(Storage_HArrayOfCallBack) theCallBack; + + while (theIStream.good() && !theIStream.eof()) + { + Standard_Integer aPos = (Standard_Integer)theIStream.tellg(); + + if (aPos >= aHeaderPos.edata) + { + break; + } + else if (aPos == aHeaderPos.bcomment) + { + TColStd_SequenceOfExtendedString mComment; + ReadComment (theIStream, mComment); + + for (Standard_Integer i = 1; i <= mComment.Length(); i++) + { + hData->AddToComments (mComment.Value(i)); + } + + iData->ReadArray() = new Storage_HPArray(1, theData->NumberOfObjects()); + } + else if (aPos == aHeaderPos.btype) + { + Standard_Integer aTypeSectionSize = TypeSectionSize (theIStream); + theCallBack = new Storage_HArrayOfCallBack (1, aTypeSectionSize); + + TCollection_AsciiString aTypeName; + Standard_Integer aTypeNum; + + for (Standard_Integer i = 1; i <= aTypeSectionSize; i++) + { + ReadTypeInformations (theIStream, aTypeNum, aTypeName); + tData->AddType (aTypeName,aTypeNum); + + theCallBack->SetValue (aTypeNum, NULL); + } + } + else if (aPos == aHeaderPos.broot) + { + Standard_Integer aRootSectionSize = RootSectionSize(theIStream); + + Standard_Integer aRef; + TCollection_AsciiString aRootName, aTypeName; + Handle(Storage_Root) aRoot; + Handle(Standard_Persistent) aPer; + + for (Standard_Integer i = 1; i <= aRootSectionSize; i++) + { + ReadRoot (theIStream, aRootName, aRef, aTypeName); + + aRoot = new Storage_Root(aRootName, aPer); + aRoot->SetReference(aRef); + aRoot->SetType(aTypeName); + rData->AddRoot(aRoot); + } + } + else if (aPos == aHeaderPos.bref) + { + Standard_Integer aRefSectionSize = RefSectionSize (theIStream); + + Standard_Integer aTypeNum, aRef = 0; + + for (Standard_Integer i = 1; i <= aRefSectionSize; i++) + { + ReadReferenceType (theIStream, aRef, aTypeNum); + + iData->ReadArray()->ChangeValue(aRef) = theCallBack->Value(aTypeNum)->New(); + + if (!iData->ReadArray()->ChangeValue(aRef).IsNull()) + { + iData->ReadArray()->ChangeValue(aRef)->TypeNum() = aTypeNum; + } + } + } + else if (aPos == aHeaderPos.bdata) + { + // + } + } + + Handle(Storage_HSeqOfRoot) aRoots = rData->Roots(); + for(Standard_Integer i = 1; i <= theData->NumberOfRoots(); i++) + { + const Handle(Storage_Root)& aCurRoot = aRoots->Value(i); + rData->UpdateRoot (aCurRoot->Name(), iData->ReadArray()->Value (aCurRoot->Reference())); + } + + iData->Clear(); +} + //======================================================================= //function : EndReadInfoSection //purpose : COMMENTS SECTION @@ -554,6 +777,16 @@ Storage_Error FSD_BinaryFile::BeginWriteCommentSection() return Storage_VSOk; } +//======================================================================= +//function : BeginWriteCommentSection +//purpose : +//======================================================================= +Storage_Error FSD_BinaryFile::BeginWriteCommentSection(Standard_OStream& theOStream) +{ + myHeader.bcomment = (Standard_Integer)theOStream.tellp(); + return Storage_VSOk; +} + //======================================================================= //function : WriteComment //purpose : @@ -570,6 +803,26 @@ void FSD_BinaryFile::WriteComment(const TColStd_SequenceOfExtendedString& aCom) } } +//======================================================================= +//function : WriteComment +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::WriteComment (Standard_OStream& theOStream, + const TColStd_SequenceOfExtendedString& theComments, + const Standard_Boolean theOnlyCount) +{ + Standard_Integer aCommentSize = 0; + + Standard_Integer aSize = theComments.Length(); + aCommentSize += PutInteger(theOStream, aSize, theOnlyCount); + + for (Standard_Integer i = 1; i <= aSize; i++) { + aCommentSize += WriteExtendedString (theOStream, theComments.Value(i), theOnlyCount); + } + + return aCommentSize; +} + //======================================================================= //function : EndWriteCommentSection //purpose : read @@ -582,6 +835,17 @@ Storage_Error FSD_BinaryFile::EndWriteCommentSection() return Storage_VSOk; } +//======================================================================= +//function : EndWriteCommentSection +//purpose : read +//======================================================================= +Storage_Error FSD_BinaryFile::EndWriteCommentSection (Standard_OStream& theOStream) +{ + myHeader.ecomment = (Standard_Integer)theOStream.tellp(); + + return Storage_VSOk; +} + //======================================================================= //function : BeginReadCommentSection //purpose : ---------------- COMMENTS : READ @@ -610,6 +874,23 @@ void FSD_BinaryFile::ReadComment(TColStd_SequenceOfExtendedString& aCom) } } +//======================================================================= +//function : ReadComment +//purpose : +//======================================================================= +void FSD_BinaryFile::ReadComment (Standard_IStream& theIStream, TColStd_SequenceOfExtendedString& aCom) +{ + TCollection_ExtendedString line; + Standard_Integer len,i; + + GetInteger(theIStream, len); + for (i = 1; i <= len && theIStream.good(); i++) + { + ReadExtendedString(theIStream, line); + aCom.Append(line); + } +} + //======================================================================= //function : EndReadCommentSection //purpose : @@ -691,6 +972,18 @@ Standard_Integer FSD_BinaryFile::TypeSectionSize() return i; } +//======================================================================= +//function : TypeSectionSize +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::TypeSectionSize(Standard_IStream& theIStream) +{ + Standard_Integer i; + + GetInteger(theIStream, i); + return i; +} + //======================================================================= //function : ReadTypeInformations //purpose : @@ -702,6 +995,16 @@ void FSD_BinaryFile::ReadTypeInformations(Standard_Integer& typeNum,TCollection_ ReadString(typeName); } +//======================================================================= +//function : ReadTypeInformations +//purpose : +//======================================================================= +void FSD_BinaryFile::ReadTypeInformations(Standard_IStream& theIStream, Standard_Integer& typeNum,TCollection_AsciiString& typeName) +{ + GetInteger(theIStream, typeNum); + ReadString(theIStream, typeName); +} + //======================================================================= //function : EndReadTypeSection //purpose : ROOT SECTION @@ -784,6 +1087,18 @@ Standard_Integer FSD_BinaryFile::RootSectionSize() return i; } +//======================================================================= +//function : RootSectionSize +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::RootSectionSize (Standard_IStream& theIStream) +{ + Standard_Integer i; + + GetInteger(theIStream, i); + return i; +} + //======================================================================= //function : ReadRoot //purpose : @@ -796,6 +1111,17 @@ void FSD_BinaryFile::ReadRoot(TCollection_AsciiString& rootName, Standard_Intege ReadString(rootType); } +//======================================================================= +//function : ReadRoot +//purpose : +//======================================================================= +void FSD_BinaryFile::ReadRoot (Standard_IStream& theIStream, TCollection_AsciiString& rootName, Standard_Integer& aRef,TCollection_AsciiString& rootType) +{ + GetReference(theIStream, aRef); + ReadString(theIStream, rootName); + ReadString(theIStream, rootType); +} + //======================================================================= //function : EndReadRootSection //purpose : REF SECTION @@ -877,6 +1203,18 @@ Standard_Integer FSD_BinaryFile::RefSectionSize() return i; } +//======================================================================= +//function : RefSectionSize +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::RefSectionSize (Standard_IStream& theIStream) +{ + Standard_Integer i; + + GetInteger(theIStream, i); + return i; +} + //======================================================================= //function : ReadReferenceType //purpose : @@ -889,6 +1227,16 @@ void FSD_BinaryFile::ReadReferenceType(Standard_Integer& reference, GetInteger(typeNum); } +//======================================================================= +//function : ReadReferenceType +//purpose : +//======================================================================= +void FSD_BinaryFile::ReadReferenceType (Standard_IStream& theIStream, Standard_Integer& reference, Standard_Integer& typeNum) +{ + GetReference (theIStream, reference); + GetInteger (theIStream, typeNum); +} + //======================================================================= //function : EndReadRefSection //purpose : DATA SECTION @@ -1063,6 +1411,32 @@ void FSD_BinaryFile::WriteString(const TCollection_AsciiString& aString) } } +//======================================================================= +//function : WriteString +//purpose : write string at the current position. +//======================================================================= +Standard_Integer FSD_BinaryFile::WriteString (Standard_OStream& theOStream, + const TCollection_AsciiString& theString, + const Standard_Boolean theOnlyCount) +{ + Standard_Integer aNumAndStrLen, anAsciiStrLen; + + anAsciiStrLen = aNumAndStrLen = theString.Length(); + + aNumAndStrLen += PutInteger (theOStream, anAsciiStrLen, theOnlyCount); + + if (anAsciiStrLen > 0 && !theOnlyCount) + { + theOStream.write (theString.ToCString(), theString.Length()); + if (theOStream.fail()) + { + Storage_StreamWriteError::Raise(); + } + } + + return aNumAndStrLen; +} + //======================================================================= //function : ReadString //purpose : read string from the current position. @@ -1085,6 +1459,44 @@ void FSD_BinaryFile::ReadString(TCollection_AsciiString& aString) } } +//======================================================================= +//function : ReadString +//purpose : read string from the current position. +//======================================================================= +void FSD_BinaryFile::ReadString (Standard_IStream& theIStream, TCollection_AsciiString& aString) +{ + Standard_Integer size = 0; + + GetInteger(theIStream, size); + + if (size > 0) + { + Standard_Character *c = (Standard_Character *)Standard::Allocate((size+1) * sizeof(Standard_Character)); + + if (!theIStream.good()) + { + Storage_StreamReadError::Raise(); + } + + theIStream.read (c, size); + + if (theIStream.gcount() != size) + { + Storage_StreamReadError::Raise(); + } + + c[size] = '\0'; + + aString = c; + + Standard::Free(c); + } + else + { + aString.Clear(); + } +} + //======================================================================= //function : WriteExtendedString //purpose : write string at the current position. @@ -1118,6 +1530,49 @@ void FSD_BinaryFile::WriteExtendedString(const TCollection_ExtendedString& aStri } } +//======================================================================= +//function : WriteExtendedString +//purpose : write string at the current position. +//======================================================================= +Standard_Integer FSD_BinaryFile::WriteExtendedString (Standard_OStream& theOStream, + const TCollection_ExtendedString& theString, + const Standard_Boolean theOnlyCount) +{ + Standard_Integer aNumAndStrLen, anExtStrLen; + anExtStrLen = theString.Length(); + + aNumAndStrLen = anExtStrLen * sizeof(Standard_ExtCharacter); + aNumAndStrLen += PutInteger (theOStream, anExtStrLen, theOnlyCount); + + if (anExtStrLen > 0 && !theOnlyCount) + { + Standard_ExtString anExtStr; +#if OCCT_BINARY_FILE_DO_INVERSE + TCollection_ExtendedString aCopy = theString; + anExtStr = aCopy.ToExtString(); + + Standard_PExtCharacter pChar; + // + pChar = (Standard_PExtCharacter)anExtStr; + + for (Standard_Integer i = 0; i < anExtStrLen; i++) + { + pChar[i] = InverseExtChar (pChar[i]); + } +#else + anExtStr = theString.ToExtString(); +#endif + + theOStream.write((char*)anExtStr, sizeof(Standard_ExtCharacter)*theString.Length()); + if (theOStream.fail()) + { + Storage_StreamWriteError::Raise(); + } + } + + return aNumAndStrLen; +} + //======================================================================= //function : ReadExtendedString //purpose : read string from the current position. @@ -1146,6 +1601,49 @@ void FSD_BinaryFile::ReadExtendedString(TCollection_ExtendedString& aString) } } +//======================================================================= +//function : ReadExtendedString +//purpose : read string from the current position. +//======================================================================= +void FSD_BinaryFile::ReadExtendedString (Standard_IStream& theIStream, TCollection_ExtendedString& aString) +{ + Standard_Integer size = 0; + + GetInteger (theIStream, size); + + if (size > 0) + { + Standard_ExtCharacter *c = (Standard_ExtCharacter *)Standard::Allocate((size+1) * sizeof(Standard_ExtCharacter)); + + if (!theIStream.good()) + { + Storage_StreamReadError::Raise(); + } + + theIStream.read ((char *)c, size*sizeof(Standard_ExtCharacter)); + + if (theIStream.gcount() != size) + { + Storage_StreamReadError::Raise(); + } + + c[size] = '\0'; + +#if OCCT_BINARY_FILE_DO_INVERSE + for (Standard_Integer i=0; i < size; i++) + { + c[i] = InverseExtChar (c[i]); + } +#endif + aString = c; + Standard::Free(c); + } + else + { + aString.Clear(); + } +} + //======================================================================= //function : WriteHeader //purpose : @@ -1168,6 +1666,33 @@ void FSD_BinaryFile::WriteHeader() PutInteger(myHeader.edata); } +//======================================================================= +//function : WriteHeader +//purpose : +//======================================================================= +Standard_Integer FSD_BinaryFile::WriteHeader (Standard_OStream& theOStream, + const FSD_FileHeader& theHeader, + const Standard_Boolean theOnlyCount) +{ + Standard_Integer aHeaderSize = 0; + + aHeaderSize += PutInteger (theOStream, theHeader.testindian, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.binfo, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.einfo, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.bcomment, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.ecomment, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.btype, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.etype, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.broot, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.eroot, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.bref, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.eref, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.bdata, theOnlyCount); + aHeaderSize += PutInteger (theOStream, theHeader.edata, theOnlyCount); + + return aHeaderSize; +} + //======================================================================= //function : ReadHeader //purpose : @@ -1190,6 +1715,73 @@ void FSD_BinaryFile::ReadHeader() GetInteger(myHeader.edata); } +//======================================================================= +//function : ReadHeader +//purpose : +//======================================================================= + +void FSD_BinaryFile::ReadHeader(Standard_IStream& theIStream, FSD_FileHeader& theFileHeader) +{ + GetInteger (theIStream, theFileHeader.testindian); + GetInteger (theIStream, theFileHeader.binfo); + GetInteger (theIStream, theFileHeader.einfo); + GetInteger (theIStream, theFileHeader.bcomment); + GetInteger (theIStream, theFileHeader.ecomment); + GetInteger (theIStream, theFileHeader.btype); + GetInteger (theIStream, theFileHeader.etype); + GetInteger (theIStream, theFileHeader.broot); + GetInteger (theIStream, theFileHeader.eroot); + GetInteger (theIStream, theFileHeader.bref); + GetInteger (theIStream, theFileHeader.eref); + GetInteger (theIStream, theFileHeader.bdata); + GetInteger (theIStream, theFileHeader.edata); +} + +//======================================================================= +//function : ReadHeaderData +//purpose : +//======================================================================= +void FSD_BinaryFile::ReadHeaderData( Standard_IStream& theIStream, const Handle(Storage_HeaderData)& theHeaderData ) +{ + // read info + TCollection_AsciiString uinfo,mStorageVersion,mDate,mSchemaName,mSchemaVersion,mApplicationVersion; + TCollection_ExtendedString mApplicationName,mDataType; + TColStd_SequenceOfAsciiString mUserInfo; + Standard_Integer mNBObj; + + FSD_BinaryFile::GetInteger (theIStream, mNBObj); + FSD_BinaryFile::ReadString (theIStream, mStorageVersion); + FSD_BinaryFile::ReadString (theIStream, mDate); + FSD_BinaryFile::ReadString (theIStream, mSchemaName); + FSD_BinaryFile::ReadString (theIStream, mSchemaVersion); + FSD_BinaryFile::ReadExtendedString(theIStream, mApplicationName); + FSD_BinaryFile::ReadString (theIStream, mApplicationVersion); + FSD_BinaryFile::ReadExtendedString(theIStream, mDataType); + + Standard_Integer len = 0; + TCollection_AsciiString line; + + FSD_BinaryFile::GetInteger(theIStream, len); + + for (Standard_Integer i = 1; i <= len && theIStream.good(); i++) + { + FSD_BinaryFile::ReadString (theIStream, line); + mUserInfo.Append(line); + } + + theHeaderData->SetNumberOfObjects(mNBObj); + theHeaderData->SetStorageVersion(mStorageVersion); + theHeaderData->SetCreationDate(mDate); + theHeaderData->SetSchemaName(mSchemaName); + theHeaderData->SetSchemaVersion(mSchemaVersion); + theHeaderData->SetApplicationName(mApplicationName); + theHeaderData->SetApplicationVersion(mApplicationVersion); + theHeaderData->SetDataType(mDataType); + + for (Standard_Integer i = 1; i <= mUserInfo.Length(); i++) { + theHeaderData->AddToUserInfo(mUserInfo.Value(i)); + } +} //======================================================================= //function : Tell diff --git a/src/FSD/FSD_CmpFile.cxx b/src/FSD/FSD_CmpFile.cxx index f30fa25afd..a3f8c2791d 100644 --- a/src/FSD/FSD_CmpFile.cxx +++ b/src/FSD/FSD_CmpFile.cxx @@ -748,6 +748,16 @@ void FSD_CmpFile::ReadInfo(Standard_Integer& nbObj, } } +//======================================================================= +//function : ReadCompleteInfo +//purpose : +// +//======================================================================= +void FSD_CmpFile::ReadCompleteInfo( Standard_IStream& /*theIStream*/, Handle(Storage_Data)& /*theData*/) +{ + +} + //======================================================================= //function : EndReadInfoSection //purpose : COMMENTS SECTION diff --git a/src/FSD/FSD_File.cxx b/src/FSD/FSD_File.cxx index bf62a62c45..5b6461ea65 100644 --- a/src/FSD/FSD_File.cxx +++ b/src/FSD/FSD_File.cxx @@ -741,6 +741,16 @@ void FSD_File::ReadInfo(Standard_Integer& nbObj, } } +//======================================================================= +//function : ReadCompleteInfo +//purpose : +// +//======================================================================= +void FSD_File::ReadCompleteInfo( Standard_IStream& /*theIStream*/, Handle(Storage_Data)& /*theData*/) +{ + +} + //======================================================================= //function : EndReadInfoSection //purpose : COMMENTS SECTION diff --git a/src/LDOM/LDOMParser.cxx b/src/LDOM/LDOMParser.cxx index 0d28c7bd51..02e9f88992 100644 --- a/src/LDOM/LDOMParser.cxx +++ b/src/LDOM/LDOMParser.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #ifdef WNT @@ -53,13 +54,14 @@ static inline #endif LDOM_XmlReader::RecordType ReadRecord (LDOM_XmlReader& aReader, + Standard_IStream& theIStream, LDOM_OSStream& aData) { #ifdef LDOM_PARSER_TRACE static aCounter = 0; ++ aCounter; #endif - const LDOM_XmlReader::RecordType aType = aReader.ReadRecord (aData); + const LDOM_XmlReader::RecordType aType = aReader.ReadRecord (theIStream, aData); #ifdef LDOM_PARSER_TRACE static FILE * ff = NULL; TCollection_AsciiString aTraceFileName; @@ -117,10 +119,10 @@ Standard_Boolean LDOMParser::parse (istream& anInput) // Create the Reader instance if (myReader) delete myReader; - myReader = new LDOM_XmlReader (anInput, myDocument, myError); + myReader = new LDOM_XmlReader (myDocument, myError); // Parse - return ParseDocument(); + return ParseDocument (anInput); } //======================================================================= @@ -130,30 +132,18 @@ Standard_Boolean LDOMParser::parse (istream& anInput) Standard_Boolean LDOMParser::parse (const char * const aFileName) { - // Open the DOM Document - myDocument = new LDOM_MemManager (20000); - myError.Clear (); + std::ifstream aFileStream; + OSD_OpenStream (aFileStream, aFileName, std::ios::in); - // Open the file -#ifdef _WIN32 - TCollection_ExtendedString aFileNameW(aFileName, Standard_True); - int aFile = _wopen ((const wchar_t*) aFileNameW.ToExtString(), O_RDONLY); -#else - int aFile = open (aFileName, O_RDONLY); -#endif - if (aFile < 0) { + if (aFileStream.good()) + { + return parse (aFileStream); + } + else + { myError = "Fatal XML error: Cannot open XML file"; return Standard_True; } - - // Create the Reader instance - if (myReader) delete myReader; - myReader = new LDOM_XmlReader (aFile, myDocument, myError); - - // Parse - Standard_Boolean isError = ParseDocument(); - close (aFile); - return isError; } //======================================================================= @@ -161,14 +151,14 @@ Standard_Boolean LDOMParser::parse (const char * const aFileName) //purpose : parse the whole document (abstracted from the XML source) //======================================================================= -Standard_Boolean LDOMParser::ParseDocument () +Standard_Boolean LDOMParser::ParseDocument (istream& theIStream) { Standard_Boolean isError = Standard_False; Standard_Boolean isElement = Standard_False; Standard_Boolean isDoctype = Standard_False; for(;;) { - LDOM_XmlReader::RecordType aType = ReadRecord (*myReader, myCurrentData); + LDOM_XmlReader::RecordType aType = ReadRecord (*myReader, theIStream, myCurrentData); switch (aType) { case LDOM_XmlReader::XML_HEADER: if (isDoctype || isElement) { @@ -211,7 +201,7 @@ Standard_Boolean LDOMParser::ParseDocument () myError = "User abort at startElement()"; break; } - isError = ParseElement (); + isError = ParseElement (theIStream); if (isError) break; continue; } @@ -241,7 +231,7 @@ Standard_Boolean LDOMParser::ParseDocument () //purpose : parse one element, given the type of its XML presentation //======================================================================= -Standard_Boolean LDOMParser::ParseElement () +Standard_Boolean LDOMParser::ParseElement (Standard_IStream& theIStream) { Standard_Boolean isError = Standard_False; const LDOM_BasicElement * aParent = &myReader->GetElement(); @@ -250,7 +240,7 @@ Standard_Boolean LDOMParser::ParseElement () LDOM_Node::NodeType aLocType; LDOMBasicString aTextValue; char *aTextStr; - LDOM_XmlReader::RecordType aType = ReadRecord (* myReader, myCurrentData); + LDOM_XmlReader::RecordType aType = ReadRecord (* myReader, theIStream, myCurrentData); switch (aType) { case LDOM_XmlReader::XML_UNKNOWN: isError = Standard_True; @@ -275,7 +265,7 @@ Standard_Boolean LDOMParser::ParseElement () myError = "User abort at startElement()"; break; } - isError = ParseElement (); + isError = ParseElement (theIStream); break; case LDOM_XmlReader::XML_END_ELEMENT: { diff --git a/src/LDOM/LDOMParser.hxx b/src/LDOM/LDOMParser.hxx index d350e8fa1b..bf99d1c6c9 100644 --- a/src/LDOM/LDOMParser.hxx +++ b/src/LDOM/LDOMParser.hxx @@ -73,9 +73,9 @@ class LDOMParser private: // ---------- PRIVATE METHODS ---------- - Standard_Boolean ParseDocument (); + Standard_Boolean ParseDocument (Standard_IStream& theIStream); - Standard_Boolean ParseElement (); + Standard_Boolean ParseElement (Standard_IStream& theIStream); // ---------- PRIVATE (PROHIBITED) METHODS ---------- diff --git a/src/LDOM/LDOM_XmlReader.cxx b/src/LDOM/LDOM_XmlReader.cxx index a4a5f11bb0..e240602d6c 100644 --- a/src/LDOM/LDOM_XmlReader.cxx +++ b/src/LDOM/LDOM_XmlReader.cxx @@ -63,32 +63,10 @@ static Standard_Boolean isName (const char * aString, //purpose : Constructor (file descriptor) //======================================================================= -LDOM_XmlReader::LDOM_XmlReader (const int theFileDes, +LDOM_XmlReader::LDOM_XmlReader ( const Handle(LDOM_MemManager)& theDocument, TCollection_AsciiString& theErrorString) : myEOF (Standard_False), - myFileDes (theFileDes), - myIStream (cin), // just a placeholder, myIStream will never be used anyway - myError (theErrorString), - myDocument (theDocument), - myElement (NULL), - myLastChild(NULL), - myPtr (&myBuffer[0]), - myEndPtr (&myBuffer[0]) -{ -} - -//======================================================================= -//function : LDOM_XmlReader() -//purpose : Constructor (istream) -//======================================================================= - -LDOM_XmlReader::LDOM_XmlReader (istream& theInput, - const Handle(LDOM_MemManager)& theDocument, - TCollection_AsciiString& theErrorString) -: myEOF (Standard_False), - myFileDes (FILE_NONVALUE), - myIStream (theInput), myError (theErrorString), myDocument (theDocument), myElement (NULL), @@ -103,8 +81,8 @@ LDOM_XmlReader::LDOM_XmlReader (istream& theInput, //purpose : Read a record from XML file //======================================================================= -LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord - (LDOM_OSStream& theData) +LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord (Standard_IStream& theIStream, + LDOM_OSStream& theData) { theData.Clear(); myError.Clear(); @@ -136,14 +114,9 @@ LDOM_XmlReader::RecordType LDOM_XmlReader::ReadRecord // Read the full buffer and reset start and end buffer pointers myPtr = &myBuffer[0]; Standard_Size aNBytes; - if (myFileDes != FILE_NONVALUE) - aNBytes = read (myFileDes, &myBuffer[aBytesRest], - XML_BUFFER_SIZE - aBytesRest); - else { - myIStream.read (&myBuffer[aBytesRest], + theIStream.read (&myBuffer[aBytesRest], XML_BUFFER_SIZE - aBytesRest); - aNBytes = (Standard_Size)myIStream.gcount(); - } + aNBytes = (Standard_Size)theIStream.gcount(); if (aNBytes == 0) myEOF = Standard_True; // END-OF-FILE myEndPtr = &myBuffer[aBytesRest + aNBytes]; diff --git a/src/LDOM/LDOM_XmlReader.hxx b/src/LDOM/LDOM_XmlReader.hxx index 90550a6664..f40de60740 100644 --- a/src/LDOM/LDOM_XmlReader.hxx +++ b/src/LDOM/LDOM_XmlReader.hxx @@ -47,15 +47,12 @@ class LDOM_XmlReader }; // ---------- PUBLIC METHODS ---------- - LDOM_XmlReader (const int aFileDes, const Handle(LDOM_MemManager)& aDocument, + LDOM_XmlReader (const Handle(LDOM_MemManager)& aDocument, TCollection_AsciiString& anErrorString); // Constructor - takes a file descriptor for input - - LDOM_XmlReader (istream& anInput, const Handle(LDOM_MemManager)& aDocument, - TCollection_AsciiString& anErrorString); // Constructor - takes an istream for input - RecordType ReadRecord (LDOM_OSStream& theData); + RecordType ReadRecord (Standard_IStream& theIStream, LDOM_OSStream& theData); // reading a markup or other element of XML format LDOM_BasicElement& GetElement () const { return * myElement; } @@ -78,8 +75,6 @@ class LDOM_XmlReader // ---------- PRIVATE FIELDS ---------- Standard_Boolean myEOF; - int myFileDes; // alternative 1: file descriptor - istream& myIStream; // alternative 2: istream TCollection_AsciiString & myError; Handle(LDOM_MemManager) myDocument; LDOM_BasicElement * myElement; diff --git a/src/LDOM/LDOM_XmlWriter.cxx b/src/LDOM/LDOM_XmlWriter.cxx index bf0968555c..342bd24d42 100644 --- a/src/LDOM/LDOM_XmlWriter.cxx +++ b/src/LDOM/LDOM_XmlWriter.cxx @@ -93,326 +93,373 @@ #define chLatin_Y 'Y' #define chLatin_Z 'Z' -static const LXMLCh gEndElement[] = { chOpenAngle, chForwardSlash, chNull }; -static const LXMLCh gEndElement1[]= { chForwardSlash, chNull }; -//static const LXMLCh gEndPI[] = { chQuestion, chCloseAngle, chNull }; -//static const LXMLCh gStartPI[] = { chOpenAngle, chQuestion, chNull }; -static const LXMLCh gXMLDecl1[] = +static const char gEndElement[] = { chOpenAngle, chForwardSlash, chNull }; +static const char gEndElement1[]= { chForwardSlash, chNull }; + +static const char gXMLDecl1[] = { chOpenAngle, chQuestion, chLatin_x, chLatin_m, chLatin_l , chSpace, chLatin_v, chLatin_e, chLatin_r, chLatin_s, chLatin_i , chLatin_o, chLatin_n, chEqual, chDoubleQuote, chNull }; -static const LXMLCh gXMLDecl2[] = +static const char gXMLDecl2[] = { chDoubleQuote, chSpace, chLatin_e, chLatin_n, chLatin_c , chLatin_o, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chEqual , chDoubleQuote, chNull }; -/* -static const LXMLCh gXMLDecl3[] = -{ chDoubleQuote, chSpace, chLatin_s, chLatin_t, chLatin_a - , chLatin_n, chLatin_d, chLatin_a, chLatin_l, chLatin_o - , chLatin_n, chLatin_e, chEqual, chDoubleQuote, chNull -}; -*/ -static const LXMLCh gXMLDecl4[] = + +static const char gXMLDecl4[] = { chDoubleQuote, chQuestion, chCloseAngle , chLF, chNull }; -static const LXMLCh gStartCDATA[] = +static const char gStartCDATA[] = { chOpenAngle, chBang, chOpenSquare, chLatin_C, chLatin_D, chLatin_A, chLatin_T, chLatin_A, chOpenSquare, chNull }; -static const LXMLCh gEndCDATA[] = +static const char gEndCDATA[] = { chCloseSquare, chCloseSquare, chCloseAngle, chNull }; -static const LXMLCh gStartComment[] = +static const char gStartComment[] = { chOpenAngle, chBang, chDash, chDash, chNull }; -static const LXMLCh gEndComment[] = +static const char gEndComment[] = { chDash, chDash, chCloseAngle, chNull }; -/* -static const LXMLCh gStartDoctype[] = -{ chOpenAngle, chBang, chLatin_D, chLatin_O, chLatin_C, chLatin_T, - chLatin_Y, chLatin_P, chLatin_E, chSpace, chNull -}; -static const LXMLCh gPublic[] = -{ chLatin_P, chLatin_U, chLatin_B, chLatin_L, chLatin_I, - chLatin_C, chSpace, chDoubleQuote, chNull -}; -static const LXMLCh gSystem[] = -{ chLatin_S, chLatin_Y, chLatin_S, chLatin_T, chLatin_E, - chLatin_M, chSpace, chDoubleQuote, chNull -}; -static const LXMLCh gStartEntity[] = -{ chOpenAngle, chBang, chLatin_E, chLatin_N, chLatin_T, chLatin_I, - chLatin_T, chLatin_Y, chSpace, chNull -}; -static const LXMLCh gNotation[] = -{ chLatin_N, chLatin_D, chLatin_A, chLatin_T, chLatin_A, - chSpace, chDoubleQuote, chNull -}; -*/ -static LXMLCh * getEncodingName (const LXMLCh * theEncodingName) +static char* getEncodingName (const char* theEncodingName) { - const LXMLCh * anEncoding = theEncodingName; + const char* anEncoding = theEncodingName; if (theEncodingName == NULL) { -// anEncoding = // US-ASCII -// { chLatin_U, chLatin_S, chDash, chLatin_A, chLatin_S, chLatin_C, chLatin_I, -// chLatin_I, chNull }; - static const LXMLCh anUTFEncoding [] = // UTF-8 - { chLatin_U, chLatin_T, chLatin_F, chDash, chEight, chNull }; + static const char anUTFEncoding [] = {chLatin_U, chLatin_T, chLatin_F, chDash, chEight, chNull}; anEncoding = anUTFEncoding; } + Standard_Integer aLen = 0; while (anEncoding[aLen++] != chNull); - LXMLCh * aResult = new LXMLCh [aLen]; - memcpy (aResult, anEncoding, aLen * sizeof (LXMLCh)); + + char * aResult = new char [aLen]; + memcpy (aResult, anEncoding, aLen * sizeof (char)); + return aResult; } //======================================================================= -//function : LH3D_LXMLWriter() -//purpose : Constructor +//function : LDOM_XmlWriter +//purpose : //======================================================================= -LDOM_XmlWriter::LDOM_XmlWriter (FILE * aFile, - const LXMLCh * theEncoding) - : myFile (aFile), - myEncodingName (::getEncodingName (theEncoding)), - myIndent (0), - myCurIndent (0), - myABuffer (NULL), - myABufferLen (0) -{} +LDOM_XmlWriter::LDOM_XmlWriter (const char * theEncoding) + : myEncodingName (::getEncodingName (theEncoding)), + myIndent (0), + myCurIndent (0), + myABuffer (NULL), + myABufferLen (0) +{ + ; +} //======================================================================= //function : ~LDOM_XmlWriter //purpose : Destructor //======================================================================= - LDOM_XmlWriter::~LDOM_XmlWriter () { delete [] myEncodingName; - if (myABuffer != NULL) delete [] myABuffer; -} -//======================================================================= -//function : operator << -//purpose : -//======================================================================= - -LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LDOM_Document& aDoc) -{ - const char * anXMLversion = "1.0"; - * this << gXMLDecl1 << anXMLversion - << gXMLDecl2 << myEncodingName << gXMLDecl4; - - return (* this << aDoc.getDocumentElement()); -} - -//======================================================================= -//function : operator << -//purpose : Stream out an LDOMString -//======================================================================= - -inline LDOM_XmlWriter& LDOM_XmlWriter::operator << - (const LDOMBasicString& aString) -{ - switch (aString.Type()) { - case LDOMBasicString::LDOM_Integer: - { - Standard_Integer aValue; - aString.GetInteger (aValue); - fprintf (myFile, "%d", aValue); - break; - } - case LDOMBasicString::LDOM_AsciiHashed: // attr names and element tags - case LDOMBasicString::LDOM_AsciiDocClear: - { - const char * str = aString.GetString(); - if (str) { - const Standard_Size aLen = strlen (str); - if (aLen > 0) fwrite (str, aLen, 1, myFile); - } - } - break; - case LDOMBasicString::LDOM_AsciiFree: - case LDOMBasicString::LDOM_AsciiDoc: - { - const char * str = aString.GetString(); - if (str) { - Standard_Integer aLen; - char * encStr = LDOM_CharReference::Encode(str, aLen, Standard_False); - if (aLen > 0) fwrite (encStr, aLen, 1, myFile); - if (encStr != str) delete [] encStr; - } - } - default: ; + if (myABuffer != NULL) + { + delete [] myABuffer; } - return * this; } //======================================================================= -//function : operator<<() -//purpose : Stream out a char *. +//function : Write +//purpose : //======================================================================= -inline LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LXMLCh * aString) +void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const LDOM_Document& aDoc) { - Standard_Size aLength = strlen (aString); - if (aLength > 0) fwrite ((void *) aString, aLength, 1, myFile); - return * this; -} + Write (theOStream, gXMLDecl1); -//======================================================================= -//function : operator<<() -//purpose : Stream out a character. -//======================================================================= -inline LDOM_XmlWriter& LDOM_XmlWriter::operator << (const LXMLCh aChar) -{ - fputc (aChar, myFile); - return * this; -} + const char * anXMLversion = "1.0"; + Write (theOStream, anXMLversion); -//======================================================================= -//function : WriteAttribute() -//purpose : Stream out an XML attribute. -//======================================================================= -void LDOM_XmlWriter::WriteAttribute (const LDOM_Node& theAtt) -{ - int aLength; - const char * aName = theAtt.getNodeName().GetString(); - const LDOMString aValueStr = theAtt.getNodeValue(); + Write (theOStream, gXMLDecl2); + Write (theOStream, myEncodingName); + Write (theOStream, gXMLDecl4); - // Integer attribute value - if (aValueStr.Type() == LDOMBasicString::LDOM_Integer) { - Standard_Integer anIntValue; - aValueStr.GetInteger (anIntValue); - aLength = (Standard_Integer) (20 + strlen (aName)); - if (aLength > myABufferLen) { - if (myABuffer != NULL) delete [] myABuffer; - myABuffer = new char [aLength+1]; - myABufferLen = aLength; - } - sprintf (myABuffer, "%c%s%c%c%d%c", chSpace, aName, - chEqual, chDoubleQuote, anIntValue, chDoubleQuote); - aLength = (Standard_Integer) strlen (myABuffer); - - // String attribute value - } else { - const char * aValue = aValueStr.GetString(); - char * encStr; - if (aValueStr.Type() == LDOMBasicString::LDOM_AsciiDocClear) { - encStr = (char *) aValue; - aLength = (Standard_Integer) (4 + strlen (aValue) + strlen (aName)); - } else { - encStr = LDOM_CharReference::Encode (aValue, aLength, Standard_True); - aLength += (Standard_Integer) (4 + strlen (aName)); - } - if (aLength > myABufferLen) { - if (myABuffer != NULL) delete [] myABuffer; - myABuffer = new char [aLength+1]; - myABufferLen = aLength; - } - sprintf (myABuffer, "%c%s%c%c%s%c", chSpace, aName, - chEqual, chDoubleQuote, encStr, chDoubleQuote); - if (encStr != aValue) delete [] encStr; - } - fwrite ((void *) myABuffer, aLength, 1, myFile); + Write (theOStream, aDoc.getDocumentElement()); } //======================================================================= -//function : operator<<() -//purpose : Stream out a DOM node, and, recursively, all of its children. -// This function is the heart of writing a DOM tree out as XML source. -// Give it a document node and it will do the whole thing. +//function : Write +//purpose : //======================================================================= -LDOM_XmlWriter& LDOM_XmlWriter::operator<< (const LDOM_Node& theNodeToWrite) +void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const LDOM_Node& theNode) { // Get the name and value out for convenience - LDOMString aNodeName = theNodeToWrite.getNodeName(); - LDOMString aNodeValue = theNodeToWrite.getNodeValue(); -// unsigned long dwLent = aNodeValue.length(); + LDOMString aNodeName = theNode.getNodeName(); + LDOMString aNodeValue = theNode.getNodeValue(); - switch (theNodeToWrite.getNodeType()) + switch (theNode.getNodeType()) { - case LDOM_Node::TEXT_NODE : - * this << aNodeValue; + case LDOM_Node::TEXT_NODE : + Write (theOStream, aNodeValue); break; - case LDOM_Node::ELEMENT_NODE : + case LDOM_Node::ELEMENT_NODE : { const int aMaxNSpaces = 40; - static LXMLCh aSpaces [] = { + static char aSpaces [] = { chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chSpace, chOpenAngle, chNull }; - const LXMLCh * anIndentString = &aSpaces [aMaxNSpaces - myCurIndent]; - if (anIndentString < &aSpaces[0]) anIndentString = &aSpaces[0]; + const char * anIndentString = &aSpaces [aMaxNSpaces - myCurIndent]; + + if (anIndentString < &aSpaces[0]) + { + anIndentString = &aSpaces[0]; + } // Output the element start tag. - * this << anIndentString << aNodeName.GetString(); + Write (theOStream, anIndentString); + Write (theOStream, aNodeName.GetString()); - // Output any attributes of this element - const LDOM_Element& anElemToWrite = (const LDOM_Element&) theNodeToWrite; - LDOM_NodeList aListAtt = anElemToWrite.GetAttributesList (); + // Output any attributes of this element + const LDOM_Element& anElemToWrite = (const LDOM_Element&)theNode; + LDOM_NodeList aListAtt = anElemToWrite.GetAttributesList(); Standard_Integer aListInd = aListAtt.getLength(); - while (aListInd--) { + + while (aListInd--) + { LDOM_Node aChild = aListAtt.item (aListInd); - WriteAttribute (aChild); + WriteAttribute (theOStream, aChild); } // Test for the presence of children - LDOM_Node aChild = theNodeToWrite.getFirstChild(); + LDOM_Node aChild = theNode.getFirstChild(); if (aChild != 0) { // There are children. Close start-tag, and output children. - * this << chCloseAngle; + Write (theOStream, chCloseAngle); if (aChild.getNodeType() == LDOM_Node::ELEMENT_NODE && myIndent > 0) - * this << chLF; + { + Write(theOStream, chLF); + } + Standard_Boolean isChildElem = Standard_False; while( aChild != 0) { isChildElem = (aChild.getNodeType() == LDOM_Node::ELEMENT_NODE); - if (isChildElem) myCurIndent += myIndent; - *this << aChild; - if (isChildElem) myCurIndent -= myIndent; - do aChild = aChild.getNextSibling(); - while (aChild.getNodeType() == LDOM_Node::ATTRIBUTE_NODE); + if (isChildElem) + { + myCurIndent += myIndent; + } + + Write(theOStream, aChild); + + if (isChildElem) + { + myCurIndent -= myIndent; + } + + do + { + aChild = aChild.getNextSibling(); + } while (aChild.getNodeType() == LDOM_Node::ATTRIBUTE_NODE); } + // Done with children. Output the end tag. - // if (isChildElem) - * this << anIndentString - << gEndElement1 << aNodeName.GetString() << chCloseAngle; + { + Write (theOStream, anIndentString); + Write (theOStream, gEndElement1); + Write (theOStream, aNodeName.GetString()); + Write (theOStream, chCloseAngle); + } else - * this << gEndElement << aNodeName.GetString() << chCloseAngle; + { + Write (theOStream, gEndElement); + Write (theOStream, aNodeName.GetString()); + Write (theOStream, chCloseAngle); + } } else { // There were no children. Output the short form close of // the element start tag, making it an empty-element tag. - * this << chForwardSlash << chCloseAngle; + Write (theOStream, chForwardSlash); + Write (theOStream, chCloseAngle); } + if (myIndent > 0) - * this << chLF; + { + Write (theOStream, chLF); + } break; } case LDOM_Node::CDATA_SECTION_NODE: { - * this << gStartCDATA << aNodeValue << gEndCDATA; + Write (theOStream, gStartCDATA); + Write (theOStream, aNodeValue); + Write (theOStream, gEndCDATA); break; } case LDOM_Node::COMMENT_NODE: { - * this << gStartComment << aNodeValue << gEndComment; + Write (theOStream, gStartComment); + Write (theOStream, aNodeValue); + Write (theOStream, gEndComment); break; } default: #ifndef WNT cerr << "Unrecognized node type = " - << (long)theNodeToWrite.getNodeType() << endl + << (long)theNode.getNodeType() << endl #endif ; } - return *this; +} + +//======================================================================= +//function : +//purpose : Stream out an LDOMString +//======================================================================= +void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const LDOMBasicString& theString) +{ + switch (theString.Type()) + { + case LDOMBasicString::LDOM_Integer: + { + Standard_Integer aValue; + theString.GetInteger (aValue); + + TCollection_AsciiString aStrValue (aValue); + theOStream.write(aStrValue.ToCString(), strlen (aStrValue.ToCString())); + + break; + } + case LDOMBasicString::LDOM_AsciiHashed: // attr names and element tags + case LDOMBasicString::LDOM_AsciiDocClear: + { + const char* aStr = theString.GetString(); + if (aStr) + { + const Standard_Size aLen = strlen (aStr); + if (aLen > 0) + { + theOStream.write(aStr, aLen); + } + } + } + break; + case LDOMBasicString::LDOM_AsciiFree: + case LDOMBasicString::LDOM_AsciiDoc: + { + const char* aStr = theString.GetString(); + if (aStr) + { + Standard_Integer aLen; + char* encStr = LDOM_CharReference::Encode (aStr, aLen, Standard_False); + if (aLen > 0) + { + theOStream.write(encStr, aLen); + } + + if (encStr != aStr) + { + delete [] encStr; + } + } + } + default: ; + } +} + +//======================================================================= +//function : Write +//purpose : Stream out a char +//======================================================================= +void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const char theChar) +{ + theOStream.write (&theChar, sizeof(char)); +} + +//======================================================================= +//function : Write +//purpose : Stream out a char * +//======================================================================= +void LDOM_XmlWriter::Write (Standard_OStream& theOStream, const char * theString) +{ + Standard_Size aLength = strlen (theString); + if (aLength > 0) + { + theOStream.write (theString, aLength); + } +} + +//======================================================================= +//function : WriteAttribute() +//purpose : Stream out an XML attribute. +//======================================================================= +void LDOM_XmlWriter::WriteAttribute (Standard_OStream& theOStream, const LDOM_Node& theAtt) +{ + const char* aName = theAtt.getNodeName().GetString(); + const LDOMString aValueStr = theAtt.getNodeValue(); + + int aLength = 0; + + // Integer attribute value + if (aValueStr.Type() == LDOMBasicString::LDOM_Integer) + { + Standard_Integer anIntValue; + aValueStr.GetInteger (anIntValue); + + aLength = (Standard_Integer)(20 + strlen (aName)); + if (aLength > myABufferLen) + { + if (myABuffer != NULL) + { + delete [] myABuffer; + } + + myABuffer = new char [aLength+1]; + myABufferLen = aLength; + } + sprintf (myABuffer, "%c%s%c%c%d%c", chSpace, aName, chEqual, chDoubleQuote, anIntValue, chDoubleQuote); + aLength = (Standard_Integer)strlen (myABuffer); + + + } + else // String attribute value + { + char* encStr; + const char* aValue = aValueStr.GetString(); + if (aValueStr.Type() == LDOMBasicString::LDOM_AsciiDocClear) + { + encStr = (char *) aValue; + aLength = (Standard_Integer) (4 + strlen (aValue) + strlen (aName)); + } + else + { + encStr = LDOM_CharReference::Encode (aValue, aLength, Standard_True); + aLength += (Standard_Integer) (4 + strlen (aName)); + } + + if (aLength > myABufferLen) + { + if (myABuffer != NULL) + { + delete [] myABuffer; + } + + myABuffer = new char [aLength+1]; + myABufferLen = aLength; + } + + sprintf (myABuffer, "%c%s%c%c%s%c", chSpace, aName, chEqual, chDoubleQuote, encStr, chDoubleQuote); + + if (encStr != aValue) + { + delete [] encStr; + } + } + + theOStream.write (myABuffer, aLength); } diff --git a/src/LDOM/LDOM_XmlWriter.hxx b/src/LDOM/LDOM_XmlWriter.hxx index 9965e5c363..4ef47d4ae8 100644 --- a/src/LDOM/LDOM_XmlWriter.hxx +++ b/src/LDOM/LDOM_XmlWriter.hxx @@ -16,63 +16,51 @@ #ifndef LDOM_XmlWriter_HeaderFile #define LDOM_XmlWriter_HeaderFile +#include #include #include -typedef char LXMLCh; - class LDOM_Document; class LDOM_Node; class LDOMBasicString; class LDOM_XmlWriter { - public: - - Standard_EXPORT LDOM_XmlWriter (FILE * aFile, const char * theEncoding= NULL); - // Constructor +public: + Standard_EXPORT LDOM_XmlWriter (const char* theEncoding = NULL); + Standard_EXPORT ~LDOM_XmlWriter (); - // Destructor - void SetIndentation (const Standard_Integer theIndent) { myIndent=theIndent; } // Set indentation for output (by default 0) + void SetIndentation (const Standard_Integer theIndent) { myIndent = theIndent; } - Standard_EXPORT LDOM_XmlWriter& operator<< (const LDOM_Document& aDoc); + Standard_EXPORT void Write (Standard_OStream& theOStream, const LDOM_Document& theDoc); - Standard_EXPORT LDOM_XmlWriter& operator<< (const LDOM_Node& toWrite); - // ostream << DOM_Node // Stream out a DOM node, and, recursively, all of its children. This // function is the heart of writing a DOM tree out as XML source. Give it // a document node and it will do the whole thing. + Standard_EXPORT void Write (Standard_OStream& theOStream, const LDOM_Node& theNode); - private: - - void WriteAttribute (const LDOM_Node& theAtt); - - LDOM_XmlWriter& operator<< (const LDOMBasicString&); - // Stream out LDOM String - - inline LDOM_XmlWriter& operator<< (const LXMLCh * toWrite); - // Stream out a character string. Doing this requires that we first transcode - // to char * form in the default code page for the system - - inline LDOM_XmlWriter& operator << (const LXMLCh aChar); +private: LDOM_XmlWriter (const LDOM_XmlWriter& anOther); - // Copy constructor - prohibited LDOM_XmlWriter& operator = (const LDOM_XmlWriter& anOther); - // Assignment operator - prohibited + + void Write (Standard_OStream& theOStream, const LDOMBasicString& theString); + void Write (Standard_OStream& theOStream, const char* theString); + void Write (Standard_OStream& theOStream, const char theChar); + + void WriteAttribute (Standard_OStream& theOStream, const LDOM_Node& theAtt); private: - FILE * myFile; - LXMLCh * myEncodingName; - Standard_Integer myIndent; - Standard_Integer myCurIndent; - char * myABuffer; // for WriteAttribute() - Standard_Integer myABufferLen; // for WriteAttribute() + char* myEncodingName; + Standard_Integer myIndent; + Standard_Integer myCurIndent; + char* myABuffer; + Standard_Integer myABufferLen; }; #endif diff --git a/src/PCDM/PCDM.cxx b/src/PCDM/PCDM.cxx index 876775d054..448d65d608 100644 --- a/src/PCDM/PCDM.cxx +++ b/src/PCDM/PCDM.cxx @@ -97,3 +97,48 @@ PCDM_TypeOfFileDriver PCDM::FileDriverType(const TCollection_AsciiString& aFileN return PCDM_TOFD_Unknown; } } + +//======================================================================= +//function : FileDriverType +//purpose : +//======================================================================= + +PCDM_TypeOfFileDriver PCDM::FileDriverType (Standard_IStream& theIStream, PCDM_BaseDriverPointer& theBaseDriver) +{ + TCollection_AsciiString aReadMagicNumber; + + if (theIStream.good()) + { + streampos aDocumentPos = theIStream.tellg(); + + // read magic number from the file + aReadMagicNumber = Storage_BaseDriver::ReadMagicNumber (theIStream); + + if (!theIStream.good()) + { + theIStream.clear(); + } + + theIStream.seekg(aDocumentPos); + } + + if(aReadMagicNumber == FSD_CmpFile::MagicNumber()) + { + theBaseDriver = new FSD_CmpFile; + return PCDM_TOFD_CmpFile; + } + else if (aReadMagicNumber == FSD_File::MagicNumber()) + { + theBaseDriver = new FSD_File; + return PCDM_TOFD_File; + } + else if (aReadMagicNumber == FSD_BinaryFile::MagicNumber()) + { + theBaseDriver = new FSD_BinaryFile; + return PCDM_TOFD_File; + } + + theBaseDriver = NULL; + return PCDM_TOFD_Unknown; +} + diff --git a/src/PCDM/PCDM_ReadWriter.cxx b/src/PCDM/PCDM_ReadWriter.cxx index 92df812ad6..9e4720b171 100644 --- a/src/PCDM/PCDM_ReadWriter.cxx +++ b/src/PCDM/PCDM_ReadWriter.cxx @@ -30,6 +30,8 @@ static TCollection_ExtendedString TryXmlDriverType (const TCollection_AsciiString& theFileName); +static TCollection_ExtendedString TryXmlDriverType (Standard_IStream& theIStream); + //======================================================================= //function : Open //purpose : @@ -141,6 +143,41 @@ TCollection_ExtendedString PCDM_ReadWriter::FileFormat return theFormat; } +//======================================================================= +//function : FileFormat +//purpose : +//======================================================================= + +TCollection_ExtendedString PCDM_ReadWriter::FileFormat (Standard_IStream& theIStream, Handle(Storage_Data)& theData) +{ + TCollection_ExtendedString aFormat; + + Storage_BaseDriver* aFileDriver; + if (PCDM::FileDriverType (theIStream, aFileDriver) == PCDM_TOFD_Unknown) + { + return ::TryXmlDriverType (theIStream); + } + + // the stream starts with a magic number, FileDriverType has read + // them already but returned the stream pos to initial state, + // thus we should read them before reading of info section + aFileDriver->ReadMagicNumber(theIStream); + + aFileDriver->ReadCompleteInfo (theIStream, theData); + + for (Standard_Integer i = 1; i <= theData->HeaderData()->UserInfo().Length(); i++) + { + const TCollection_AsciiString& aLine = theData->HeaderData()->UserInfo().Value(i); + + if(aLine.Search (FILE_FORMAT) != -1) + { + aFormat = TCollection_ExtendedString (aLine.Token(" ",2).ToCString(), Standard_True); + } + } + + return aFormat; +} + //======================================================================= //function : ::TryXmlDriverType //purpose : called from FileFormat() @@ -164,3 +201,39 @@ static TCollection_ExtendedString TryXmlDriverType } return theFormat; } + +//======================================================================= +//function : ::TryXmlDriverType +//purpose : called from FileFormat() +//======================================================================= + +static TCollection_ExtendedString TryXmlDriverType (Standard_IStream& theIStream) +{ + TCollection_ExtendedString theFormat; + PCDM_DOMHeaderParser aParser; + const char * aDocumentElementName = "document"; + aParser.SetStartElementName (Standard_CString(aDocumentElementName)); + + if (theIStream.good()) + { + streampos aDocumentPos = theIStream.tellg(); + + // Parse the file; if there is no error or an error appears before retrieval + // of the DocumentElement, the XML format cannot be defined + if (aParser.parse (theIStream)) + { + LDOM_Element anElement = aParser.GetElement(); + if (anElement.getTagName().equals (LDOMString(aDocumentElementName))) + theFormat = anElement.getAttribute ("format"); + } + + if (!theIStream.good()) + { + theIStream.clear(); + } + + theIStream.seekg(aDocumentPos); + } + + return theFormat; +} diff --git a/src/PCDM/PCDM_RetrievalDriver.cxx b/src/PCDM/PCDM_RetrievalDriver.cxx index c019708001..9cba39443a 100644 --- a/src/PCDM/PCDM_RetrievalDriver.cxx +++ b/src/PCDM/PCDM_RetrievalDriver.cxx @@ -60,6 +60,18 @@ void PCDM_RetrievalDriver::RaiseIfUnknownTypes(const Handle(Storage_Schema)& aSc } } +//======================================================================= +//function : Read +//purpose : +//======================================================================= +void PCDM_RetrievalDriver::Read(Standard_IStream& /*theIStream*/, + const Handle(Storage_Data)& /*theStorageData*/, + const Handle(CDM_Document)& /*theDoc*/, + const Handle(CDM_Application)& /*theApplication*/) +{ + +} + //======================================================================= //function : Read //purpose : diff --git a/src/PCDM/PCDM_StorageDriver.cxx b/src/PCDM/PCDM_StorageDriver.cxx index a72560df36..fb3ff9b475 100644 --- a/src/PCDM/PCDM_StorageDriver.cxx +++ b/src/PCDM/PCDM_StorageDriver.cxx @@ -96,6 +96,15 @@ void PCDM_StorageDriver::Write(const Handle(CDM_Document)& aDocument, const TCol PCDM_DriverError::Raise(theData->ErrorStatusExtension().ToCString()); } + +//======================================================================= +//function : Write +//purpose : +//======================================================================= +void PCDM_StorageDriver::Write (const Handle(CDM_Document)& /*aDocument*/, Standard_OStream& /*theOStream*/) +{ + +} //void PCDM_StorageDriver::LoadExtensions(const Handle(Storage_Schema)& aSchema, const TColStd_SequenceOfExtendedString& Extensions) {} void PCDM_StorageDriver::LoadExtensions(const Handle(Storage_Schema)& , const TColStd_SequenceOfExtendedString& ) {} diff --git a/src/StdResource/XCAF b/src/StdResource/XCAF index 0d3c979e2c..4a67f6ec4d 100755 --- a/src/StdResource/XCAF +++ b/src/StdResource/XCAF @@ -1,30 +1,29 @@ -formatlist: MDTV-XCAF XmlXCAF MDTV-Standard +formatlist: MDTV-XCAF XmlXCAF BinXCAF MDTV-Standard XmlOcaf BinOcaf ! ! Default format xml.FileFormat: XmlXCAF ! +! XCAF attributes +! MDTV-XCAF.Description: XCAF Document Version 1.0 MDTV-XCAF.FileExtension: dxc MDTV-XCAF.StoragePlugin: ed8793f8-3142-11d4-b9b5-0060b0ee281b MDTV-XCAF.RetrievalPlugin: ed8793f9-3142-11d4-b9b5-0060b0ee281b MDTV-XCAFSchema: ed8793fa-3142-11d4-b9b5-0060b0ee281b ! +! XmlXCAF format +! XmlXCAF.Description: XmlXCAF Document Version 1.0 XmlXCAF.FileExtension: xml XmlXCAF.StoragePlugin: f78ff496-a779-11d5-aab4-0050044b1af1 XmlXCAF.RetrievalPlugin: f78ff497-a779-11d5-aab4-0050044b1af1 ! +! BinXCAF format +! BinXCAF.Description: BinXCAF Document Version 1.0 BinXCAF.FileExtension: xbf BinXCAF.StoragePlugin: a78ff496-a779-11d5-aab4-0050044b1af1 BinXCAF.RetrievalPlugin: a78ff497-a779-11d5-aab4-0050044b1af1 -! -! XmlOcaf format -! -XmlOcaf.Description: Xml Document Version 1.0 -XmlOcaf.FileExtension: xml -XmlOcaf.StoragePlugin: 03a56820-8269-11d5-aab2-0050044b1af1 -XmlOcaf.RetrievalPlugin: 03a56822-8269-11d5-aab2-0050044b1af1 ! ! standard attributes ! @@ -36,10 +35,16 @@ MDTV-StandardSchema: ad696002-5b34-11d1-b5ba-00a0c9064368 MDTV-Standard.AttributeStoragePlugin: 47b0b826-d931-11d1-b5da-00a0c9064368 MDTV-Standard.AttributeRetrievalPlugin: 47b0b827-d931-11d1-b5da-00a0c9064368 ! +! XmlOcaf format +! +XmlOcaf.Description: Xml Document Version 1.0 +XmlOcaf.FileExtension: xml +XmlOcaf.StoragePlugin: 03a56820-8269-11d5-aab2-0050044b1af1 +XmlOcaf.RetrievalPlugin: 03a56822-8269-11d5-aab2-0050044b1af1 +! ! BinOcaf format ! BinOcaf.Description: Bin Ocaf Document Version 1.0 BinOcaf.FileExtension: cbf BinOcaf.StoragePlugin: 03a56835-8269-11d5-aab2-0050044b1af1 BinOcaf.RetrievalPlugin: 03a56836-8269-11d5-aab2-0050044b1af1 - diff --git a/src/Storage/Storage_BaseDriver.cxx b/src/Storage/Storage_BaseDriver.cxx index cab37b035c..9decce7c52 100644 --- a/src/Storage/Storage_BaseDriver.cxx +++ b/src/Storage/Storage_BaseDriver.cxx @@ -20,3 +20,22 @@ Storage_BaseDriver::Storage_BaseDriver() : myOpenMode(Storage_VSNone) void Storage_BaseDriver::Delete() {} +TCollection_AsciiString Storage_BaseDriver::ReadMagicNumber (Standard_IStream& theIStream) +{ + // magic number has the same length which is 7: BINFILE, CMPFILE and FSDFILE + Standard_Size aMagicNumberLen = 7; + + TCollection_AsciiString aReadMagicNumber; + + char aChar; + Standard_Size aReadCharNb = 0; + + while (theIStream.good() && (aReadCharNb < aMagicNumberLen)) + { + theIStream.get(aChar); + aReadCharNb += (Standard_Size)theIStream.gcount(); + aReadMagicNumber += aChar; + } + + return aReadMagicNumber; +} diff --git a/src/TDocStd/TDocStd_Application.cxx b/src/TDocStd/TDocStd_Application.cxx index 689961b0a9..4005d3e5c1 100644 --- a/src/TDocStd/TDocStd_Application.cxx +++ b/src/TDocStd/TDocStd_Application.cxx @@ -227,6 +227,36 @@ PCDM_ReaderStatus TDocStd_Application::Open(const TCollection_ExtendedString& pa return status; } +//======================================================================= +//function : Open +//purpose : +//======================================================================= +PCDM_ReaderStatus TDocStd_Application::Open (Standard_IStream& theIStream, Handle(TDocStd_Document)& theDoc) +{ + try + { + OCC_CATCH_SIGNALS + + Handle(TDocStd_Document) D = Handle(TDocStd_Document)::DownCast (Read (theIStream)); + if (!D.IsNull()) + { + CDF_Application::Open(D); + theDoc = D; + } + } + catch (Standard_Failure) + { + Handle(Standard_Failure) aFailure = Standard_Failure::Caught(); + if (!aFailure.IsNull() && !MessageDriver().IsNull()) + { + TCollection_ExtendedString aFailureMessage (aFailure->GetMessageString()); + MessageDriver()->Write (aFailureMessage.ToExtString()); + } + } + + return GetRetrieveStatus(); +} + //======================================================================= //function : SaveAs //purpose : @@ -269,6 +299,52 @@ PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& D,c return storer.StoreStatus(); } +//======================================================================= +//function : SaveAs +//purpose : +//======================================================================= +PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc, Standard_OStream& theOStream) +{ + PCDM_StoreStatus aStatus = PCDM_SS_Failure; + + if (theDoc->FindStoragePlugin()) + { + try + { + Handle(PCDM_StorageDriver) aDocStorageDriver = + Handle(PCDM_StorageDriver)::DownCast (Plugin::Load(theDoc->StoragePlugin())); + + if (!aDocStorageDriver.IsNull()) + { + aDocStorageDriver->SetFormat (theDoc->StorageFormat()); + aDocStorageDriver->Write (theDoc,theOStream); + + if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK) + { + theDoc->SetSaved(); + } + + aStatus = aDocStorageDriver->GetStoreStatus(); + } + } + catch (Standard_Failure) + { + Handle(Standard_Failure) aFailure = Standard_Failure::Caught(); + if (!aFailure.IsNull() && !MessageDriver().IsNull()) + { + TCollection_ExtendedString aString (aFailure->GetMessageString()); + MessageDriver()->Write(aString.ToExtString()); + } + } + } + else + { + aStatus = PCDM_SS_DriverFailure; + } + + return aStatus; +} + //======================================================================= //function : Save //purpose : @@ -374,6 +450,56 @@ PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& D, return aStatus; } +//======================================================================= +//function : SaveAs +//purpose : +//======================================================================= + +PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc, + Standard_OStream& theOStream, + TCollection_ExtendedString& theStatusMessage) +{ + PCDM_StoreStatus aStatus = PCDM_SS_Failure; + + if (theDoc->FindStoragePlugin()) + { + try + { + Handle(PCDM_StorageDriver) aDocStorageDriver = + Handle(PCDM_StorageDriver)::DownCast (Plugin::Load(theDoc->StoragePlugin())); + + if (!aDocStorageDriver.IsNull()) + { + aDocStorageDriver->SetFormat (theDoc->StorageFormat()); + aDocStorageDriver->Write (theDoc,theOStream); + + if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK) + { + theDoc->SetSaved(); + } + + aStatus = aDocStorageDriver->GetStoreStatus(); + } + } + catch (Standard_Failure) + { + Handle(Standard_Failure) aFailure = Standard_Failure::Caught(); + if (!aFailure.IsNull() && !MessageDriver().IsNull()) + { + TCollection_ExtendedString aString (aFailure->GetMessageString()); + MessageDriver()->Write(aString.ToExtString()); + } + } + } + else + { + theStatusMessage = TCollection_ExtendedString("TDocStd_Application::sSaveAs: a storage plugin has not been found"); + aStatus = PCDM_SS_DriverFailure; + } + + return aStatus; +} + //======================================================================= //function : Save //purpose : diff --git a/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx b/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx index 084d4c5dcb..3842cea943 100644 --- a/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx +++ b/src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx @@ -44,7 +44,9 @@ #define START_REF "START_REF" #define END_REF "END_REF" -#define REFERENCE_COUNTER "REFERENCE_COUNTER" + +#define MODIFICATION_COUNTER "MODIFICATION_COUNTER: " +#define REFERENCE_COUNTER "REFERENCE_COUNTER: " //#define TAKE_TIMES static void take_time (const Standard_Integer, const char *, @@ -188,13 +190,42 @@ void XmlLDrivers_DocumentRetrievalDriver::Read { myReaderStatus = PCDM_RS_DriverFailure; myFileName = theFileName; + + std::ifstream aFileStream; + OSD_OpenStream (aFileStream, myFileName, std::ios::in); + + if (aFileStream.is_open() && aFileStream.good()) + { + Read (aFileStream, NULL, theNewDocument, theApplication); + } + else + { + myReaderStatus = PCDM_RS_OpenError; + + TCollection_ExtendedString aMsg = TCollection_ExtendedString("Error: the file ") + + theFileName + " cannot be opened for reading"; + + theApplication->MessageDriver()->Write (aMsg.ToExtString()); + Standard_Failure::Raise("File cannot be opened for reading"); + } +} + +//======================================================================= +//function : Read +//purpose : +//======================================================================= +void XmlLDrivers_DocumentRetrievalDriver::Read (Standard_IStream& theIStream, + const Handle(Storage_Data)& /*theStorageData*/, + const Handle(CDM_Document)& theNewDocument, + const Handle(CDM_Application)& theApplication) +{ Handle(CDM_MessageDriver) aMessageDriver = theApplication -> MessageDriver(); ::take_time (~0, " +++++ Start RETRIEVE procedures ++++++", aMessageDriver); // 1. Read DOM_Document from file LDOMParser aParser; - TCollection_AsciiString aName (theFileName,'?'); - if (aParser.parse(aName.ToCString())) + + if (aParser.parse(theIStream)) { TCollection_AsciiString aData; cout << aParser.GetError(aData) << ": " << aData << endl; @@ -268,8 +299,8 @@ void XmlLDrivers_DocumentRetrievalDriver::ReadFromDomDocument try { OCC_CATCH_SIGNALS TCollection_AsciiString anInf(anInfo,'?'); - //Standard_Integer aRefCounter = anInf.Token(" ",2).IntegerValue(); - //theNewDocument->SetReferenceCounter(aRefCounter); + Standard_Integer aRefCounter = anInf.Token(" ",2).IntegerValue(); + theNewDocument->SetReferenceCounter(aRefCounter); } catch (Standard_Failure) { // cout << "warning: could not read the reference counter in " << aFileName << endl; @@ -279,6 +310,20 @@ void XmlLDrivers_DocumentRetrievalDriver::ReadFromDomDocument aMsgDriver->Write(aMsg.ToExtString()); } } + else if (anInfo.Search(MODIFICATION_COUNTER) != -1) { + try { + OCC_CATCH_SIGNALS + + TCollection_AsciiString anInf(anInfo,'?'); + Standard_Integer aModCounter = anInf.Token(" ",2).IntegerValue(); + theNewDocument->SetModifications (aModCounter); + } + catch (Standard_Failure) { + TCollection_ExtendedString aMsg("Warning: could not read the modification counter\0"); + if(!aMsgDriver.IsNull()) + aMsgDriver->Write(aMsg.ToExtString()); + } + } if(anInfo == END_REF) isRef = Standard_False; diff --git a/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx b/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx index 1aa875ef10..7fba581baf 100644 --- a/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx +++ b/src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx @@ -100,12 +100,39 @@ void XmlLDrivers_DocumentStorageDriver::AddNamespace //function : Write //purpose : //======================================================================= -void XmlLDrivers_DocumentStorageDriver::Write - (const Handle(CDM_Document)& theDocument, - const TCollection_ExtendedString& theFileName) +void XmlLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)& theDocument, + const TCollection_ExtendedString& theFileName) { - Handle(CDM_MessageDriver) aMessageDriver = - theDocument -> Application() -> MessageDriver(); + myFileName = theFileName; + + std::ofstream aFileStream; + OSD_OpenStream (aFileStream, theFileName, std::ios::out); + + if (aFileStream.is_open() && aFileStream.good()) + { + Write (theDocument, aFileStream); + } + else + { + SetIsError (Standard_True); + SetStoreStatus(PCDM_SS_WriteFailure); + + TCollection_ExtendedString aMsg = TCollection_ExtendedString("Error: the file ") + + theFileName + " cannot be opened for writing"; + + theDocument->Application()->MessageDriver()->Write (aMsg.ToExtString()); + Standard_Failure::Raise("File cannot be opened for writing"); + } +} + +//======================================================================= +//function : Write +//purpose : +//======================================================================= +Standard_EXPORT void XmlLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)& theDocument, + Standard_OStream& theOStream) +{ + Handle(CDM_MessageDriver) aMessageDriver = theDocument->Application()->MessageDriver(); ::take_time (~0, " +++++ Start STORAGE procedures ++++++", aMessageDriver); // Create new DOM_Document @@ -114,26 +141,28 @@ void XmlLDrivers_DocumentStorageDriver::Write // Fill the document with data XmlObjMgt_Element anElement = aDOMDoc.getDocumentElement(); - if (WriteToDomDocument (theDocument, anElement, theFileName) == Standard_False) { - // Write DOM_Document into XML file, - FILE * aFile = OSD_OpenFile(theFileName, "wt"); - - if (aFile) { - LDOM_XmlWriter aWriter (aFile); - aWriter.SetIndentation(1); - aWriter << aDOMDoc; - fclose(aFile); - ::take_time (0, " +++++ Fin formatting to XML : ", aMessageDriver); + if (WriteToDomDocument (theDocument, anElement) == Standard_False) { - }else{ + LDOM_XmlWriter aWriter; + aWriter.SetIndentation(1); + + if (theOStream.good()) + { + aWriter.Write (theOStream, aDOMDoc); + } + else + { SetIsError (Standard_True); SetStoreStatus(PCDM_SS_WriteFailure); - TCollection_ExtendedString aMsg = - TCollection_ExtendedString("Error: the file ") + theFileName + - " cannot be opened for writing"; - aMessageDriver -> Write (aMsg.ToExtString()); - Standard_Failure::Raise("File cannot be opened for writing"); + + TCollection_ExtendedString aMsg = TCollection_ExtendedString("Error: the stream is bad and") + + " cannot be used for writing"; + theDocument->Application()->MessageDriver()->Write (aMsg.ToExtString()); + + Standard_Failure::Raise("File cannot be opened for writing"); } + + ::take_time (0, " +++++ Fin formatting to XML : ", aMessageDriver); } } @@ -144,10 +173,8 @@ void XmlLDrivers_DocumentStorageDriver::Write // data to XML, this method should be reimplemented avoiding step 3 //======================================================================= -Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument - (const Handle(CDM_Document)& theDocument, - XmlObjMgt_Element& theElement, - const TCollection_ExtendedString& theFileName) +Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument (const Handle(CDM_Document)& theDocument, + XmlObjMgt_Element& theElement) { SetIsError(Standard_False); Handle(CDM_MessageDriver) aMessageDriver = @@ -255,7 +282,7 @@ Standard_Boolean XmlLDrivers_DocumentStorageDriver::WriteToDomDocument 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()->WriteReferences(theData,theDocument, myFileName); PCDM_ReadWriter::Writer()->WriteExtensions(theData,theDocument); PCDM_ReadWriter::Writer()->WriteVersion(theData,theDocument); diff --git a/tests/bugs/caf/bug26229_1 b/tests/bugs/caf/bug26229_1 new file mode 100644 index 0000000000..18a99a5ae4 --- /dev/null +++ b/tests/bugs/caf/bug26229_1 @@ -0,0 +1,44 @@ +puts "================" +puts "OCC26229" +puts "================" +puts "" +################################################################################################### +# Add the possibility in OCAF to open/save a document from/to a stream object (BinOcaf format) +################################################################################################### + +pload DCAF + +NewDocument D BinOcaf + +# Add an attribute to a data framework +set aSetAttr1 100 +set aLabel 0:2 +SetInteger D ${aLabel} ${aSetAttr1} + +# Close/Open the transaction +NewCommand D + +# Save the document +set aFile ${imagedir}/${casename}.cbf +file delete ${aFile} +SaveAs D ${aFile} -stream +if { ![file exists ${aFile}] } { + puts "Error: there is not ${aFile} file; SaveAs command" + return +} + + +# Restore the document +Close D +Open ${aFile} DD -stream + +# Get a value of the attribute +set IsDone [catch {set aGetAttr3 [GetInteger DD ${aLabel}]} aResult] +if { ${IsDone} != 0 || + ${aSetAttr1}!=${aGetAttr3} } { + puts ${aResult} + puts "aSetAttr1=${aSetAttr1} aGetAttr3=${aGetAttr3}" + puts "Error: get a value of TDataStd_Integer attribute from Streamed restoring document" +} else { + puts "Get a value of TDataStd_Integer attribute from Streamed restoring document: OK" +} \ No newline at end of file diff --git a/tests/bugs/caf/bug26229_2 b/tests/bugs/caf/bug26229_2 new file mode 100644 index 0000000000..c206695e9c --- /dev/null +++ b/tests/bugs/caf/bug26229_2 @@ -0,0 +1,44 @@ +puts "================" +puts "OCC26229" +puts "================" +puts "" +################################################################################################### +# Add the possibility in OCAF to open/save a document from/to a stream object (XmlOcaf format) +################################################################################################### + +pload DCAF + +NewDocument D XmlOcaf + +# Add an attribute to a data framework +set aSetAttr1 100 +set aLabel 0:2 +SetInteger D ${aLabel} ${aSetAttr1} + +# Close/Open the transaction +NewCommand D + +# Save the document +set aFile ${imagedir}/${casename}.xml +file delete ${aFile} +SaveAs D ${aFile} -stream +if { ![file exists ${aFile}] } { + puts "Error: there is not ${aFile} file; SaveAs command" + return +} + + +# Restore the document +Close D +Open ${aFile} DD -stream + +# Get a value of the attribute +set IsDone [catch {set aGetAttr3 [GetInteger DD ${aLabel}]} aResult] +if { ${IsDone} != 0 || + ${aSetAttr1}!=${aGetAttr3} } { + puts ${aResult} + puts "aSetAttr1=${aSetAttr1} aGetAttr3=${aGetAttr3}" + puts "Error: get a value of TDataStd_Integer attribute from Streamed restoring document" +} else { + puts "Get a value of TDataStd_Integer attribute from Streamed restoring document: OK" +} \ No newline at end of file -- 2.39.5