1370b324cSopenharmony_ci// LimitedStreams.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include <string.h>
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "LimitedStreams.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ciZ7_COM7F_IMF(CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
10370b324cSopenharmony_ci{
11370b324cSopenharmony_ci  UInt32 realProcessedSize = 0;
12370b324cSopenharmony_ci  {
13370b324cSopenharmony_ci    const UInt64 rem = _size - _pos;
14370b324cSopenharmony_ci    if (size > rem)
15370b324cSopenharmony_ci      size = (UInt32)rem;
16370b324cSopenharmony_ci  }
17370b324cSopenharmony_ci  HRESULT result = S_OK;
18370b324cSopenharmony_ci  if (size != 0)
19370b324cSopenharmony_ci  {
20370b324cSopenharmony_ci    result = _stream->Read(data, size, &realProcessedSize);
21370b324cSopenharmony_ci    _pos += realProcessedSize;
22370b324cSopenharmony_ci    if (realProcessedSize == 0)
23370b324cSopenharmony_ci      _wasFinished = true;
24370b324cSopenharmony_ci  }
25370b324cSopenharmony_ci  if (processedSize)
26370b324cSopenharmony_ci    *processedSize = realProcessedSize;
27370b324cSopenharmony_ci  return result;
28370b324cSopenharmony_ci}
29370b324cSopenharmony_ci
30370b324cSopenharmony_ciZ7_COM7F_IMF(CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
31370b324cSopenharmony_ci{
32370b324cSopenharmony_ci  if (processedSize)
33370b324cSopenharmony_ci    *processedSize = 0;
34370b324cSopenharmony_ci  if (_virtPos >= _size)
35370b324cSopenharmony_ci  {
36370b324cSopenharmony_ci    // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
37370b324cSopenharmony_ci    return S_OK;
38370b324cSopenharmony_ci    // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
39370b324cSopenharmony_ci  }
40370b324cSopenharmony_ci  {
41370b324cSopenharmony_ci    const UInt64 rem = _size - _virtPos;
42370b324cSopenharmony_ci    if (size > rem)
43370b324cSopenharmony_ci      size = (UInt32)rem;
44370b324cSopenharmony_ci  }
45370b324cSopenharmony_ci  UInt64 newPos = _startOffset + _virtPos;
46370b324cSopenharmony_ci  if (newPos != _physPos)
47370b324cSopenharmony_ci  {
48370b324cSopenharmony_ci    _physPos = newPos;
49370b324cSopenharmony_ci    RINOK(SeekToPhys())
50370b324cSopenharmony_ci  }
51370b324cSopenharmony_ci  HRESULT res = _stream->Read(data, size, &size);
52370b324cSopenharmony_ci  if (processedSize)
53370b324cSopenharmony_ci    *processedSize = size;
54370b324cSopenharmony_ci  _physPos += size;
55370b324cSopenharmony_ci  _virtPos += size;
56370b324cSopenharmony_ci  return res;
57370b324cSopenharmony_ci}
58370b324cSopenharmony_ci
59370b324cSopenharmony_ciZ7_COM7F_IMF(CLimitedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
60370b324cSopenharmony_ci{
61370b324cSopenharmony_ci  switch (seekOrigin)
62370b324cSopenharmony_ci  {
63370b324cSopenharmony_ci    case STREAM_SEEK_SET: break;
64370b324cSopenharmony_ci    case STREAM_SEEK_CUR: offset += _virtPos; break;
65370b324cSopenharmony_ci    case STREAM_SEEK_END: offset += _size; break;
66370b324cSopenharmony_ci    default: return STG_E_INVALIDFUNCTION;
67370b324cSopenharmony_ci  }
68370b324cSopenharmony_ci  if (offset < 0)
69370b324cSopenharmony_ci    return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
70370b324cSopenharmony_ci  _virtPos = (UInt64)offset;
71370b324cSopenharmony_ci  if (newPosition)
72370b324cSopenharmony_ci    *newPosition = _virtPos;
73370b324cSopenharmony_ci  return S_OK;
74370b324cSopenharmony_ci}
75370b324cSopenharmony_ci
76370b324cSopenharmony_ciHRESULT CreateLimitedInStream(IInStream *inStream, UInt64 pos, UInt64 size, ISequentialInStream **resStream)
77370b324cSopenharmony_ci{
78370b324cSopenharmony_ci  *resStream = NULL;
79370b324cSopenharmony_ci  CLimitedInStream *streamSpec = new CLimitedInStream;
80370b324cSopenharmony_ci  CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
81370b324cSopenharmony_ci  streamSpec->SetStream(inStream);
82370b324cSopenharmony_ci  RINOK(streamSpec->InitAndSeek(pos, size))
83370b324cSopenharmony_ci  streamSpec->SeekToStart();
84370b324cSopenharmony_ci  *resStream = streamTemp.Detach();
85370b324cSopenharmony_ci  return S_OK;
86370b324cSopenharmony_ci}
87370b324cSopenharmony_ci
88370b324cSopenharmony_ciZ7_COM7F_IMF(CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
89370b324cSopenharmony_ci{
90370b324cSopenharmony_ci  if (processedSize)
91370b324cSopenharmony_ci    *processedSize = 0;
92370b324cSopenharmony_ci  if (_virtPos >= Size)
93370b324cSopenharmony_ci    return S_OK;
94370b324cSopenharmony_ci  {
95370b324cSopenharmony_ci    UInt64 rem = Size - _virtPos;
96370b324cSopenharmony_ci    if (size > rem)
97370b324cSopenharmony_ci      size = (UInt32)rem;
98370b324cSopenharmony_ci  }
99370b324cSopenharmony_ci  if (size == 0)
100370b324cSopenharmony_ci    return S_OK;
101370b324cSopenharmony_ci
102370b324cSopenharmony_ci  if (_curRem == 0)
103370b324cSopenharmony_ci  {
104370b324cSopenharmony_ci    const UInt32 blockSize = (UInt32)1 << BlockSizeLog;
105370b324cSopenharmony_ci    const UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog);
106370b324cSopenharmony_ci    const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1);
107370b324cSopenharmony_ci    const UInt32 phyBlock = Vector[virtBlock];
108370b324cSopenharmony_ci
109370b324cSopenharmony_ci    UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock;
110370b324cSopenharmony_ci    if (newPos != _physPos)
111370b324cSopenharmony_ci    {
112370b324cSopenharmony_ci      _physPos = newPos;
113370b324cSopenharmony_ci      RINOK(SeekToPhys())
114370b324cSopenharmony_ci    }
115370b324cSopenharmony_ci
116370b324cSopenharmony_ci    _curRem = blockSize - offsetInBlock;
117370b324cSopenharmony_ci
118370b324cSopenharmony_ci    for (unsigned i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++)
119370b324cSopenharmony_ci      _curRem += (UInt32)1 << BlockSizeLog;
120370b324cSopenharmony_ci  }
121370b324cSopenharmony_ci
122370b324cSopenharmony_ci  if (size > _curRem)
123370b324cSopenharmony_ci    size = _curRem;
124370b324cSopenharmony_ci  HRESULT res = Stream->Read(data, size, &size);
125370b324cSopenharmony_ci  if (processedSize)
126370b324cSopenharmony_ci    *processedSize = size;
127370b324cSopenharmony_ci  _physPos += size;
128370b324cSopenharmony_ci  _virtPos += size;
129370b324cSopenharmony_ci  _curRem -= size;
130370b324cSopenharmony_ci  return res;
131370b324cSopenharmony_ci}
132370b324cSopenharmony_ci
133370b324cSopenharmony_ciZ7_COM7F_IMF(CClusterInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
134370b324cSopenharmony_ci{
135370b324cSopenharmony_ci  switch (seekOrigin)
136370b324cSopenharmony_ci  {
137370b324cSopenharmony_ci    case STREAM_SEEK_SET: break;
138370b324cSopenharmony_ci    case STREAM_SEEK_CUR: offset += _virtPos; break;
139370b324cSopenharmony_ci    case STREAM_SEEK_END: offset += Size; break;
140370b324cSopenharmony_ci    default: return STG_E_INVALIDFUNCTION;
141370b324cSopenharmony_ci  }
142370b324cSopenharmony_ci  if (offset < 0)
143370b324cSopenharmony_ci    return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
144370b324cSopenharmony_ci  if (_virtPos != (UInt64)offset)
145370b324cSopenharmony_ci    _curRem = 0;
146370b324cSopenharmony_ci  _virtPos = (UInt64)offset;
147370b324cSopenharmony_ci  if (newPosition)
148370b324cSopenharmony_ci    *newPosition = (UInt64)offset;
149370b324cSopenharmony_ci  return S_OK;
150370b324cSopenharmony_ci}
151370b324cSopenharmony_ci
152370b324cSopenharmony_ci
153370b324cSopenharmony_ciZ7_COM7F_IMF(CExtentsStream::Read(void *data, UInt32 size, UInt32 *processedSize))
154370b324cSopenharmony_ci{
155370b324cSopenharmony_ci  if (processedSize)
156370b324cSopenharmony_ci    *processedSize = 0;
157370b324cSopenharmony_ci  const UInt64 virt = _virtPos;
158370b324cSopenharmony_ci  if (virt >= Extents.Back().Virt)
159370b324cSopenharmony_ci    return S_OK;
160370b324cSopenharmony_ci  if (size == 0)
161370b324cSopenharmony_ci    return S_OK;
162370b324cSopenharmony_ci
163370b324cSopenharmony_ci  unsigned left = _prevExtentIndex;
164370b324cSopenharmony_ci  if (virt <  Extents[left].Virt ||
165370b324cSopenharmony_ci      virt >= Extents[left + 1].Virt)
166370b324cSopenharmony_ci  {
167370b324cSopenharmony_ci    left = 0;
168370b324cSopenharmony_ci    unsigned right = Extents.Size() - 1;
169370b324cSopenharmony_ci    for (;;)
170370b324cSopenharmony_ci    {
171370b324cSopenharmony_ci      const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
172370b324cSopenharmony_ci      if (mid == left)
173370b324cSopenharmony_ci        break;
174370b324cSopenharmony_ci      if (virt < Extents[mid].Virt)
175370b324cSopenharmony_ci        right = mid;
176370b324cSopenharmony_ci      else
177370b324cSopenharmony_ci        left = mid;
178370b324cSopenharmony_ci    }
179370b324cSopenharmony_ci    _prevExtentIndex = left;
180370b324cSopenharmony_ci  }
181370b324cSopenharmony_ci
182370b324cSopenharmony_ci  {
183370b324cSopenharmony_ci    const UInt64 rem = Extents[left + 1].Virt - virt;
184370b324cSopenharmony_ci    if (size > rem)
185370b324cSopenharmony_ci      size = (UInt32)rem;
186370b324cSopenharmony_ci  }
187370b324cSopenharmony_ci
188370b324cSopenharmony_ci  const CSeekExtent &extent = Extents[left];
189370b324cSopenharmony_ci
190370b324cSopenharmony_ci  if (extent.Is_ZeroFill())
191370b324cSopenharmony_ci  {
192370b324cSopenharmony_ci    memset(data, 0, size);
193370b324cSopenharmony_ci    _virtPos += size;
194370b324cSopenharmony_ci    if (processedSize)
195370b324cSopenharmony_ci      *processedSize = size;
196370b324cSopenharmony_ci    return S_OK;
197370b324cSopenharmony_ci  }
198370b324cSopenharmony_ci
199370b324cSopenharmony_ci  {
200370b324cSopenharmony_ci    const UInt64 phy = extent.Phy + (virt - extent.Virt);
201370b324cSopenharmony_ci    if (_phyPos != phy)
202370b324cSopenharmony_ci    {
203370b324cSopenharmony_ci      _phyPos = (UInt64)0 - 1;  // we don't trust seek_pos in case of error
204370b324cSopenharmony_ci      RINOK(InStream_SeekSet(Stream, phy))
205370b324cSopenharmony_ci      _phyPos = phy;
206370b324cSopenharmony_ci    }
207370b324cSopenharmony_ci  }
208370b324cSopenharmony_ci
209370b324cSopenharmony_ci  const HRESULT res = Stream->Read(data, size, &size);
210370b324cSopenharmony_ci  _virtPos += size;
211370b324cSopenharmony_ci  if (res == S_OK)
212370b324cSopenharmony_ci    _phyPos += size;
213370b324cSopenharmony_ci  else
214370b324cSopenharmony_ci    _phyPos = (UInt64)0 - 1;  // we don't trust seek_pos in case of error
215370b324cSopenharmony_ci  if (processedSize)
216370b324cSopenharmony_ci    *processedSize = size;
217370b324cSopenharmony_ci  return res;
218370b324cSopenharmony_ci}
219370b324cSopenharmony_ci
220370b324cSopenharmony_ci
221370b324cSopenharmony_ciZ7_COM7F_IMF(CExtentsStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
222370b324cSopenharmony_ci{
223370b324cSopenharmony_ci  switch (seekOrigin)
224370b324cSopenharmony_ci  {
225370b324cSopenharmony_ci    case STREAM_SEEK_SET: break;
226370b324cSopenharmony_ci    case STREAM_SEEK_CUR: offset += _virtPos; break;
227370b324cSopenharmony_ci    case STREAM_SEEK_END: offset += Extents.Back().Virt; break;
228370b324cSopenharmony_ci    default: return STG_E_INVALIDFUNCTION;
229370b324cSopenharmony_ci  }
230370b324cSopenharmony_ci  if (offset < 0)
231370b324cSopenharmony_ci    return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
232370b324cSopenharmony_ci  _virtPos = (UInt64)offset;
233370b324cSopenharmony_ci  if (newPosition)
234370b324cSopenharmony_ci    *newPosition = _virtPos;
235370b324cSopenharmony_ci  return S_OK;
236370b324cSopenharmony_ci}
237370b324cSopenharmony_ci
238370b324cSopenharmony_ci
239370b324cSopenharmony_ciZ7_COM7F_IMF(CLimitedSequentialOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
240370b324cSopenharmony_ci{
241370b324cSopenharmony_ci  HRESULT result = S_OK;
242370b324cSopenharmony_ci  if (processedSize)
243370b324cSopenharmony_ci    *processedSize = 0;
244370b324cSopenharmony_ci  if (size > _size)
245370b324cSopenharmony_ci  {
246370b324cSopenharmony_ci    if (_size == 0)
247370b324cSopenharmony_ci    {
248370b324cSopenharmony_ci      _overflow = true;
249370b324cSopenharmony_ci      if (!_overflowIsAllowed)
250370b324cSopenharmony_ci        return E_FAIL;
251370b324cSopenharmony_ci      if (processedSize)
252370b324cSopenharmony_ci        *processedSize = size;
253370b324cSopenharmony_ci      return S_OK;
254370b324cSopenharmony_ci    }
255370b324cSopenharmony_ci    size = (UInt32)_size;
256370b324cSopenharmony_ci  }
257370b324cSopenharmony_ci  if (_stream)
258370b324cSopenharmony_ci    result = _stream->Write(data, size, &size);
259370b324cSopenharmony_ci  _size -= size;
260370b324cSopenharmony_ci  if (processedSize)
261370b324cSopenharmony_ci    *processedSize = size;
262370b324cSopenharmony_ci  return result;
263370b324cSopenharmony_ci}
264370b324cSopenharmony_ci
265370b324cSopenharmony_ci
266370b324cSopenharmony_ciZ7_COM7F_IMF(CTailInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
267370b324cSopenharmony_ci{
268370b324cSopenharmony_ci  UInt32 cur;
269370b324cSopenharmony_ci  HRESULT res = Stream->Read(data, size, &cur);
270370b324cSopenharmony_ci  if (processedSize)
271370b324cSopenharmony_ci    *processedSize = cur;
272370b324cSopenharmony_ci  _virtPos += cur;
273370b324cSopenharmony_ci  return res;
274370b324cSopenharmony_ci}
275370b324cSopenharmony_ci
276370b324cSopenharmony_ciZ7_COM7F_IMF(CTailInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
277370b324cSopenharmony_ci{
278370b324cSopenharmony_ci  switch (seekOrigin)
279370b324cSopenharmony_ci  {
280370b324cSopenharmony_ci    case STREAM_SEEK_SET: break;
281370b324cSopenharmony_ci    case STREAM_SEEK_CUR: offset += _virtPos; break;
282370b324cSopenharmony_ci    case STREAM_SEEK_END:
283370b324cSopenharmony_ci    {
284370b324cSopenharmony_ci      UInt64 pos = 0;
285370b324cSopenharmony_ci      RINOK(Stream->Seek(offset, STREAM_SEEK_END, &pos))
286370b324cSopenharmony_ci      if (pos < Offset)
287370b324cSopenharmony_ci        return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
288370b324cSopenharmony_ci      _virtPos = pos - Offset;
289370b324cSopenharmony_ci      if (newPosition)
290370b324cSopenharmony_ci        *newPosition = _virtPos;
291370b324cSopenharmony_ci      return S_OK;
292370b324cSopenharmony_ci    }
293370b324cSopenharmony_ci    default: return STG_E_INVALIDFUNCTION;
294370b324cSopenharmony_ci  }
295370b324cSopenharmony_ci  if (offset < 0)
296370b324cSopenharmony_ci    return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
297370b324cSopenharmony_ci  _virtPos = (UInt64)offset;
298370b324cSopenharmony_ci  if (newPosition)
299370b324cSopenharmony_ci    *newPosition = _virtPos;
300370b324cSopenharmony_ci  return InStream_SeekSet(Stream, Offset + _virtPos);
301370b324cSopenharmony_ci}
302370b324cSopenharmony_ci
303370b324cSopenharmony_ciZ7_COM7F_IMF(CLimitedCachedInStream::Read(void *data, UInt32 size, UInt32 *processedSize))
304370b324cSopenharmony_ci{
305370b324cSopenharmony_ci  if (processedSize)
306370b324cSopenharmony_ci    *processedSize = 0;
307370b324cSopenharmony_ci  if (_virtPos >= _size)
308370b324cSopenharmony_ci  {
309370b324cSopenharmony_ci    // 9.31: Fixed. Windows doesn't return error in ReadFile and IStream->Read in that case.
310370b324cSopenharmony_ci    return S_OK;
311370b324cSopenharmony_ci    // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
312370b324cSopenharmony_ci  }
313370b324cSopenharmony_ci  UInt64 rem = _size - _virtPos;
314370b324cSopenharmony_ci  if (rem < size)
315370b324cSopenharmony_ci    size = (UInt32)rem;
316370b324cSopenharmony_ci
317370b324cSopenharmony_ci  UInt64 newPos = _startOffset + _virtPos;
318370b324cSopenharmony_ci  UInt64 offsetInCache = newPos - _cachePhyPos;
319370b324cSopenharmony_ci  HRESULT res = S_OK;
320370b324cSopenharmony_ci  if (newPos >= _cachePhyPos &&
321370b324cSopenharmony_ci      offsetInCache <= _cacheSize &&
322370b324cSopenharmony_ci      size <= _cacheSize - (size_t)offsetInCache)
323370b324cSopenharmony_ci  {
324370b324cSopenharmony_ci    if (size != 0)
325370b324cSopenharmony_ci      memcpy(data, _cache + (size_t)offsetInCache, size);
326370b324cSopenharmony_ci  }
327370b324cSopenharmony_ci  else
328370b324cSopenharmony_ci  {
329370b324cSopenharmony_ci    if (newPos != _physPos)
330370b324cSopenharmony_ci    {
331370b324cSopenharmony_ci      _physPos = newPos;
332370b324cSopenharmony_ci      RINOK(SeekToPhys())
333370b324cSopenharmony_ci    }
334370b324cSopenharmony_ci    res = _stream->Read(data, size, &size);
335370b324cSopenharmony_ci    _physPos += size;
336370b324cSopenharmony_ci  }
337370b324cSopenharmony_ci  if (processedSize)
338370b324cSopenharmony_ci    *processedSize = size;
339370b324cSopenharmony_ci  _virtPos += size;
340370b324cSopenharmony_ci  return res;
341370b324cSopenharmony_ci}
342370b324cSopenharmony_ci
343370b324cSopenharmony_ciZ7_COM7F_IMF(CLimitedCachedInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
344370b324cSopenharmony_ci{
345370b324cSopenharmony_ci  switch (seekOrigin)
346370b324cSopenharmony_ci  {
347370b324cSopenharmony_ci    case STREAM_SEEK_SET: break;
348370b324cSopenharmony_ci    case STREAM_SEEK_CUR: offset += _virtPos; break;
349370b324cSopenharmony_ci    case STREAM_SEEK_END: offset += _size; break;
350370b324cSopenharmony_ci    default: return STG_E_INVALIDFUNCTION;
351370b324cSopenharmony_ci  }
352370b324cSopenharmony_ci  if (offset < 0)
353370b324cSopenharmony_ci    return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
354370b324cSopenharmony_ci  _virtPos = (UInt64)offset;
355370b324cSopenharmony_ci  if (newPosition)
356370b324cSopenharmony_ci    *newPosition = _virtPos;
357370b324cSopenharmony_ci  return S_OK;
358370b324cSopenharmony_ci}
359370b324cSopenharmony_ci
360370b324cSopenharmony_ciZ7_COM7F_IMF(CTailOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
361370b324cSopenharmony_ci{
362370b324cSopenharmony_ci  UInt32 cur;
363370b324cSopenharmony_ci  HRESULT res = Stream->Write(data, size, &cur);
364370b324cSopenharmony_ci  if (processedSize)
365370b324cSopenharmony_ci    *processedSize = cur;
366370b324cSopenharmony_ci  _virtPos += cur;
367370b324cSopenharmony_ci  if (_virtSize < _virtPos)
368370b324cSopenharmony_ci    _virtSize = _virtPos;
369370b324cSopenharmony_ci  return res;
370370b324cSopenharmony_ci}
371370b324cSopenharmony_ci
372370b324cSopenharmony_ciZ7_COM7F_IMF(CTailOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
373370b324cSopenharmony_ci{
374370b324cSopenharmony_ci  switch (seekOrigin)
375370b324cSopenharmony_ci  {
376370b324cSopenharmony_ci    case STREAM_SEEK_SET: break;
377370b324cSopenharmony_ci    case STREAM_SEEK_CUR: offset += _virtPos; break;
378370b324cSopenharmony_ci    case STREAM_SEEK_END: offset += _virtSize; break;
379370b324cSopenharmony_ci    default: return STG_E_INVALIDFUNCTION;
380370b324cSopenharmony_ci  }
381370b324cSopenharmony_ci  if (offset < 0)
382370b324cSopenharmony_ci    return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
383370b324cSopenharmony_ci  _virtPos = (UInt64)offset;
384370b324cSopenharmony_ci  if (newPosition)
385370b324cSopenharmony_ci    *newPosition = _virtPos;
386370b324cSopenharmony_ci  return Stream->Seek((Int64)(Offset + _virtPos), STREAM_SEEK_SET, NULL);
387370b324cSopenharmony_ci}
388370b324cSopenharmony_ci
389370b324cSopenharmony_ciZ7_COM7F_IMF(CTailOutStream::SetSize(UInt64 newSize))
390370b324cSopenharmony_ci{
391370b324cSopenharmony_ci  _virtSize = newSize;
392370b324cSopenharmony_ci  return Stream->SetSize(Offset + newSize);
393370b324cSopenharmony_ci}
394