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; } WasFinished()33 bool WasFinished() const { return _wasFinished; } 34 }; 35 36 class 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 SeekToPhys()46 HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } 47 public: SetStream(IInStream * stream)48 void SetStream(IInStream *stream) { _stream = stream; } InitAndSeek(UInt64 startOffset,UInt64 size)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 SeekToStart()63 HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } 64 }; 65 66 HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream); 67 68 class CClusterInStream: 69 public IInStream, 70 public CMyUnknownImp 71 { 72 UInt64 _virtPos; 73 UInt64 _physPos; 74 UInt32 _curRem; 75 public: 76 CMyComPtr<IInStream> Stream; 77 UInt64 StartOffset; 78 UInt64 Size; 79 unsigned BlockSizeLog; 80 CRecordVector<UInt32> Vector; 81 SeekToPhys()82 HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } 83 InitAndSeek()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 103 struct CSeekExtent 104 { 105 UInt64 Phy; 106 UInt64 Virt; 107 }; 108 109 class CExtentsStream: 110 public IInStream, 111 public CMyUnknownImp 112 { 113 UInt64 _phyPos; 114 UInt64 _virtPos; 115 bool _needStartSeek; 116 SeekToPhys()117 HRESULT SeekToPhys() { return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); } 118 119 public: 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); ReleaseStream()126 void ReleaseStream() { Stream.Release(); } 127 Init()128 void Init() 129 { 130 _virtPos = 0; 131 _phyPos = 0; 132 _needStartSeek = true; 133 } 134 }; 135 136 class CLimitedSequentialOutStream: 137 public ISequentialOutStream, 138 public CMyUnknownImp 139 { 140 CMyComPtr<ISequentialOutStream> _stream; 141 UInt64 _size; 142 bool _overflow; 143 bool _overflowIsAllowed; 144 public: 145 MY_UNKNOWN_IMP1(ISequentialOutStream) 146 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); SetStream(ISequentialOutStream * stream)147 void SetStream(ISequentialOutStream *stream) { _stream = stream; } ReleaseStream()148 void ReleaseStream() { _stream.Release(); } 149 void Init(UInt64 size, bool overflowIsAllowed = false) 150 { 151 _size = size; 152 _overflow = false; 153 _overflowIsAllowed = overflowIsAllowed; 154 } IsFinishedOK()155 bool IsFinishedOK() const { return (_size == 0 && !_overflow); } GetRem()156 UInt64 GetRem() const { return _size; } 157 }; 158 159 160 class CTailInStream: 161 public IInStream, 162 public CMyUnknownImp 163 { 164 UInt64 _virtPos; 165 public: 166 CMyComPtr<IInStream> Stream; 167 UInt64 Offset; 168 Init()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 SeekToStart()179 HRESULT SeekToStart() { return Stream->Seek(Offset, STREAM_SEEK_SET, NULL); } 180 }; 181 182 class 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 SeekToPhys()197 HRESULT SeekToPhys() { return _stream->Seek(_physPos, STREAM_SEEK_SET, NULL); } 198 public: 199 CByteBuffer Buffer; 200 SetStream(IInStream * stream)201 void SetStream(IInStream *stream) { _stream = stream; } SetCache(size_t cacheSize,size_t cachePos)202 void SetCache(size_t cacheSize, size_t cachePos) 203 { 204 _cache = Buffer; 205 _cacheSize = cacheSize; 206 _cachePhyPos = cachePos; 207 } 208 InitAndSeek(UInt64 startOffset,UInt64 size)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 SeekToStart()223 HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } 224 }; 225 226 class CTailOutStream: 227 public IOutStream, 228 public CMyUnknownImp 229 { 230 UInt64 _virtPos; 231 UInt64 _virtSize; 232 public: 233 CMyComPtr<IOutStream> Stream; 234 UInt64 Offset; 235 ~CTailOutStream()236 virtual ~CTailOutStream() {} 237 MY_UNKNOWN_IMP2(ISequentialOutStream,IOutStream)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