• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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