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