1// LimitedStreams.h 2 3#ifndef __LIMITED_STREAMS_H 4#define __LIMITED_STREAMS_H 5 6#include "../../Common/MyBuffer.h" 7#include "../../Common/MyCom.h" 8#include "../../Common/MyVector.h" 9#include "../IStream.h" 10 11class CLimitedSequentialInStream: 12 public ISequentialInStream, 13 public CMyUnknownImp 14{ 15 CMyComPtr<ISequentialInStream> _stream; 16 UInt64 _size; 17 UInt64 _pos; 18 bool _wasFinished; 19public: 20 void SetStream(ISequentialInStream *stream) { _stream = stream; } 21 void ReleaseStream() { _stream.Release(); } 22 void Init(UInt64 streamSize) 23 { 24 _size = streamSize; 25 _pos = 0; 26 _wasFinished = false; 27 } 28 29 MY_UNKNOWN_IMP1(ISequentialInStream) 30 31 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 32 UInt64 GetSize() const { return _pos; } 33 bool WasFinished() const { return _wasFinished; } 34}; 35 36class CLimitedInStream: 37 public IInStream, 38 public CMyUnknownImp 39{ 40 CMyComPtr<IInStream> _stream; 41 UInt64 _virtPos; 42 UInt64 _physPos; 43 UInt64 _size; 44 UInt64 _startOffset; 45 46 HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } 47public: 48 void SetStream(IInStream *stream) { _stream = stream; } 49 HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) 50 { 51 _startOffset = startOffset; 52 _physPos = startOffset; 53 _virtPos = 0; 54 _size = size; 55 return SeekToPhys(); 56 } 57 58 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 59 60 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 61 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 62 63 HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } 64}; 65 66HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); 67 68class CClusterInStream: 69 public IInStream, 70 public CMyUnknownImp 71{ 72 UInt64 _virtPos; 73 UInt64 _physPos; 74 UInt32 _curRem; 75public: 76 CMyComPtr<IInStream> Stream; 77 UInt64 StartOffset; 78 UInt64 Size; 79 unsigned BlockSizeLog; 80 CRecordVector<UInt32> Vector; 81 82 HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } 83 84 HRESULT InitAndSeek() 85 { 86 _curRem = 0; 87 _virtPos = 0; 88 _physPos = StartOffset; 89 if (Vector.Size() > 0) 90 { 91 _physPos = StartOffset + (Vector[0] << BlockSizeLog); 92 return SeekToPhys(); 93 } 94 return S_OK; 95 } 96 97 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 98 99 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 100 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 101}; 102 103struct CSeekExtent 104{ 105 UInt64 Phy; 106 UInt64 Virt; 107}; 108 109class CExtentsStream: 110 public IInStream, 111 public CMyUnknownImp 112{ 113 UInt64 _phyPos; 114 UInt64 _virtPos; 115 bool _needStartSeek; 116 117 HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); } 118 119public: 120 CMyComPtr<IInStream> Stream; 121 CRecordVector<CSeekExtent> Extents; 122 123 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 124 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 125 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 126 void ReleaseStream() { Stream.Release(); } 127 128 void Init() 129 { 130 _virtPos = 0; 131 _phyPos = 0; 132 _needStartSeek = true; 133 } 134}; 135 136class CLimitedSequentialOutStream: 137 public ISequentialOutStream, 138 public CMyUnknownImp 139{ 140 CMyComPtr<ISequentialOutStream> _stream; 141 UInt64 _size; 142 bool _overflow; 143 bool _overflowIsAllowed; 144public: 145 MY_UNKNOWN_IMP1(ISequentialOutStream) 146 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 147 void SetStream(ISequentialOutStream *stream) { _stream = stream; } 148 void ReleaseStream() { _stream.Release(); } 149 void Init(UInt64 size, bool overflowIsAllowed = false) 150 { 151 _size = size; 152 _overflow = false; 153 _overflowIsAllowed = overflowIsAllowed; 154 } 155 bool IsFinishedOK() const { return (_size == 0 && !_overflow); } 156 UInt64 GetRem() const { return _size; } 157}; 158 159 160class CTailInStream: 161 public IInStream, 162 public CMyUnknownImp 163{ 164 UInt64 _virtPos; 165public: 166 CMyComPtr<IInStream> Stream; 167 UInt64 Offset; 168 169 void Init() 170 { 171 _virtPos = 0; 172 } 173 174 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 175 176 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 177 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 178 179 HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); } 180}; 181 182class CLimitedCachedInStream: 183 public IInStream, 184 public CMyUnknownImp 185{ 186 CMyComPtr<IInStream> _stream; 187 UInt64 _virtPos; 188 UInt64 _physPos; 189 UInt64 _size; 190 UInt64 _startOffset; 191 192 const Byte *_cache; 193 size_t _cacheSize; 194 size_t _cachePhyPos; 195 196 197 HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } 198public: 199 CByteBuffer Buffer; 200 201 void SetStream(IInStream *stream) { _stream = stream; } 202 void SetCache(size_t cacheSize, size_t cachePos) 203 { 204 _cache = Buffer; 205 _cacheSize = cacheSize; 206 _cachePhyPos = cachePos; 207 } 208 209 HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) 210 { 211 _startOffset = startOffset; 212 _physPos = startOffset; 213 _virtPos = 0; 214 _size = size; 215 return SeekToPhys(); 216 } 217 218 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 219 220 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 221 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 222 223 HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } 224}; 225 226class CTailOutStream: 227 public IOutStream, 228 public CMyUnknownImp 229{ 230 UInt64 _virtPos; 231 UInt64 _virtSize; 232public: 233 CMyComPtr<IOutStream> Stream; 234 UInt64 Offset; 235 236 virtual ~CTailOutStream() {} 237 238 MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream) 239 240 void Init() 241 { 242 _virtPos = 0; 243 _virtSize = 0; 244 } 245 246 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 247 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 248 STDMETHOD(SetSize)(UInt64 newSize); 249}; 250 251#endif 252