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