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