xref: /aosp_15_r20/external/lzma/CPP/7zip/IStream.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // IStream.h
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_ISTREAM_H
4*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_ISTREAM_H
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "../Common/Common0.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../Common/MyTypes.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../Common/MyWindows.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "IDecl.h"
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker Z7_PURE_INTERFACES_BEGIN
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \
15*f6dc9357SAndroid Build Coastguard Worker   Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \
16*f6dc9357SAndroid Build Coastguard Worker   { Z7_IFACE_COM7_PURE(i) };
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACE_CONSTR_STREAM(i, n) \
19*f6dc9357SAndroid Build Coastguard Worker         Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n)
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker /*
23*f6dc9357SAndroid Build Coastguard Worker ISequentialInStream::Read()
24*f6dc9357SAndroid Build Coastguard Worker   The requirement for caller: (processedSize != NULL).
25*f6dc9357SAndroid Build Coastguard Worker   The callee can allow (processedSize == NULL) for compatibility reasons.
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker   if (size == 0), this function returns S_OK and (*processedSize) is set to 0.
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker   if (size != 0)
30*f6dc9357SAndroid Build Coastguard Worker   {
31*f6dc9357SAndroid Build Coastguard Worker     Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size),
32*f6dc9357SAndroid Build Coastguard Worker       where (avail_size) is the size of remaining bytes in stream.
33*f6dc9357SAndroid Build Coastguard Worker     If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0).
34*f6dc9357SAndroid Build Coastguard Worker     You must call Read() in loop, if you need to read exact amount of data.
35*f6dc9357SAndroid Build Coastguard Worker   }
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker   If seek pointer before Read() call was changed to position past the end of stream:
38*f6dc9357SAndroid Build Coastguard Worker     if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0.
39*f6dc9357SAndroid Build Coastguard Worker 
40*f6dc9357SAndroid Build Coastguard Worker   ERROR CASES:
41*f6dc9357SAndroid Build Coastguard Worker     If the function returns error code, then (*processedSize) is size of
42*f6dc9357SAndroid Build Coastguard Worker     data written to (data) buffer (it can be data before error or data with errors).
43*f6dc9357SAndroid Build Coastguard Worker     The recommended way for callee to work with reading errors:
44*f6dc9357SAndroid Build Coastguard Worker       1) write part of data before error to (data) buffer and return S_OK.
45*f6dc9357SAndroid Build Coastguard Worker       2) return error code for further calls of Read().
46*f6dc9357SAndroid Build Coastguard Worker */
47*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_ISequentialInStream(x) \
48*f6dc9357SAndroid Build Coastguard Worker   x(Read(void *data, UInt32 size, UInt32 *processedSize))
49*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01)
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker 
52*f6dc9357SAndroid Build Coastguard Worker /*
53*f6dc9357SAndroid Build Coastguard Worker ISequentialOutStream::Write()
54*f6dc9357SAndroid Build Coastguard Worker   The requirement for caller: (processedSize != NULL).
55*f6dc9357SAndroid Build Coastguard Worker   The callee can allow (processedSize == NULL) for compatibility reasons.
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker   if (size != 0)
58*f6dc9357SAndroid Build Coastguard Worker   {
59*f6dc9357SAndroid Build Coastguard Worker     Partial write is allowed: (*processedSize <= size),
60*f6dc9357SAndroid Build Coastguard Worker     but this function must write at least 1 byte: (*processedSize > 0).
61*f6dc9357SAndroid Build Coastguard Worker     You must call Write() in loop, if you need to write exact amount of data.
62*f6dc9357SAndroid Build Coastguard Worker   }
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker   ERROR CASES:
65*f6dc9357SAndroid Build Coastguard Worker     If the function returns error code, then (*processedSize) is size of
66*f6dc9357SAndroid Build Coastguard Worker     data written from (data) buffer.
67*f6dc9357SAndroid Build Coastguard Worker */
68*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_ISequentialOutStream(x) \
69*f6dc9357SAndroid Build Coastguard Worker   x(Write(const void *data, UInt32 size, UInt32 *processedSize))
70*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02)
71*f6dc9357SAndroid Build Coastguard Worker 
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker #ifdef __HRESULT_FROM_WIN32
76*f6dc9357SAndroid Build Coastguard Worker #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
77*f6dc9357SAndroid Build Coastguard Worker #else
78*f6dc9357SAndroid Build Coastguard Worker #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK   HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
79*f6dc9357SAndroid Build Coastguard Worker #endif
80*f6dc9357SAndroid Build Coastguard Worker 
81*f6dc9357SAndroid Build Coastguard Worker #else
82*f6dc9357SAndroid Build Coastguard Worker 
83*f6dc9357SAndroid Build Coastguard Worker #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK   MY_E_ERROR_NEGATIVE_SEEK
84*f6dc9357SAndroid Build Coastguard Worker 
85*f6dc9357SAndroid Build Coastguard Worker #endif
86*f6dc9357SAndroid Build Coastguard Worker 
87*f6dc9357SAndroid Build Coastguard Worker 
88*f6dc9357SAndroid Build Coastguard Worker /*
89*f6dc9357SAndroid Build Coastguard Worker IInStream::Seek() / IOutStream::Seek()
90*f6dc9357SAndroid Build Coastguard Worker   If you seek to position before the beginning of the stream,
91*f6dc9357SAndroid Build Coastguard Worker   Seek() function returns error code:
92*f6dc9357SAndroid Build Coastguard Worker       Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK).
93*f6dc9357SAndroid Build Coastguard Worker       or STG_E_INVALIDFUNCTION
94*f6dc9357SAndroid Build Coastguard Worker   It is allowed to seek past the end of the stream.
95*f6dc9357SAndroid Build Coastguard Worker   if Seek() returns error, then the value of *newPosition is undefined.
96*f6dc9357SAndroid Build Coastguard Worker */
97*f6dc9357SAndroid Build Coastguard Worker 
98*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IInStream(x) \
99*f6dc9357SAndroid Build Coastguard Worker   x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
100*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03)
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IOutStream(x) \
103*f6dc9357SAndroid Build Coastguard Worker   x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \
104*f6dc9357SAndroid Build Coastguard Worker   x(SetSize(UInt64 newSize))
105*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04)
106*f6dc9357SAndroid Build Coastguard Worker 
107*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IStreamGetSize(x) \
108*f6dc9357SAndroid Build Coastguard Worker   x(GetSize(UInt64 *size))
109*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06)
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IOutStreamFinish(x) \
112*f6dc9357SAndroid Build Coastguard Worker   x(OutStreamFinish())
113*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07)
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IStreamGetProps(x) \
116*f6dc9357SAndroid Build Coastguard Worker   x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib))
117*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08)
118*f6dc9357SAndroid Build Coastguard Worker 
119*f6dc9357SAndroid Build Coastguard Worker 
120*f6dc9357SAndroid Build Coastguard Worker struct CStreamFileProps
121*f6dc9357SAndroid Build Coastguard Worker {
122*f6dc9357SAndroid Build Coastguard Worker   UInt64 Size;
123*f6dc9357SAndroid Build Coastguard Worker   UInt64 VolID;
124*f6dc9357SAndroid Build Coastguard Worker   UInt64 FileID_Low;
125*f6dc9357SAndroid Build Coastguard Worker   UInt64 FileID_High;
126*f6dc9357SAndroid Build Coastguard Worker   UInt32 NumLinks;
127*f6dc9357SAndroid Build Coastguard Worker   UInt32 Attrib;
128*f6dc9357SAndroid Build Coastguard Worker   FILETIME CTime;
129*f6dc9357SAndroid Build Coastguard Worker   FILETIME ATime;
130*f6dc9357SAndroid Build Coastguard Worker   FILETIME MTime;
131*f6dc9357SAndroid Build Coastguard Worker };
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IStreamGetProps2(x) \
135*f6dc9357SAndroid Build Coastguard Worker   x(GetProps2(CStreamFileProps *props))
136*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09)
137*f6dc9357SAndroid Build Coastguard Worker 
138*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IStreamGetProp(x) \
139*f6dc9357SAndroid Build Coastguard Worker   x(GetProperty(PROPID propID, PROPVARIANT *value)) \
140*f6dc9357SAndroid Build Coastguard Worker   x(ReloadProps())
141*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a)
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker 
144*f6dc9357SAndroid Build Coastguard Worker /*
145*f6dc9357SAndroid Build Coastguard Worker IStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end)
146*f6dc9357SAndroid Build Coastguard Worker 
147*f6dc9357SAndroid Build Coastguard Worker   It sets region of data in output stream that is restricted.
148*f6dc9357SAndroid Build Coastguard Worker   For restricted region it's expected (or allowed)
149*f6dc9357SAndroid Build Coastguard Worker   that the caller can write to same region with different calls of Write()/SetSize().
150*f6dc9357SAndroid Build Coastguard Worker   Another regions of output stream will be supposed as non-restricted:
151*f6dc9357SAndroid Build Coastguard Worker     - The callee usually doesn't flush the data in restricted region.
152*f6dc9357SAndroid Build Coastguard Worker     - The callee usually can flush data from non-restricted region after writing.
153*f6dc9357SAndroid Build Coastguard Worker 
154*f6dc9357SAndroid Build Coastguard Worker Actual restiction rules depend also from current stream position.
155*f6dc9357SAndroid Build Coastguard Worker It's recommended to call SetRestriction() just before the Write() call.
156*f6dc9357SAndroid Build Coastguard Worker So the callee can optimize writing and flushing, if that Write()
157*f6dc9357SAndroid Build Coastguard Worker operation is not restricted.
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker Note: Each new call of SetRestriction() sets new restictions,
160*f6dc9357SAndroid Build Coastguard Worker so previous restrction calls has no effect anymore.
161*f6dc9357SAndroid Build Coastguard Worker 
162*f6dc9357SAndroid Build Coastguard Worker inputs:
163*f6dc9357SAndroid Build Coastguard Worker 
164*f6dc9357SAndroid Build Coastguard Worker   (begin > end) is not allowed, and returns E_FAIL;
165*f6dc9357SAndroid Build Coastguard Worker 
166*f6dc9357SAndroid Build Coastguard Worker   if (begin == end)
167*f6dc9357SAndroid Build Coastguard Worker   {
168*f6dc9357SAndroid Build Coastguard Worker     No restriction.
169*f6dc9357SAndroid Build Coastguard Worker     The caller will call Write() in sequential order.
170*f6dc9357SAndroid Build Coastguard Worker     After SetRestriction(begin, begin), but before next call of SetRestriction()
171*f6dc9357SAndroid Build Coastguard Worker     {
172*f6dc9357SAndroid Build Coastguard Worker       Additional condition:
173*f6dc9357SAndroid Build Coastguard Worker         it's expected that current stream seek position is equal to stream size.
174*f6dc9357SAndroid Build Coastguard Worker       The callee can make final flushing for any data before current stream seek position.
175*f6dc9357SAndroid Build Coastguard Worker       For each Write(size) call:
176*f6dc9357SAndroid Build Coastguard Worker         The callee can make final flushing for that new written data.
177*f6dc9357SAndroid Build Coastguard Worker     }
178*f6dc9357SAndroid Build Coastguard Worker     The pair of values (begin == 0 && end == 0) is recommended to remove write restriction.
179*f6dc9357SAndroid Build Coastguard Worker   }
180*f6dc9357SAndroid Build Coastguard Worker 
181*f6dc9357SAndroid Build Coastguard Worker   if (begin < end)
182*f6dc9357SAndroid Build Coastguard Worker   {
183*f6dc9357SAndroid Build Coastguard Worker     it means that callee must NOT flush any data in region [begin, end).
184*f6dc9357SAndroid Build Coastguard Worker     The caller is allowed to Seek() to that region and rewrite the
185*f6dc9357SAndroid Build Coastguard Worker     data in that restriction region.
186*f6dc9357SAndroid Build Coastguard Worker     if (end == (UInt64)(Int64)-1)
187*f6dc9357SAndroid Build Coastguard Worker     {
188*f6dc9357SAndroid Build Coastguard Worker       there is no upper bound for restricted region.
189*f6dc9357SAndroid Build Coastguard Worker       So non-restricted region will be [0, begin) in that case
190*f6dc9357SAndroid Build Coastguard Worker     }
191*f6dc9357SAndroid Build Coastguard Worker   }
192*f6dc9357SAndroid Build Coastguard Worker 
193*f6dc9357SAndroid Build Coastguard Worker  returns:
194*f6dc9357SAndroid Build Coastguard Worker   - if (begin > end) it return ERROR code (E_FAIL)
195*f6dc9357SAndroid Build Coastguard Worker   - S_OK : if no errors.
196*f6dc9357SAndroid Build Coastguard Worker   - Also the call of SetRestriction() can initiate the flushing of already written data.
197*f6dc9357SAndroid Build Coastguard Worker     So it can return the result of that flushing.
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker  Note: IOutStream::SetSize() also can change the data.
200*f6dc9357SAndroid Build Coastguard Worker     So it's not expected the call
201*f6dc9357SAndroid Build Coastguard Worker     IOutStream::SetSize() to region that was written before as unrestricted.
202*f6dc9357SAndroid Build Coastguard Worker */
203*f6dc9357SAndroid Build Coastguard Worker 
204*f6dc9357SAndroid Build Coastguard Worker #define Z7_IFACEM_IStreamSetRestriction(x) \
205*f6dc9357SAndroid Build Coastguard Worker   x(SetRestriction(UInt64 begin, UInt64 end)) \
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker Z7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10)
208*f6dc9357SAndroid Build Coastguard Worker 
209*f6dc9357SAndroid Build Coastguard Worker Z7_PURE_INTERFACES_END
210*f6dc9357SAndroid Build Coastguard Worker #endif
211