]> OCCT Git - occt-copy.git/commitdiff
0026229: Add the possibility in OCAF to open/save a document from/to a stream object
authoribs <ibs@opencascade.com>
Fri, 27 Nov 2015 10:03:25 +0000 (13:03 +0300)
committermsv <msv@opencascade.com>
Fri, 22 Apr 2016 14:35:31 +0000 (17:35 +0300)
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

27 files changed:
dox/user_guides/draw_test_harness/draw_test_harness.md
src/BinLDrivers/BinLDrivers_DocumentRetrievalDriver.cxx
src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx
src/CDF/CDF_Application.cxx
src/DDF/DDF_IOStream.cxx
src/DDF/DDF_IOStream.hxx
src/DDocStd/DDocStd_ApplicationCommands.cxx
src/FSD/FSD_BinaryFile.cxx
src/FSD/FSD_CmpFile.cxx
src/FSD/FSD_File.cxx
src/LDOM/LDOMParser.cxx
src/LDOM/LDOMParser.hxx
src/LDOM/LDOM_XmlReader.cxx
src/LDOM/LDOM_XmlReader.hxx
src/LDOM/LDOM_XmlWriter.cxx
src/LDOM/LDOM_XmlWriter.hxx
src/PCDM/PCDM.cxx
src/PCDM/PCDM_ReadWriter.cxx
src/PCDM/PCDM_RetrievalDriver.cxx
src/PCDM/PCDM_StorageDriver.cxx
src/StdResource/XCAF
src/Storage/Storage_BaseDriver.cxx
src/TDocStd/TDocStd_Application.cxx
src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx
src/XmlLDrivers/XmlLDrivers_DocumentStorageDriver.cxx
tests/bugs/caf/bug26229_1 [new file with mode: 0644]
tests/bugs/caf/bug26229_2 [new file with mode: 0644]

index 98afd46f3387bb45bb093c2aa44b59f6dae5714f..e8f925d37e214479ed563f3921cb72dd65e5df62 100644 (file)
@@ -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 <i>-stream</i> 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 <i>-stream</i> activates usage of alternative interface of OCAF persistence working with C++ streams instead of file names.
 
 **Example:** 
 ~~~~~
index 9c3781c785b3c12c47a29dfbf3ef67c2a235aac9..f0bc9df6153200d7f56c69f4bee88a5746540ce3 100644 (file)
@@ -21,6 +21,7 @@
 #include <BinObjMgt_Persistent.hxx>
 #include <FSD_BinaryFile.hxx>
 #include <FSD_FileHeader.hxx>
+#include <PCDM_ReadWriter.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_Stream.hxx>
 #include <Storage_Schema.hxx>
@@ -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 = " <<aShapeSectionPos <<endl;
 #endif
       if(aShapeSectionPos) { 
-       aDocumentPos = anIS.tellg();
-       anIS.seekg((streampos) aShapeSectionPos);
+       aDocumentPos = theIStream.tellg();
+       theIStream.seekg((streampos) aShapeSectionPos);
 
-       CheckShapeSection(aShapeSectionPos, anIS);
+       CheckShapeSection(aShapeSectionPos, theIStream);
        // Read Shapes
        BinLDrivers_DocumentSection aCurSection;
-       ReadShapeSection (aCurSection, anIS, Standard_False);
+       ReadShapeSection (aCurSection, theIStream, Standard_False);
       }
     }
   } // end of reading Sections or shape section
 
   // Return to read of the Document structure
-  anIS.seekg(aDocumentPos);
+  theIStream.seekg(aDocumentPos);
 
   // read the header (tag) of the root label
   Standard_Integer aTag;
-  anIS.read ((char*)&aTag, sizeof(Standard_Integer));
+  theIStream.read ((char*)&aTag, sizeof(Standard_Integer));
 
   // read sub-tree of the root label
