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((Int64)_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((Int64)_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 105 106 const UInt64 k_SeekExtent_Phy_Type_ZeroFill = (UInt64)(Int64)-1; 107 108 struct CSeekExtent 109 { 110 UInt64 Virt; 111 UInt64 Phy; 112 SetAs_ZeroFillCSeekExtent113 void SetAs_ZeroFill() { Phy = k_SeekExtent_Phy_Type_ZeroFill; } Is_ZeroFillCSeekExtent114 bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; } 115 }; 116 117 class CExtentsStream: 118 public IInStream, 119 public CMyUnknownImp 120 { 121 UInt64 _virtPos; 122 UInt64 _phyPos; 123 unsigned _prevExtentIndex; 124 125 public: 126 CMyComPtr<IInStream> Stream; 127 CRecordVector<CSeekExtent> Extents; 128 129 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 130 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 131 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); ReleaseStream()132 void ReleaseStream() { Stream.Release(); } 133 Init()134 void Init() 135 { 136 _virtPos = 0; 137 _phyPos = (UInt64)0 - 1; // we need Seek() for Stream 138 _prevExtentIndex = 0; 139 } 140 }; 141 142 143 144 class CLimitedSequentialOutStream: 145 public ISequentialOutStream, 146 public CMyUnknownImp 147 { 148 CMyComPtr<ISequentialOutStream> _stream; 149 UInt64 _size; 150 bool _overflow; 151 bool _overflowIsAllowed; 152 public: 153 MY_UNKNOWN_IMP1(ISequentialOutStream) 154 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); SetStream(ISequentialOutStream * stream)155 void SetStream(ISequentialOutStream *stream) { _stream = stream; } ReleaseStream()156 void ReleaseStream() { _stream.Release(); } 157 void Init(UInt64 size, bool overflowIsAllowed = false) 158 { 159 _size = size; 160 _overflow = false; 161 _overflowIsAllowed = overflowIsAllowed; 162 } IsFinishedOK()163 bool IsFinishedOK() const { return (_size == 0 && !_overflow); } GetRem()164 UInt64 GetRem() const { return _size; } 165 }; 166 167 168 class CTailInStream: 169 public IInStream, 170 public CMyUnknownImp 171 { 172 UInt64 _virtPos; 173 public: 174 CMyComPtr<IInStream> Stream; 175 UInt64 Offset; 176 Init()177 void Init() 178 { 179 _virtPos = 0; 180 } 181 182 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 183 184 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 185 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 186 SeekToStart()187 HRESULT SeekToStart() { return Stream->Seek((Int64)Offset, STREAM_SEEK_SET, NULL); } 188 }; 189 190 class CLimitedCachedInStream: 191 public IInStream, 192 public CMyUnknownImp 193 { 194 CMyComPtr<IInStream> _stream; 195 UInt64 _virtPos; 196 UInt64 _physPos; 197 UInt64 _size; 198 UInt64 _startOffset; 199 200 const Byte *_cache; 201 size_t _cacheSize; 202 size_t _cachePhyPos; 203 204 SeekToPhys()205 HRESULT SeekToPhys() { return _stream->Seek((Int64)_physPos, STREAM_SEEK_SET, NULL); } 206 public: 207 CByteBuffer Buffer; 208 SetStream(IInStream * stream)209 void SetStream(IInStream *stream) { _stream = stream; } SetCache(size_t cacheSize,size_t cachePos)210 void SetCache(size_t cacheSize, size_t cachePos) 211 { 212 _cache = Buffer; 213 _cacheSize = cacheSize; 214 _cachePhyPos = cachePos; 215 } 216 InitAndSeek(UInt64 startOffset,UInt64 size)217 HRESULT InitAndSeek(UInt64 startOffset, UInt64 size) 218 { 219 _startOffset = startOffset; 220 _physPos = startOffset; 221 _virtPos = 0; 222 _size = size; 223 return SeekToPhys(); 224 } 225 226 MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) 227 228 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 229 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 230 SeekToStart()231 HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); } 232 }; 233 234 class CTailOutStream: 235 public IOutStream, 236 public CMyUnknownImp 237 { 238 UInt64 _virtPos; 239 UInt64 _virtSize; 240 public: 241 CMyComPtr<IOutStream> Stream; 242 UInt64 Offset; 243 ~CTailOutStream()244 virtual ~CTailOutStream() {} 245 MY_UNKNOWN_IMP2(ISequentialOutStream,IOutStream)246 MY_UNKNOWN_IMP2(ISequentialOutStream, IOutStream) 247 248 void Init() 249 { 250 _virtPos = 0; 251 _virtSize = 0; 252 } 253 254 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 255 STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); 256 STDMETHOD(SetSize)(UInt64 newSize); 257 }; 258 259 #endif 260