1// LimitedStreams.h
2
3#ifndef ZIP7_INC_LIMITED_STREAMS_H
4#define ZIP7_INC_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#include "StreamUtils.h"
12
13Z7_CLASS_IMP_COM_1(
14  CLimitedSequentialInStream
15  , ISequentialInStream
16)
17  CMyComPtr<ISequentialInStream> _stream;
18  UInt64 _size;
19  UInt64 _pos;
20  bool _wasFinished;
21public:
22  void SetStream(ISequentialInStream *stream) { _stream = stream; }
23  void ReleaseStream() { _stream.Release(); }
24  void Init(UInt64 streamSize)
25  {
26    _size = streamSize;
27    _pos = 0;
28    _wasFinished = false;
29  }
30  UInt64 GetSize() const { return _pos; }
31  UInt64 GetRem() const { return _size - _pos; }
32  bool WasFinished() const { return _wasFinished; }
33};
34
35
36Z7_CLASS_IMP_IInStream(
37  CLimitedInStream
38)
39  CMyComPtr<IInStream> _stream;
40  UInt64 _virtPos;
41  UInt64 _physPos;
42  UInt64 _size;
43  UInt64 _startOffset;
44
45  HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); }
46public:
47  void SetStream(IInStream *stream) { _stream = stream; }
48  HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
49  {
50    _startOffset = startOffset;
51    _physPos = startOffset;
52    _virtPos = 0;
53    _size = size;
54    return SeekToPhys();
55  }
56  HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
57};
58
59HRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream);
60
61
62Z7_CLASS_IMP_IInStream(
63  CClusterInStream
64)
65  UInt64 _virtPos;
66  UInt64 _physPos;
67  UInt32 _curRem;
68public:
69  unsigned BlockSizeLog;
70  UInt64 Size;
71  CMyComPtr<IInStream> Stream;
72  CRecordVector<UInt32> Vector;
73  UInt64 StartOffset;
74
75  HRESULT SeekToPhys() { return InStream_SeekSet(Stream, _physPos); }
76
77  HRESULT InitAndSeek()
78  {
79    _curRem = 0;
80    _virtPos = 0;
81    _physPos = StartOffset;
82    if (Vector.Size() > 0)
83    {
84      _physPos = StartOffset + (Vector[0] << BlockSizeLog);
85      return SeekToPhys();
86    }
87    return S_OK;
88  }
89};
90
91
92
93const UInt64 k_SeekExtent_Phy_Type_ZeroFill = (UInt64)(Int64)-1;
94
95struct CSeekExtent
96{
97  UInt64 Virt;
98  UInt64 Phy;
99
100  void SetAs_ZeroFill() { Phy = k_SeekExtent_Phy_Type_ZeroFill; }
101  bool Is_ZeroFill() const { return Phy == k_SeekExtent_Phy_Type_ZeroFill; }
102};
103
104
105Z7_CLASS_IMP_IInStream(
106  CExtentsStream
107)
108  UInt64 _virtPos;
109  UInt64 _phyPos;
110  unsigned _prevExtentIndex;
111public:
112  CMyComPtr<IInStream> Stream;
113  CRecordVector<CSeekExtent> Extents;
114
115  void ReleaseStream() { Stream.Release(); }
116  void Init()
117  {
118    _virtPos = 0;
119    _phyPos = (UInt64)0 - 1; // we need Seek() for Stream
120    _prevExtentIndex = 0;
121  }
122};
123
124
125
126Z7_CLASS_IMP_COM_1(
127  CLimitedSequentialOutStream
128  , ISequentialOutStream
129)
130  CMyComPtr<ISequentialOutStream> _stream;
131  UInt64 _size;
132  bool _overflow;
133  bool _overflowIsAllowed;
134public:
135  void SetStream(ISequentialOutStream *stream) { _stream = stream; }
136  void ReleaseStream() { _stream.Release(); }
137  void Init(UInt64 size, bool overflowIsAllowed = false)
138  {
139    _size = size;
140    _overflow = false;
141    _overflowIsAllowed = overflowIsAllowed;
142  }
143  bool IsFinishedOK() const { return (_size == 0 && !_overflow); }
144  UInt64 GetRem() const { return _size; }
145};
146
147
148Z7_CLASS_IMP_IInStream(
149  CTailInStream
150)
151  UInt64 _virtPos;
152public:
153  CMyComPtr<IInStream> Stream;
154  UInt64 Offset;
155
156  void Init()
157  {
158    _virtPos = 0;
159  }
160  HRESULT SeekToStart() { return InStream_SeekSet(Stream, Offset); }
161};
162
163
164Z7_CLASS_IMP_IInStream(
165  CLimitedCachedInStream
166)
167  CMyComPtr<IInStream> _stream;
168  UInt64 _virtPos;
169  UInt64 _physPos;
170  UInt64 _size;
171  UInt64 _startOffset;
172
173  const Byte *_cache;
174  size_t _cacheSize;
175  size_t _cachePhyPos;
176
177  HRESULT SeekToPhys() { return InStream_SeekSet(_stream, _physPos); }
178public:
179  CByteBuffer Buffer;
180
181  void SetStream(IInStream *stream) { _stream = stream; }
182  void SetCache(size_t cacheSize, size_t cachePos)
183  {
184    _cache = Buffer;
185    _cacheSize = cacheSize;
186    _cachePhyPos = cachePos;
187  }
188
189  HRESULT InitAndSeek(UInt64 startOffset, UInt64 size)
190  {
191    _startOffset = startOffset;
192    _physPos = startOffset;
193    _virtPos = 0;
194    _size = size;
195    return SeekToPhys();
196  }
197
198  HRESULT SeekToStart() { return Seek(0, STREAM_SEEK_SET, NULL); }
199};
200
201
202class CTailOutStream Z7_final :
203  public IOutStream,
204  public CMyUnknownImp
205{
206  Z7_IFACES_IMP_UNK_2(ISequentialOutStream, IOutStream)
207
208  UInt64 _virtPos;
209  UInt64 _virtSize;
210public:
211  CMyComPtr<IOutStream> Stream;
212  UInt64 Offset;
213
214  void Init()
215  {
216    _virtPos = 0;
217    _virtSize = 0;
218  }
219};
220
221#endif
222