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