]> OCCT Git - occt-copy.git/commitdiff
Fix for problem with using nonseekable streams (ex boost filtering_streams with zip...
authorstv <stv@opencascade.com>
Thu, 2 Jul 2015 07:29:44 +0000 (10:29 +0300)
committerstv <stv@opencascade.com>
Thu, 2 Jul 2015 07:29:44 +0000 (10:29 +0300)
src/CDF/CDF_Application.cxx
src/PCDM/PCDM_DOMHeaderParser.cxx
src/Storage/Storage_IStream.cdl
src/Storage/Storage_IStream.cxx
src/Storage/Storage_OStream.cdl
src/Storage/Storage_OStream.cxx
src/XmlLDrivers/XmlLDrivers_DocumentRetrievalDriver.cxx

index c700e84fce782ea56519fb127d249c1763f829a1..b7ddf1620fdb80f7b7d5cbba5208ac5a8e8c9172 100644 (file)
@@ -200,8 +200,6 @@ PCDM_ReaderStatus CDF_Application::CanRetrieve(Handle(Storage_IODevice)& aDevice
     }
   }
 
-  aDevice->Close();
-
   return PCDM_RS_OK;
 }
 
index 9bcbcc9f233325286f929f94976c02f6883da462..7cabf17605c1c5a141b1c2d3af3ca67778f5d69e 100644 (file)
@@ -22,17 +22,29 @@ Standard_Boolean PCDM_DOMHeaderParser::parse( const Handle(Storage_IODevice)& an
 {
   Standard_Boolean aRes = Standard_True;
   Handle(Storage_File) aFile = Handle(Storage_File)::DownCast(anInput);
-  Handle(Storage_IStream) aStream = Handle(Storage_IStream)::DownCast(anInput);
   if ( !aFile.IsNull() )
   {
     TCollection_AsciiString aPath( aFile->Path() );
     aRes = LDOMParser::parse( aPath.ToCString() );
   }
-  else if ( !aStream.IsNull() && aStream->Stream() )
+  else if ( !anInput.IsNull() && anInput->CanRead() )
   {
-    aStream->Open(Storage_VSRead);
-    aRes = LDOMParser::parse( *aStream->Stream() );
-    aStream->Close();
+    Standard_Size aSize = 8000;
+    char* aBuf = (char*)malloc( aSize );
+    anInput->Open(Storage_VSRead);
+    std::string aStr;
+    while ( !anInput->IsEnd() )
+    {
+        Standard_Size aNum = anInput->Read( aBuf, aSize );
+        aStr.append( aBuf, aNum );
+    }
+    anInput->Close();
+    free( aBuf );
+
+    Standard_SStream aStream( std::ios::in );
+    aStream.str( aStr );
+
+    aRes = LDOMParser::parse( aStream );
   }
   return aRes;
 }
index 8f1419a1cf5e17da685b91e53fbe7230d695578c..a35c4a81df6dc7aca563e1c6845504c40bd61f54 100644 (file)
@@ -21,6 +21,7 @@ uses Position       from Storage,
      OpenMode       from Storage,
      SeekMode       from Storage,
      Error          from Storage,
+     SStream        from Standard,
      IStream        from Standard,
      IStreamPtr     from Standard,
      ExtendedString from TCollection
@@ -35,8 +36,6 @@ is
 
     Delete (me: mutable) is redefined;
 
-    Stream(me) returns IStreamPtr from Standard;
-
     Name (me) returns ExtendedString from TCollection is redefined;
 
     Open (me: mutable; theMode: OpenMode from Storage = Storage_VSWrite) returns Error from Storage;
@@ -68,6 +67,10 @@ is
     returns OStream from Standard is redefined;
     ---C++: return &
 
+    fillBuffer(me: mutable)
+    is private;
+
 fields
+    myBuffer: SStream from Standard;
     myStream: IStreamPtr from Standard;
 end;
index 62b4594969395134cd962c4e1ca44c8935b8ad72..980b5d42c710bfd3145cf422db0efd076cfa0a1b 100644 (file)
@@ -5,6 +5,8 @@
 
 #include <Storage_IStream.ixx>
 
+#include <Standard_SStream.hxx>
+
 #include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
 
@@ -14,7 +16,8 @@
 //=======================================================================
 Storage_IStream::Storage_IStream (Standard_IStream& theStream)
   : Storage_IODevice(),
-    myStream (&theStream)
+    myStream( &theStream ),
+    myBuffer( std::ios::in | std::ios::binary )
 {
 }
 
@@ -26,15 +29,6 @@ void Storage_IStream::Delete()
 {
 }
 
-//=======================================================================
-//function : Path
-//purpose  : 
-//=======================================================================
-Standard_IStreamPtr Storage_IStream::Stream() const
-{
-  return myStream;
-}
-
 //=======================================================================
 //function : Name
 //purpose  : 
@@ -59,17 +53,15 @@ Storage_Error Storage_IStream::Open (const Storage_OpenMode theMode)
   
   if (OpenMode() == Storage_VSNone)
   {
-    if (!myStream->good()) // not good for eof
-    {
+    if ( !myBuffer.good() ) // not good for eof
       anOpenResult = Storage_VSOpenError;
-    }
     else
     {
       SetOpenMode (theMode);
-      
+
       // clear flags and set the position where the next character is to be inserted 
-      myStream->clear();
-      Seek(0);
+      myBuffer.clear();
+      Seek( 0 );
     }
   }
   else
@@ -86,7 +78,7 @@ Storage_Error Storage_IStream::Open (const Storage_OpenMode theMode)
 //=======================================================================
 Standard_Boolean Storage_IStream::IsEnd() const
 {
-  return myStream->eof();
+  return myBuffer.eof() && myStream->eof();
 }
 
 //=======================================================================
@@ -95,7 +87,7 @@ Standard_Boolean Storage_IStream::IsEnd() const
 //=======================================================================
 Storage_Position Storage_IStream::Tell()
 {
-  return Storage_Position (myStream->tellg());
+  return Storage_Position( myBuffer.tellg() );
 }
 
 //=======================================================================
@@ -104,21 +96,37 @@ Storage_Position Storage_IStream::Tell()
 //=======================================================================
 Standard_Boolean Storage_IStream::Seek (const Storage_Position& thePos, const Storage_SeekMode aMode )
 {
-  switch ( aMode )
+  if ( aMode == Storage_SMEnd )
+  {
+    fillBuffer();
+    myBuffer.seekg( thePos, ios::end );
+  }
+  else
   {
-  case Storage_SMEnd:
-    myStream->seekg(thePos, ios::end);
-    break;
-  case Storage_SMCur:
-    myStream->seekg(thePos, ios::cur);
-    break;
-  case Storage_SMBegin:
-  default:
-    myStream->seekg(thePos, ios::beg);
-    break;
+    Standard_Size aCur = myBuffer.tellg();
+    Standard_Size aPos = aMode == Storage_SMBegin ? thePos : aCur + thePos;
+    if ( aPos > aCur )
+    {
+      myBuffer.seekg( 0, ios::end );
+      Standard_Size aLast = myBuffer.tellg();
+      if ( aLast < aPos )
+      {
+        Standard_Size aCount = aPos - aLast;
+        char* aBuf = (char*)malloc( aCount );
+        myStream->read( aBuf, aCount );
+        Standard_Size aNum = (Standard_Size)myStream->gcount();
+        std::string& aStr = myBuffer.str();
+        aStr.append( (char*)aBuf, aNum );
+        myBuffer.str( aStr );
+        free( aBuf );
+        aPos = aLast + aNum;
+      }
+    }
+    if ( aPos != aCur )
+      myBuffer.seekg( aPos );
   }
 
-  return !myStream->fail();
+  return !myBuffer.fail();
 }
 
 //=======================================================================
@@ -128,8 +136,7 @@ Standard_Boolean Storage_IStream::Seek (const Storage_Position& thePos, const St
 Standard_Boolean Storage_IStream::Close()
 {
   SetOpenMode( Storage_VSNone );
-  myStream->clear();
-  Seek(0);
+  myBuffer.clear();
 
   return Standard_True;
 }
@@ -140,7 +147,7 @@ Standard_Boolean Storage_IStream::Close()
 //=======================================================================
 Standard_Boolean Storage_IStream::CanRead() const
 {
-  return myStream->good();
+    return myBuffer.good() || myStream->good();
 }
 
 //=======================================================================
@@ -156,10 +163,28 @@ Standard_Boolean Storage_IStream::CanWrite() const
 //function : Read
 //purpose  : 
 //=======================================================================
-Standard_Size Storage_IStream::Read (const Standard_Address theBuffer, const Standard_Size theSize)
+Standard_Size Storage_IStream::Read( const Standard_Address theBuffer, const Standard_Size theSize )
 {
-  myStream->read((char*)theBuffer, theSize);
-  return (Standard_Size)myStream->gcount();
+  myBuffer.read((char*)theBuffer, theSize);
+  Standard_Size aCount = (Standard_Size)myBuffer.gcount();
+  if ( aCount < theSize )
+  {
+    myStream->read((char*)theBuffer + aCount, theSize - aCount  );
+    Standard_Size aNum = (Standard_Size)myStream->gcount();
+
+    if ( aNum > 0 )
+    {
+      std::string aStr = myBuffer.str();
+      aStr.append( (char*)theBuffer + aCount, aNum );
+      myBuffer.str( aStr );
+      aCount += aNum;
+
+      myBuffer.clear();
+      myBuffer.seekg( 0, std::ios::end );
+    }
+  }
+
+  return aCount;
 }
 
 //=======================================================================
@@ -188,3 +213,26 @@ Standard_OStream& Storage_IStream::Print (Standard_OStream& theOStream) const
 {
   return theOStream;
 }
+
+//=======================================================================
+//function : fillBuffer
+//purpose  : 
+//=======================================================================
+void Storage_IStream::fillBuffer()
+{
+  Standard_Size aCur = myBuffer.tellg();
+
+  Standard_Size aSize = 8000;
+  char* aBuf = (char*)malloc( aSize );
+  while ( !myStream->eof() )
+  {
+    myStream->read( aBuf, aSize );
+    Standard_Size aNum = (Standard_Size)myStream->gcount();
+    std::string aStr = myBuffer.str();
+    aStr.append( (char*)aBuf, aNum );
+    myBuffer.str( aStr );
+  }
+  free( aBuf );
+
+  myBuffer.seekg( aCur );
+}
index a3a364ea7a14300a1b15c9d83d4e5c00d734e216..a112de096459c299e1f89d4db074b2f7856d8b91 100644 (file)
@@ -23,6 +23,7 @@ uses Position       from Storage,
      Error          from Storage,
      OStream        from Standard,
      OStreamPtr     from Standard,
+     SStream        from Standard,
      ExtendedString from TCollection
 
 raises StreamTypeMismatchError from Storage,
@@ -35,8 +36,6 @@ is
 
     Delete (me: mutable) is redefined;
 
-    Stream (me) returns OStreamPtr from Standard;
-
     Name (me) returns ExtendedString from TCollection is redefined;
 
     Open (me: mutable; theMode: OpenMode from Storage = Storage_VSWrite) returns Error from Storage;
@@ -69,5 +68,6 @@ is
     ---C++: return &
 
 fields
-    myStream: OStreamPtr from Standard;
+    myBuffer : SStream from Standard;
+    myStream : OStreamPtr from Standard;
 end;
index 62236cf47db5a52f72c392b169aa76e8b3231008..9da1bc87e1f0fbbb2f64ad1a0e68f7a27664b7b9 100644 (file)
@@ -5,6 +5,8 @@
 
 #include <Storage_OStream.ixx>
 
+#include <Standard_SStream.hxx>
+
 #include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
 
 //function : Storage_OStream
 //purpose  : Constructor
 //=======================================================================
-Storage_OStream::Storage_OStream (Standard_OStream& theStream)
+Storage_OStream::Storage_OStream( Standard_OStream& theStream )
   : Storage_IODevice(),
-    myStream (&theStream)
+    myStream( &theStream ),
+    myBuffer( std::ios::out | std::ios::binary )
 {
 }
 
@@ -26,15 +29,6 @@ void Storage_OStream::Delete()
 {
 }
 
-//=======================================================================
-//function : Stream
-//purpose  : 
-//=======================================================================
-Standard_OStreamPtr Storage_OStream::Stream() const
-{
-  return myStream;
-}
-
 //=======================================================================
 //function : Name
 //purpose  : 
@@ -50,7 +44,7 @@ TCollection_ExtendedString Storage_OStream::Name() const
 //=======================================================================
 Storage_Error Storage_OStream::Open (const Storage_OpenMode theMode)
 {
-  if (theMode != Storage_VSWrite || theMode != Storage_VSAppend)
+  if (theMode != Storage_VSWrite && theMode != Storage_VSAppend)
   {
     return Storage_VSOpenError;
   }
@@ -68,11 +62,11 @@ Storage_Error Storage_OStream::Open (const Storage_OpenMode theMode)
       SetOpenMode (theMode);
       
       // clear flags and set the position where the next character is to be inserted 
-      myStream->clear();
+      myBuffer.clear();
       if ( theMode == Storage_VSWrite )
-        myStream->seekp(0, ios::beg);
+        myBuffer.seekp(0, ios::beg);
       else
-        myStream->seekp(0, ios::end);
+        myBuffer.seekp(0, ios::end);
     }
   }
   else
@@ -89,7 +83,7 @@ Storage_Error Storage_OStream::Open (const Storage_OpenMode theMode)
 //=======================================================================
 Standard_Boolean Storage_OStream::IsEnd() const
 {
-  return myStream->eof();
+  return myBuffer.eof();
 }
 
 //=======================================================================
@@ -98,7 +92,7 @@ Standard_Boolean Storage_OStream::IsEnd() const
 //=======================================================================
 Storage_Position Storage_OStream::Tell()
 {
-  return Storage_Position (myStream->tellp());
+  return Storage_Position( myBuffer.tellp() );
 }
 
 //=======================================================================
@@ -110,18 +104,18 @@ Standard_Boolean Storage_OStream::Seek (const Storage_Position& thePos, const St
   switch ( aMode )
   {
   case Storage_SMEnd:
-    myStream->seekp(thePos, ios::end);
+    myBuffer.seekp(thePos, ios::end);
     break;
   case Storage_SMCur:
-    myStream->seekp(thePos, ios::cur);
+    myBuffer.seekp(thePos, ios::cur);
     break;
   case Storage_SMBegin:
   default:
-    myStream->seekp(thePos, ios::beg);
+    myBuffer.seekp(thePos, ios::beg);
     break;
   }
 
-  return !myStream->fail();
+  return !myBuffer.fail();
 }
 
 //=======================================================================
@@ -132,6 +126,10 @@ Standard_Boolean Storage_OStream::Close()
 {
   SetOpenMode( Storage_VSNone );
 
+  std::string aStr = myBuffer.str();
+
+  myStream->write( aStr.c_str(), aStr.size() );
+
   return Standard_True;
 }
 
@@ -150,7 +148,7 @@ Standard_Boolean Storage_OStream::CanRead() const
 //=======================================================================
 Standard_Boolean Storage_OStream::CanWrite() const
 {
-  return myStream->good();
+  return myBuffer.good() && myStream->good();
 }
 
 //=======================================================================
@@ -168,7 +166,7 @@ Standard_Size Storage_OStream::Read( const Standard_Address /*theBuffer*/, const
 //=======================================================================
 Standard_Size Storage_OStream::Write (const Standard_Address theBuffer, const Standard_Size theSize)
 {
-  myStream->write((char*)theBuffer, theSize);
+  myBuffer.write((char*)theBuffer, theSize);
   return theSize;
 }
 
index 95c9ce8e5194c695cd3c5404e7d4cc7ffd375da8..255e5444d156720be95b0407a70b85e8b0714daf 100644 (file)
@@ -199,16 +199,35 @@ void XmlLDrivers_DocumentRetrievalDriver::Read
   LDOMParser aParser;
 
   Standard_Boolean aRes = Standard_True;
-  Handle(Storage_File) aFile = Handle(Storage_File)::DownCast(theDevice);
-  Handle(Storage_IStream) aStream = Handle(Storage_IStream)::DownCast(theDevice);
+  Handle(Storage_File) aFile = Handle(Storage_File)::DownCast(myDevice);
   if ( !aFile.IsNull() )
   {
     TCollection_AsciiString aPath( aFile->Path() );
     aRes = aParser.parse( aPath.ToCString() );
   }
-  else if ( !aStream.IsNull() && aStream->Stream() )
+  else if ( !myDevice.IsNull() && myDevice->CanRead() )
   {
-    aRes = aParser.parse( *aStream->Stream() );
+    if ( myDevice->Open( Storage_VSRead ) == Storage_VSOk )
+    {
+        Standard_Size aSize = 8000;
+        char* aBuf = (char*)malloc( aSize );
+        std::string aStr;
+        while ( !myDevice->IsEnd() )
+        {
+            Standard_Size aNum = myDevice->Read( aBuf, aSize );
+            aStr.append( aBuf, aNum );
+        }
+        free( aBuf );
+
+        myDevice->Close();
+
+        Standard_SStream aStream( std::ios::in );
+        aStream.str( aStr );
+
+        aRes = aParser.parse( aStream );
+    }
+    else
+        myReaderStatus = PCDM_RS_OpenError;
   }
 
   if (aRes)