// 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<ISequentialInStream> _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<IInStream> _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<IInStream> Stream; | |
UInt64 StartOffset; | |
UInt64 Size; | |
int BlockSizeLog; | |
CRecordVector<UInt32> 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<ISequentialOutStream> _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 |