1370b324cSopenharmony_ci// StreamUtils.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../Common/MyCom.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "StreamUtils.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_cistatic const UInt32 kBlockSize = ((UInt32)1 << 31);
10370b324cSopenharmony_ci
11370b324cSopenharmony_ci
12370b324cSopenharmony_ciHRESULT InStream_SeekToBegin(IInStream *stream) throw()
13370b324cSopenharmony_ci{
14370b324cSopenharmony_ci  return InStream_SeekSet(stream, 0);
15370b324cSopenharmony_ci}
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci
18370b324cSopenharmony_ciHRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &sizeRes) throw()
19370b324cSopenharmony_ci{
20370b324cSopenharmony_ci#ifdef _WIN32
21370b324cSopenharmony_ci  {
22370b324cSopenharmony_ci    Z7_DECL_CMyComPtr_QI_FROM(
23370b324cSopenharmony_ci        IStreamGetSize,
24370b324cSopenharmony_ci        streamGetSize, stream)
25370b324cSopenharmony_ci    if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK)
26370b324cSopenharmony_ci      return S_OK;
27370b324cSopenharmony_ci  }
28370b324cSopenharmony_ci#endif
29370b324cSopenharmony_ci  const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes);
30370b324cSopenharmony_ci  const HRESULT hres2 = InStream_SeekToBegin(stream);
31370b324cSopenharmony_ci  return hres != S_OK ? hres : hres2;
32370b324cSopenharmony_ci}
33370b324cSopenharmony_ci
34370b324cSopenharmony_ci
35370b324cSopenharmony_ciHRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw()
36370b324cSopenharmony_ci{
37370b324cSopenharmony_ci  RINOK(InStream_GetPos(stream, curPosRes))
38370b324cSopenharmony_ci#ifdef _WIN32
39370b324cSopenharmony_ci  {
40370b324cSopenharmony_ci    Z7_DECL_CMyComPtr_QI_FROM(
41370b324cSopenharmony_ci        IStreamGetSize,
42370b324cSopenharmony_ci        streamGetSize, stream)
43370b324cSopenharmony_ci    if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK)
44370b324cSopenharmony_ci      return S_OK;
45370b324cSopenharmony_ci  }
46370b324cSopenharmony_ci#endif
47370b324cSopenharmony_ci  const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes);
48370b324cSopenharmony_ci  const HRESULT hres2 = InStream_SeekSet(stream, curPosRes);
49370b324cSopenharmony_ci  return hres != S_OK ? hres : hres2;
50370b324cSopenharmony_ci}
51370b324cSopenharmony_ci
52370b324cSopenharmony_ci
53370b324cSopenharmony_ci
54370b324cSopenharmony_ciHRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw()
55370b324cSopenharmony_ci{
56370b324cSopenharmony_ci  size_t size = *processedSize;
57370b324cSopenharmony_ci  *processedSize = 0;
58370b324cSopenharmony_ci  while (size != 0)
59370b324cSopenharmony_ci  {
60370b324cSopenharmony_ci    UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;
61370b324cSopenharmony_ci    UInt32 processedSizeLoc;
62370b324cSopenharmony_ci    HRESULT res = stream->Read(data, curSize, &processedSizeLoc);
63370b324cSopenharmony_ci    *processedSize += processedSizeLoc;
64370b324cSopenharmony_ci    data = (void *)((Byte *)data + processedSizeLoc);
65370b324cSopenharmony_ci    size -= processedSizeLoc;
66370b324cSopenharmony_ci    RINOK(res)
67370b324cSopenharmony_ci    if (processedSizeLoc == 0)
68370b324cSopenharmony_ci      return S_OK;
69370b324cSopenharmony_ci  }
70370b324cSopenharmony_ci  return S_OK;
71370b324cSopenharmony_ci}
72370b324cSopenharmony_ci
73370b324cSopenharmony_ciHRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw()
74370b324cSopenharmony_ci{
75370b324cSopenharmony_ci  size_t processedSize = size;
76370b324cSopenharmony_ci  RINOK(ReadStream(stream, data, &processedSize))
77370b324cSopenharmony_ci  return (size == processedSize) ? S_OK : S_FALSE;
78370b324cSopenharmony_ci}
79370b324cSopenharmony_ci
80370b324cSopenharmony_ciHRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw()
81370b324cSopenharmony_ci{
82370b324cSopenharmony_ci  size_t processedSize = size;
83370b324cSopenharmony_ci  RINOK(ReadStream(stream, data, &processedSize))
84370b324cSopenharmony_ci  return (size == processedSize) ? S_OK : E_FAIL;
85370b324cSopenharmony_ci}
86370b324cSopenharmony_ci
87370b324cSopenharmony_ciHRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw()
88370b324cSopenharmony_ci{
89370b324cSopenharmony_ci  while (size != 0)
90370b324cSopenharmony_ci  {
91370b324cSopenharmony_ci    UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;
92370b324cSopenharmony_ci    UInt32 processedSizeLoc;
93370b324cSopenharmony_ci    HRESULT res = stream->Write(data, curSize, &processedSizeLoc);
94370b324cSopenharmony_ci    data = (const void *)((const Byte *)data + processedSizeLoc);
95370b324cSopenharmony_ci    size -= processedSizeLoc;
96370b324cSopenharmony_ci    RINOK(res)
97370b324cSopenharmony_ci    if (processedSizeLoc == 0)
98370b324cSopenharmony_ci      return E_FAIL;
99370b324cSopenharmony_ci  }
100370b324cSopenharmony_ci  return S_OK;
101370b324cSopenharmony_ci}
102