xref: /third_party/lzma/CPP/7zip/IStream.h (revision 370b324c)
1370b324cSopenharmony_ci// IStream.h
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#ifndef ZIP7_INC_ISTREAM_H
4370b324cSopenharmony_ci#define ZIP7_INC_ISTREAM_H
5370b324cSopenharmony_ci
6370b324cSopenharmony_ci#include "../Common/MyTypes.h"
7370b324cSopenharmony_ci#include "../Common/MyWindows.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#include "IDecl.h"
10370b324cSopenharmony_ci
11370b324cSopenharmony_ciZ7_PURE_INTERFACES_BEGIN
12370b324cSopenharmony_ci
13370b324cSopenharmony_ci#define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \
14370b324cSopenharmony_ci  Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \
15370b324cSopenharmony_ci  { Z7_IFACE_COM7_PURE(i) };
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci#define Z7_IFACE_CONSTR_STREAM(i, n) \
18370b324cSopenharmony_ci        Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n)
19370b324cSopenharmony_ci
20370b324cSopenharmony_ci
21370b324cSopenharmony_ci/*
22370b324cSopenharmony_ciISequentialInStream::Read()
23370b324cSopenharmony_ci  The requirement for caller: (processedSize != NULL).
24370b324cSopenharmony_ci  The callee can allow (processedSize == NULL) for compatibility reasons.
25370b324cSopenharmony_ci
26370b324cSopenharmony_ci  if (size == 0), this function returns S_OK and (*processedSize) is set to 0.
27370b324cSopenharmony_ci
28370b324cSopenharmony_ci  if (size != 0)
29370b324cSopenharmony_ci  {
30370b324cSopenharmony_ci    Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size),
31370b324cSopenharmony_ci      where (avail_size) is the size of remaining bytes in stream.
32370b324cSopenharmony_ci    If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0).
33370b324cSopenharmony_ci    You must call Read() in loop, if you need to read exact amount of data.
34370b324cSopenharmony_ci  }
35370b324cSopenharmony_ci
36370b324cSopenharmony_ci  If seek pointer before Read() call was changed to position past the end of stream:
37370b324cSopenharmony_ci    if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0.
38370b324cSopenharmony_ci
39370b324cSopenharmony_ci  ERROR CASES:
40370b324cSopenharmony_ci    If the function returns error code, then (*processedSize) is size of
41370b324cSopenharmony_ci    data written to (data) buffer (it can be data before error or data with errors).
42370b324cSopenharmony_ci    The recommended way for callee to work with reading errors:
43370b324cSopenharmony_ci      1) write part of data before error to (data) buffer and return S_OK.
44370b324cSopenharmony_ci      2) return error code for further calls of Read().
45370b324cSopenharmony_ci*/
46370b324cSopenharmony_ci#define Z7_IFACEM_ISequentialInStream(x) \
47370b324cSopenharmony_ci  x(Read(void *data, UInt32 size, UInt32 *processedSize))
48370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01)
49370b324cSopenharmony_ci
50370b324cSopenharmony_ci
51370b324cSopenharmony_ci/*
52370b324cSopenharmony_ciISequentialOutStream::Write()
53370b324cSopenharmony_ci  The requirement for caller: (processedSize != NULL).
54370b324cSopenharmony_ci  The callee can allow (processedSize == NULL) for compatibility reasons.
55370b324cSopenharmony_ci
56370b324cSopenharmony_ci  if (size != 0)
57370b324cSopenharmony_ci  {
58370b324cSopenharmony_ci    Partial write is allowed: (*processedSize <= size),
59370b324cSopenharmony_ci    but this function must write at least 1 byte: (*processedSize > 0).
60370b324cSopenharmony_ci    You must call Write() in loop, if you need to write exact amount of data.
61370b324cSopenharmony_ci  }
62370b324cSopenharmony_ci
63370b324cSopenharmony_ci  ERROR CASES:
64370b324cSopenharmony_ci    If the function returns error code, then (*processedSize) is size of
65370b324cSopenharmony_ci    data written from (data) buffer.
66370b324cSopenharmony_ci*/
67370b324cSopenharmony_ci#define Z7_IFACEM_ISequentialOutStream(x) \
68370b324cSopenharmony_ci  x(Write(const void *data, UInt32 size, UInt32 *processedSize))
69370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02)
70370b324cSopenharmony_ci
71370b324cSopenharmony_ci
72370b324cSopenharmony_ci#ifdef _WIN32
73370b324cSopenharmony_ci
74370b324cSopenharmony_ci#ifdef __HRESULT_FROM_WIN32
75370b324cSopenharmony_ci#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
76370b324cSopenharmony_ci#else
77370b324cSopenharmony_ci#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK   HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
78370b324cSopenharmony_ci#endif
79370b324cSopenharmony_ci
80370b324cSopenharmony_ci#else
81370b324cSopenharmony_ci
82370b324cSopenharmony_ci#define HRESULT_WIN32_ERROR_NEGATIVE_SEEK   MY_E_ERROR_NEGATIVE_SEEK
83370b324cSopenharmony_ci
84370b324cSopenharmony_ci#endif
85370b324cSopenharmony_ci
86370b324cSopenharmony_ci
87370b324cSopenharmony_ci/*
88370b324cSopenharmony_ciIInStream::Seek() / IOutStream::Seek()
89370b324cSopenharmony_ci  If you seek to position before the beginning of the stream,
90370b324cSopenharmony_ci  Seek() function returns error code:
91370b324cSopenharmony_ci      Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK).
92370b324cSopenharmony_ci      or STG_E_INVALIDFUNCTION
93370b324cSopenharmony_ci  It is allowed to seek past the end of the stream.
94370b324cSopenharmony_ci  if Seek() returns error, then the value of *newPosition is undefined.
95370b324cSopenharmony_ci*/
96370b324cSopenharmony_ci
97370b324cSopenharmony_ci#define Z7_IFACEM_IInStream(x) \
98370b324cSopenharmony_ci  x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
99370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03)
100370b324cSopenharmony_ci
101370b324cSopenharmony_ci#define Z7_IFACEM_IOutStream(x) \
102370b324cSopenharmony_ci  x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \
103370b324cSopenharmony_ci  x(SetSize(UInt64 newSize))
104370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04)
105370b324cSopenharmony_ci
106370b324cSopenharmony_ci#define Z7_IFACEM_IStreamGetSize(x) \
107370b324cSopenharmony_ci  x(GetSize(UInt64 *size))
108370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06)
109370b324cSopenharmony_ci
110370b324cSopenharmony_ci#define Z7_IFACEM_IOutStreamFinish(x) \
111370b324cSopenharmony_ci  x(OutStreamFinish())
112370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07)
113370b324cSopenharmony_ci
114370b324cSopenharmony_ci#define Z7_IFACEM_IStreamGetProps(x) \
115370b324cSopenharmony_ci  x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
116370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08)
117370b324cSopenharmony_ci
118370b324cSopenharmony_ci
119370b324cSopenharmony_cistruct CStreamFileProps
120370b324cSopenharmony_ci{
121370b324cSopenharmony_ci  UInt64 Size;
122370b324cSopenharmony_ci  UInt64 VolID;
123370b324cSopenharmony_ci  UInt64 FileID_Low;
124370b324cSopenharmony_ci  UInt64 FileID_High;
125370b324cSopenharmony_ci  UInt32 NumLinks;
126370b324cSopenharmony_ci  UInt32 Attrib;
127370b324cSopenharmony_ci  FILETIME CTime;
128370b324cSopenharmony_ci  FILETIME ATime;
129370b324cSopenharmony_ci  FILETIME MTime;
130370b324cSopenharmony_ci};
131370b324cSopenharmony_ci
132370b324cSopenharmony_ci
133370b324cSopenharmony_ci#define Z7_IFACEM_IStreamGetProps2(x) \
134370b324cSopenharmony_ci  x(GetProps2(CStreamFileProps *props))
135370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09)
136370b324cSopenharmony_ci
137370b324cSopenharmony_ci#define Z7_IFACEM_IStreamGetProp(x) \
138370b324cSopenharmony_ci  x(GetProperty(PROPID propID, PROPVARIANT *value)) \
139370b324cSopenharmony_ci  x(ReloadProps())
140370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a)
141370b324cSopenharmony_ci
142370b324cSopenharmony_ci
143370b324cSopenharmony_ci/*
144370b324cSopenharmony_ciIStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end)
145370b324cSopenharmony_ci
146370b324cSopenharmony_ci  It sets region of data in output stream that is restricted.
147370b324cSopenharmony_ci  For restricted region it's expected (or allowed)
148370b324cSopenharmony_ci  to change data with different calls of Write()/SetSize().
149370b324cSopenharmony_ci  Another regions of output stream will be supposed as non-restricted:
150370b324cSopenharmony_ci    - The callee usually doesn't flush the data in restricted region.
151370b324cSopenharmony_ci    - The callee usually can flush data from non-restricted region.
152370b324cSopenharmony_ci
153370b324cSopenharmony_ciinputs:
154370b324cSopenharmony_ci
155370b324cSopenharmony_ci  (begin > end) is not allowed, and returns E_FAIL;
156370b324cSopenharmony_ci
157370b324cSopenharmony_ci  if (begin == end)
158370b324cSopenharmony_ci  {
159370b324cSopenharmony_ci    it means that there is no region restriction for flushing.
160370b324cSopenharmony_ci    The callee is allowed to flush already written data and
161370b324cSopenharmony_ci    is allowed to flush all data in future calls of
162370b324cSopenharmony_ci    ISequentialOutStream::Write(), but before next call of SetRestriction().
163370b324cSopenharmony_ci    The pair of values (begin == 0 && end == 0) is recommended to
164370b324cSopenharmony_ci    remove all restrictions.
165370b324cSopenharmony_ci  }
166370b324cSopenharmony_ci
167370b324cSopenharmony_ci  if (begin < end)
168370b324cSopenharmony_ci  {
169370b324cSopenharmony_ci    it means that callee must NOT to flush any data in region [begin, end).
170370b324cSopenharmony_ci    The caller is allowed to Seek() to that region and rewrite the
171370b324cSopenharmony_ci    data in that restriction region.
172370b324cSopenharmony_ci    if (end == (UInt64(Int64)-1)
173370b324cSopenharmony_ci    {
174370b324cSopenharmony_ci      there is no upper bound for restricted region.
175370b324cSopenharmony_ci      So non-restricted region will be [0, begin) in that case
176370b324cSopenharmony_ci    }
177370b324cSopenharmony_ci
178370b324cSopenharmony_ci    Note: it's not expected that some already written region was marked as
179370b324cSopenharmony_ci    non-restricted by old call SetRestriction() and later the part of
180370b324cSopenharmony_ci    that region was marked as restricted with new call SetRestriction().
181370b324cSopenharmony_ci    For example, for different calls with non-empty restricted regions:
182370b324cSopenharmony_ci     (begin_new >= begin_old) is expected :
183370b324cSopenharmony_ci     {
184370b324cSopenharmony_ci       SetRestriction(begin_old, ...)
185370b324cSopenharmony_ci       ...
186370b324cSopenharmony_ci       SetRestriction(begin_new, ...)
187370b324cSopenharmony_ci     }
188370b324cSopenharmony_ci  }
189370b324cSopenharmony_ci
190370b324cSopenharmony_ci returns:
191370b324cSopenharmony_ci  - if (begin > end) it return ERROR code (E_FAIL)
192370b324cSopenharmony_ci  - S_OK : if no errors.
193370b324cSopenharmony_ci  - Also the call of SetRestriction() can initiate the flushing of already written data.
194370b324cSopenharmony_ci    So it can return the result of that flushing.
195370b324cSopenharmony_ci
196370b324cSopenharmony_ci Note: IOutStream::SetSize() also can change the data.
197370b324cSopenharmony_ci    So it's not expected the call
198370b324cSopenharmony_ci    IOutStream::SetSize() to unrestricted already written region.
199370b324cSopenharmony_ci*/
200370b324cSopenharmony_ci
201370b324cSopenharmony_ci#define Z7_IFACEM_IStreamSetRestriction(x) \
202370b324cSopenharmony_ci  x(SetRestriction(UInt64 begin, UInt64 end)) \
203370b324cSopenharmony_ci
204370b324cSopenharmony_ciZ7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10)
205370b324cSopenharmony_ci
206370b324cSopenharmony_ciZ7_PURE_INTERFACES_END
207370b324cSopenharmony_ci#endif
208