// IStream.h #ifndef ZIP7_INC_ISTREAM_H #define ZIP7_INC_ISTREAM_H #include "../Common/MyTypes.h" #include "../Common/MyWindows.h" #include "IDecl.h" Z7_PURE_INTERFACES_BEGIN #define Z7_IFACE_CONSTR_STREAM_SUB(i, base, n) \ Z7_DECL_IFACE_7ZIP_SUB(i, base, 3, n) \ { Z7_IFACE_COM7_PURE(i) }; #define Z7_IFACE_CONSTR_STREAM(i, n) \ Z7_IFACE_CONSTR_STREAM_SUB(i, IUnknown, n) /* ISequentialInStream::Read() The requirement for caller: (processedSize != NULL). The callee can allow (processedSize == NULL) for compatibility reasons. if (size == 0), this function returns S_OK and (*processedSize) is set to 0. if (size != 0) { Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size), where (avail_size) is the size of remaining bytes in stream. If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0). You must call Read() in loop, if you need to read exact amount of data. } If seek pointer before Read() call was changed to position past the end of stream: if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0. ERROR CASES: If the function returns error code, then (*processedSize) is size of data written to (data) buffer (it can be data before error or data with errors). The recommended way for callee to work with reading errors: 1) write part of data before error to (data) buffer and return S_OK. 2) return error code for further calls of Read(). */ #define Z7_IFACEM_ISequentialInStream(x) \ x(Read(void *data, UInt32 size, UInt32 *processedSize)) Z7_IFACE_CONSTR_STREAM(ISequentialInStream, 0x01) /* ISequentialOutStream::Write() The requirement for caller: (processedSize != NULL). The callee can allow (processedSize == NULL) for compatibility reasons. if (size != 0) { Partial write is allowed: (*processedSize <= size), but this function must write at least 1 byte: (*processedSize > 0). You must call Write() in loop, if you need to write exact amount of data. } ERROR CASES: If the function returns error code, then (*processedSize) is size of data written from (data) buffer. */ #define Z7_IFACEM_ISequentialOutStream(x) \ x(Write(const void *data, UInt32 size, UInt32 *processedSize)) Z7_IFACE_CONSTR_STREAM(ISequentialOutStream, 0x02) #ifdef _WIN32 #ifdef __HRESULT_FROM_WIN32 #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) #else #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK) #endif #else #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK MY_E_ERROR_NEGATIVE_SEEK #endif /* IInStream::Seek() / IOutStream::Seek() If you seek to position before the beginning of the stream, Seek() function returns error code: Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK). or STG_E_INVALIDFUNCTION It is allowed to seek past the end of the stream. if Seek() returns error, then the value of *newPosition is undefined. */ #define Z7_IFACEM_IInStream(x) \ x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) Z7_IFACE_CONSTR_STREAM_SUB(IInStream, ISequentialInStream, 0x03) #define Z7_IFACEM_IOutStream(x) \ x(Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)) \ x(SetSize(UInt64 newSize)) Z7_IFACE_CONSTR_STREAM_SUB(IOutStream, ISequentialOutStream, 0x04) #define Z7_IFACEM_IStreamGetSize(x) \ x(GetSize(UInt64 *size)) Z7_IFACE_CONSTR_STREAM(IStreamGetSize, 0x06) #define Z7_IFACEM_IOutStreamFinish(x) \ x(OutStreamFinish()) Z7_IFACE_CONSTR_STREAM(IOutStreamFinish, 0x07) #define Z7_IFACEM_IStreamGetProps(x) \ x(GetProps(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib)) Z7_IFACE_CONSTR_STREAM(IStreamGetProps, 0x08) struct CStreamFileProps { UInt64 Size; UInt64 VolID; UInt64 FileID_Low; UInt64 FileID_High; UInt32 NumLinks; UInt32 Attrib; FILETIME CTime; FILETIME ATime; FILETIME MTime; }; #define Z7_IFACEM_IStreamGetProps2(x) \ x(GetProps2(CStreamFileProps *props)) Z7_IFACE_CONSTR_STREAM(IStreamGetProps2, 0x09) #define Z7_IFACEM_IStreamGetProp(x) \ x(GetProperty(PROPID propID, PROPVARIANT *value)) \ x(ReloadProps()) Z7_IFACE_CONSTR_STREAM(IStreamGetProp, 0x0a) /* IStreamSetRestriction::SetRestriction(UInt64 begin, UInt64 end) It sets region of data in output stream that is restricted. For restricted region it's expected (or allowed) to change data with different calls of Write()/SetSize(). Another regions of output stream will be supposed as non-restricted: - The callee usually doesn't flush the data in restricted region. - The callee usually can flush data from non-restricted region. inputs: (begin > end) is not allowed, and returns E_FAIL; if (begin == end) { it means that there is no region restriction for flushing. The callee is allowed to flush already written data and is allowed to flush all data in future calls of ISequentialOutStream::Write(), but before next call of SetRestriction(). The pair of values (begin == 0 && end == 0) is recommended to remove all restrictions. } if (begin < end) { it means that callee must NOT to flush any data in region [begin, end). The caller is allowed to Seek() to that region and rewrite the data in that restriction region. if (end == (UInt64(Int64)-1) { there is no upper bound for restricted region. So non-restricted region will be [0, begin) in that case } Note: it's not expected that some already written region was marked as non-restricted by old call SetRestriction() and later the part of that region was marked as restricted with new call SetRestriction(). For example, for different calls with non-empty restricted regions: (begin_new >= begin_old) is expected : { SetRestriction(begin_old, ...) ... SetRestriction(begin_new, ...) } } returns: - if (begin > end) it return ERROR code (E_FAIL) - S_OK : if no errors. - Also the call of SetRestriction() can initiate the flushing of already written data. So it can return the result of that flushing. Note: IOutStream::SetSize() also can change the data. So it's not expected the call IOutStream::SetSize() to unrestricted already written region. */ #define Z7_IFACEM_IStreamSetRestriction(x) \ x(SetRestriction(UInt64 begin, UInt64 end)) \ Z7_IFACE_CONSTR_STREAM(IStreamSetRestriction, 0x10) Z7_PURE_INTERFACES_END #endif