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