-  Standard_Integer nbRead = ReadSubTree (anIS, aData->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
index 1599144851ad4ca2060aed4ba00d3d23bd2ea574..872fe023dc3f4c17ee41ce5dcbfd00bb46b10725 100644 (file)
@@ -21,6 +21,7 @@
 #include <CDM_Application.hxx>
 #include <FSD_BinaryFile.hxx>
 #include <FSD_FileHeader.hxx>
+#include <OSD_OpenFile.hxx>
 #include <PCDM_ReadWriter.hxx>
 #include <Standard_ErrorHandler.hxx>
 #include <Storage_Schema.hxx>
@@ -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 <<endl;
-#endif
-//#endif
 
-    if (anOS) {
 
 //  2. Write the Table of Contents of Sections
-      BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
-      for (; anIterS.More(); anIterS.Next())
-        anIterS.ChangeValue().WriteTOC (anOS);
+    BinLDrivers_VectorOfDocumentSection::Iterator anIterS (mySections);
+    for (; anIterS.More(); anIterS.Next())
+      anIterS.ChangeValue().WriteTOC (theOStream);
 
-      // Shapes Section is the last one, it indicates the end of the table.
-      BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
-                                                  Standard_False);
-      aShapesSection.WriteTOC (anOS);
+    // Shapes Section is the last one, it indicates the end of the table.
+    BinLDrivers_DocumentSection aShapesSection (SHAPESECTION_POS,
+                                                Standard_False);
+    aShapesSection.WriteTOC (theOStream);
 
 //  3. Write document contents
-      // (Storage data to the stream)
-      myRelocTable.Clear();
-      myPAtt.Init();
+    // (Storage data to the stream)
+    myRelocTable.Clear();
+    myPAtt.Init();
 
-//    Write Doc structure
-      WriteSubTree (aData->Root(), anOS); // Doc is written
+//  Write Doc structure
+    WriteSubTree (aData->Root(), theOStream); // Doc is written
 
 //  4. Write Shapes section
-      WriteShapeSection(aShapesSection, anOS);
-
-// 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 <<endl;
-#endif
-  aFileDriver.Close();
+
+  aHeader.bcomment = aHeader.einfo;
+  aHeader.ecomment = aHeader.bcomment + FSD_BinaryFile::WriteComment(theOStream, theData->Comments(), Standard_True);
+
+  aHeader.edata = aHeader.ecomment;
+
+  // write header information
+  FSD_BinaryFile::WriteHeader (theOStream, aHeader);
+
+  // write info section
+  FSD_BinaryFile::WriteInfo (theOStream,
+                             aObjNb,
+                             BinLDrivers::StorageVersion(),
+                             Storage_Schema::ICreationDate(),
+                             TCollection_AsciiString(SchemaName(),'?'),
+                             aShemaVer,
+                             theData->ApplicationName(),
+                             theData->ApplicationVersion(),
+                             theData->DataType(),
+                             theData->UserInfo());
+
+  // write the comments
+  FSD_BinaryFile::WriteComment(theOStream, theData->Comments());
+  
 }
 
 //=======================================================================
index bbabfd17f84d87eaf93467d40db2ab03c330e5a1..e025af9cda6c36a61a65bd87c0058029858e97d1 100644 (file)
@@ -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  : 
index 46cd875399216edf0b5c8d6c8fb9540e0b995511..00e40935c966a413f3270df57568abfe11c7b40e 100644 (file)
@@ -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  : 
index 38fc0a1b9d42bbe1750f75deff14e20b3c4fe05b..979752d22ae7ea5432a12557a0ba3809341fa98b 100644 (file)
@@ -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) ;
index c0a9f068a973206fe5b8c7772f2c82485c108f8b..b6c70dc90b1390e4231bbcffe2474a64a6860945 100644 (file)
@@ -32,6 +32,7 @@
 #include <TDF_Tool.hxx> 
 
 #include <OSD_Path.hxx>
+#include <OSD_OpenFile.hxx>
 #include <TDocStd_PathParser.hxx>
 
 #include <AIS_InteractiveContext.hxx>
