// LimitedStreams.h #ifndef __LIMITED_STREAMS_H #define __LIMITED_STREAMS_H #include "../../Common/MyCom.h" #include "../../Common/MyVector.h" #include "../IStream.h" class CLimitedSequentialInStream: public ISequentialInStream, public CMyUnknownImp { CMyComPtr _stream; UInt64 _size; UInt64 _pos; bool _wasFinished; public: void SetStream(ISequentialInStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(UInt64 streamSize) { _size = streamSize; _pos = 0; _wasFinished = false; } MY_UNKNOWN_IMP STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); UInt64 GetSize() const { return _pos; } bool WasFinished() const { return _wasFinished; } }; class CLimitedInStream: public IInStream, public CMyUnknownImp { CMyComPtr _stream; UInt64 _virtPos; UInt64 _physPos; UInt64 _size; UInt64 _startOffset; HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } public: void SetStream(IInStream *stream) { _stream = stream; } HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) { _startOffset = startOffset; _physPos = startOffset; _virtPos = 0; _size = size; return SeekToPhys(); } MY_UNKNOWN_IMP1(IInStream) STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } }; class CClusterInStream: public IInStream, public CMyUnknownImp { UInt64 _virtPos; UInt64 _physPos; UInt32 _curRem; public: CMyComPtr Stream; UInt64 StartOffset; UInt64 Size; int BlockSizeLog; CRecordVector Vector; HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } HRESULT InitAndSeek() { _curRem = 0; _virtPos = 0; _physPos = StartOffset; if (Vector.Size() > 0) { _physPos = StartOffset + (Vector[0] << BlockSizeLog); return SeekToPhys(); } return S_OK; } MY_UNKNOWN_IMP1(IInStream) STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); class CLimitedSequentialOutStream: public ISequentialOutStream, public CMyUnknownImp { CMyComPtr _stream; UInt64 _size; bool _overflow; bool _overflowIsAllowed; public: MY_UNKNOWN_IMP STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } void Init(UInt64 size, bool overflowIsAllowed = false) { _size = size; _overflow = false; _overflowIsAllowed = overflowIsAllowed; } bool IsFinishedOK() const { return (_size == 0 && !_overflow); } UInt64 GetRem() const { return _size; } }; #endif