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