1// StreamUtils.cpp
2
3#include "StdAfx.h"
4
5#include "../../Common/MyCom.h"
6
7#include "StreamUtils.h"
8
9static const UInt32 kBlockSize = ((UInt32)1 << 31);
10
11
12HRESULT InStream_SeekToBegin(IInStream *stream) throw()
13{
14  return InStream_SeekSet(stream, 0);
15}
16
17
18HRESULT InStream_AtBegin_GetSize(IInStream *stream, UInt64 &sizeRes) throw()
19{
20#ifdef _WIN32
21  {
22    Z7_DECL_CMyComPtr_QI_FROM(
23        IStreamGetSize,
24        streamGetSize, stream)
25    if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK)
26      return S_OK;
27  }
28#endif
29  const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes);
30  const HRESULT hres2 = InStream_SeekToBegin(stream);
31  return hres != S_OK ? hres : hres2;
32}
33
34
35HRESULT InStream_GetPos_GetSize(IInStream *stream, UInt64 &curPosRes, UInt64 &sizeRes) throw()
36{
37  RINOK(InStream_GetPos(stream, curPosRes))
38#ifdef _WIN32
39  {
40    Z7_DECL_CMyComPtr_QI_FROM(
41        IStreamGetSize,
42        streamGetSize, stream)
43    if (streamGetSize && streamGetSize->GetSize(&sizeRes) == S_OK)
44      return S_OK;
45  }
46#endif
47  const HRESULT hres = InStream_GetSize_SeekToEnd(stream, sizeRes);
48  const HRESULT hres2 = InStream_SeekSet(stream, curPosRes);
49  return hres != S_OK ? hres : hres2;
50}
51
52
53
54HRESULT ReadStream(ISequentialInStream *stream, void *data, size_t *processedSize) throw()
55{
56  size_t size = *processedSize;
57  *processedSize = 0;
58  while (size != 0)
59  {
60    UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;
61    UInt32 processedSizeLoc;
62    HRESULT res = stream->Read(data, curSize, &processedSizeLoc);
63    *processedSize += processedSizeLoc;
64    data = (void *)((Byte *)data + processedSizeLoc);
65    size -= processedSizeLoc;
66    RINOK(res)
67    if (processedSizeLoc == 0)
68      return S_OK;
69  }
70  return S_OK;
71}
72
73HRESULT ReadStream_FALSE(ISequentialInStream *stream, void *data, size_t size) throw()
74{
75  size_t processedSize = size;
76  RINOK(ReadStream(stream, data, &processedSize))
77  return (size == processedSize) ? S_OK : S_FALSE;
78}
79
80HRESULT ReadStream_FAIL(ISequentialInStream *stream, void *data, size_t size) throw()
81{
82  size_t processedSize = size;
83  RINOK(ReadStream(stream, data, &processedSize))
84  return (size == processedSize) ? S_OK : E_FAIL;
85}
86
87HRESULT WriteStream(ISequentialOutStream *stream, const void *data, size_t size) throw()
88{
89  while (size != 0)
90  {
91    UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;
92    UInt32 processedSizeLoc;
93    HRESULT res = stream->Write(data, curSize, &processedSizeLoc);
94    data = (const void *)((const Byte *)data + processedSizeLoc);
95    size -= processedSizeLoc;
96    RINOK(res)
97    if (processedSizeLoc == 0)
98      return E_FAIL;
99  }
100  return S_OK;
101}
102