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