1
0
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:
stv
2015-07-02 10:29:44 +03:00
parent f18171c815
commit f00abcb359
7 changed files with 153 additions and 75 deletions

View File

@@ -200,8 +200,6 @@ PCDM_ReaderStatus CDF_Application::CanRetrieve(Handle(Storage_IODevice)& aDevice
}
}
aDevice->Close();
return PCDM_RS_OK;
}

View 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;
}

View 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;

View 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,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 );
}

View 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
myBuffer : SStream from Standard;
myStream : OStreamPtr from Standard;
end;

View File

@@ -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;
}

View 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)