1 // IStream.h
2 
3 #ifndef __ISTREAM_H
4 #define __ISTREAM_H
5 
6 #include "../Common/MyTypes.h"
7 #include "../Common/MyUnknown.h"
8 
9 #include "IDecl.h"
10 
11 #define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x)
12 #define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
13 
14 STREAM_INTERFACE(ISequentialInStream, 0x01)
15 {
16   STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
17 
18   /*
19   The requirement for caller: (processedSize != NULL).
20   The callee can allow (processedSize == NULL) for compatibility reasons.
21 
22   if (size == 0), this function returns S_OK and (*processedSize) is set to 0.
23 
24   if (size != 0)
25   {
26     Partial read is allowed: (*processedSize <= avail_size && *processedSize <= size),
27       where (avail_size) is the size of remaining bytes in stream.
28     If (avail_size != 0), this function must read at least 1 byte: (*processedSize > 0).
29     You must call Read() in loop, if you need to read exact amount of data.
30   }
31 
32   If seek pointer before Read() call was changed to position past the end of stream:
33     if (seek_pointer >= stream_size), this function returns S_OK and (*processedSize) is set to 0.
34 
35   ERROR CASES:
36     If the function returns error code, then (*processedSize) is size of
37     data written to (data) buffer (it can be data before error or data with errors).
38     The recommended way for callee to work with reading errors:
39       1) write part of data before error to (data) buffer and return S_OK.
40       2) return error code for further calls of Read().
41   */
42 };
43 
44 STREAM_INTERFACE(ISequentialOutStream, 0x02)
45 {
46   STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
47 
48   /*
49   The requirement for caller: (processedSize != NULL).
50   The callee can allow (processedSize == NULL) for compatibility reasons.
51 
52   if (size != 0)
53   {
54     Partial write is allowed: (*processedSize <= size),
55     but this function must write at least 1 byte: (*processedSize > 0).
56     You must call Write() in loop, if you need to write exact amount of data.
57   }
58 
59   ERROR CASES:
60     If the function returns error code, then (*processedSize) is size of
61     data written from (data) buffer.
62   */
63 };
64 
65 #ifdef __HRESULT_FROM_WIN32
66 #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
67 #else
68 #define HRESULT_WIN32_ERROR_NEGATIVE_SEEK   HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK)
69 #endif
70 
71 /*  Seek() Function
72   If you seek before the beginning of the stream, Seek() function returns error code:
73       Recommended error code is __HRESULT_FROM_WIN32(ERROR_NEGATIVE_SEEK).
74       or STG_E_INVALIDFUNCTION
75 
76   It is allowed to seek past the end of the stream.
77 
78 
79   if Seek() returns error, then the value of *newPosition is undefined.
80 */
81 
82 STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
83 {
84   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
85 };
86 
87 STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
88 {
89   STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
90   STDMETHOD(SetSize)(UInt64 newSize) PURE;
91 };
92 
93 STREAM_INTERFACE(IStreamGetSize, 0x06)
94 {
95   STDMETHOD(GetSize)(UInt64 *size) PURE;
96 };
97 
98 STREAM_INTERFACE(IOutStreamFlush, 0x07)
99 {
100   STDMETHOD(Flush)() PURE;
101 };
102 
103 
104 STREAM_INTERFACE(IStreamGetProps, 0x08)
105 {
106   STDMETHOD(GetProps)(UInt64 *size, FILETIME *cTime, FILETIME *aTime, FILETIME *mTime, UInt32 *attrib) PURE;
107 };
108 
109 struct CStreamFileProps
110 {
111   UInt64 Size;
112   UInt64 VolID;
113   UInt64 FileID_Low;
114   UInt64 FileID_High;
115   UInt32 NumLinks;
116   UInt32 Attrib;
117   FILETIME CTime;
118   FILETIME ATime;
119   FILETIME MTime;
120 };
121 
122 STREAM_INTERFACE(IStreamGetProps2, 0x09)
123 {
124   STDMETHOD(GetProps2)(CStreamFileProps *props) PURE;
125 };
126 
127 #endif
128