@@ -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",
index bb90cd171f37139d762314a58f8f95f6a288c588..6bf7e61a055cc5f4cf9fdeabf0fefc7e84da929d 100644 (file)
@@ -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
index f30fa25afd872848bcaa1503618207b39b0f0f66..a3f8c2791d863333e6e68932e60909cc1d21dcc3 100644 (file)
@@ -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
index bf62a62c458cc7c6ab3b3299806b1b5fee6c0748..5b6461ea652f81bd9248839f183f635885e23920 100644 (file)
@@ -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
index 0d28c7bd51608605254127682b0df96819326eba..02e9f889924a84dde7e78e2535d7d2e193162b75 100644 (file)
@@ -24,6 +24,7 @@
 #include <LDOM_BasicText.hxx>
 #include <LDOM_CharReference.hxx>
 #include <TCollection_ExtendedString.hxx>
+#include <OSD_OpenFile.hxx>
 
 #include <fcntl.h>
 #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:
       {
index d350e8fa1b414c5c3feb48289f60f440ba0cba96..bf99d1c6c9f5607615431e1e283a5e74eb092787 100644 (file)
@@ -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 ----------
 
index a4a5f11bb0d06778da2b5d907e16a4da5371f105..e240602d6ce4261187bc2517ed4620063f7948c1 100644 (file)
@@ -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];
index 90550a666482ddf07d5d055e0feb07922b6f24d6..f40de607400c89e3981240ee071090c4e3eb7d59 100644 (file)
@@ -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;
index bf0968555cc0575ef84e197803085e0c62dac780..342bd24d429f6baf016e839a82ebe4a85a8cecc9 100644 (file)
 #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);
 }
index 9965e5c3632bcfde9241805f964ba9991c35f71b..4ef47d4ae8f0e4c33fca8b60edc39ed628c08847 100644 (file)
 #ifndef LDOM_XmlWriter_HeaderFile
 #define LDOM_XmlWriter_HeaderFile
 
+#include <Standard_OStream.hxx>
 #include <Standard_TypeDef.hxx>
 #include <stdio.h>
 
-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
index 876775d0544ef1ba6b4b1ea595e494bdb4653c1d..448d65d6083ab2f7f123279dddc303f1bb4fee79 100644 (file)
@@ -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;
+}
+
index 92df812ad6ca77a9dd9f0bf32b09d9b5e142397f..9e4720b17193857f0c0867c5c50b0c081e8055b9 100644 (file)
@@ -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;
+}
index c01970800175b3c439a7a85280da778e12ee63e2..9cba39443a03d994e3e7312dc2e7c64f9305452f 100644 (file)
@@ -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  : 
index a72560df36533a5ebfb69be127ae7d3a1322e310..fb3ff9b475e3389afacdc5c1449439f4078d1956 100644 (file)
@@ -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& ) {}
 
index 0d3c979e2c464ff96e6f2eb3038a862785e2594a..4a67f6ec4db177b0c1e26c7b8c623e2213d3331d 100755 (executable)
@@ -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
-
index cab37b035cb3cb4c6dc85fad1a81145b8c8797f5..9decce7c520779003d4932ee2755e61452c9f968 100644 (file)
@@ -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;
+}
index 689961b0a92ebcbfe0f90b80b9e2ed66c0b7ba48..4005d3e5c1a224cb4a9ed7a08efc497b6bcef202 100644 (file)
@@ -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  : 
index 084d4c5dcb4e6646e6123b92d51cd89a90f69c77..3842cea943b49569c0108905044dbadba0dac249 100644 (file)
@@ -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;
index 1aa875ef100a6ca7a1bf520bdf36329b8bbb6e12..7fba581baff9f9f5ba6c0006ff5f419302018d47 100644 (file)
@@ -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 (file)
index 0000000..18a99a5
--- /dev/null
@@ -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 (file)
index 0000000..c206695
--- /dev/null
@@ -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