mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-18 14:27:39 +03:00
Fix for problem with using nonseekable streams (ex boost filtering_streams with zip compressor/decompressor).
This commit is contained in:
@@ -200,8 +200,6 @@ PCDM_ReaderStatus CDF_Application::CanRetrieve(Handle(Storage_IODevice)& aDevice
|
||||
}
|
||||
}
|
||||
|
||||
aDevice->Close();
|
||||
|
||||
return PCDM_RS_OK;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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,16 +53,14 @@ 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();
|
||||
myBuffer.clear();
|
||||
Seek( 0 );
|
||||
}
|
||||
}
|
||||
@@ -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 )
|
||||
{
|
||||
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;
|
||||
fillBuffer();
|
||||
myBuffer.seekg( thePos, ios::end );
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -158,8 +165,26 @@ Standard_Boolean Storage_IStream::CanWrite() const
|
||||
//=======================================================================
|
||||
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 );
|
||||
}
|
||||
|
@@ -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
|
||||
myBuffer : SStream from Standard;
|
||||
myStream : OStreamPtr from Standard;
|
||||
end;
|
||||
|
@@ -5,6 +5,8 @@
|
||||
|
||||
#include <Storage_OStream.ixx>
|
||||
|
||||
#include <Standard_SStream.hxx>
|
||||
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
|
||||
@@ -14,7 +16,8 @@
|
||||
//=======================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user