1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5//
6
7#if !defined( __STREAMUTIL_H__ )
8#define __STREAMUTIL_H__
9
10namespace StreamUtil
11{
12
13// Write data to stream and advance the totalBytes counter
14//
15inline
16HRESULT WriteToStream( IStream * strm, void const * data, UINT32 sizeInBytes, UINT32 * totalBytes = NULL )
17{
18 HRESULT hr = strm->Write( data, sizeInBytes, NULL );
19 if ( SUCCEEDED( hr ) && totalBytes != NULL )
20 *totalBytes += sizeInBytes;
21 return hr;
22}
23
24
25// Write a POD to stream
26//
27template < typename T >
28HRESULT WritePODToStream( IStream * strm, T val, UINT32 * totalBytes )
29{
30 return WriteToStream( strm, & val, sizeof( val ), totalBytes );
31}
32
33
34// Write concrete data types to stream
35// Add additional overloads as needed
36//
37
38inline
39HRESULT WriteToStream( IStream * strm, int val, UINT32 * totalBytes = NULL )
40{
41 return WritePODToStream( strm, val, totalBytes );
42}
43
44
45inline
46HRESULT WriteToStream( IStream * strm, DWORD val, UINT32 * totalBytes = NULL )
47{
48 return WritePODToStream( strm, val, totalBytes );
49}
50
51
52inline
53HRESULT WriteToStream( IStream * strm, WORD val, UINT32 * totalBytes = NULL )
54{
55 return WritePODToStream( strm, val, totalBytes );
56}
57
58
59inline
60HRESULT WriteToStream( IStream * strm, BYTE val, UINT32 * totalBytes = NULL )
61{
62 return WritePODToStream( strm, val, totalBytes );
63}
64
65
66// Align to DWORD boundary
67//
68inline
69HRESULT AlignDWORD( IStream * strm, UINT32 * totalBytes )
70{
71 HRESULT hr = S_OK;
72
73 UINT32 aligned = *totalBytes + 3 & ~3;
74 if (aligned > *totalBytes)
75 { // The *totalBytes were not aligned to DWORD, we need to add padding
76 DWORD data = 0;
77 hr = WriteToStream( strm, & data, aligned - *totalBytes, totalBytes );
78 }
79 else if (aligned < *totalBytes)
80 { // We got an integer overflow in 'aligned' expression above
81 hr = COR_E_OVERFLOW;
82 }
83
84 return hr;
85}
86
87
88// Get stream position
89//
90inline
91HRESULT GetPos( IStream * strm, UINT32 * pos )
92{
93 LARGE_INTEGER temp = { {0} };
94 ULARGE_INTEGER ul_pos = { {0} };
95 HRESULT hr = strm->Seek( temp, STREAM_SEEK_CUR, & ul_pos );
96 * pos = ul_pos.u.LowPart;
97 return hr;
98}
99
100
101class NullStream : public IStream
102{
103public:
104 NullStream()
105 : m_pos( 0 )
106 {}
107
108 ULONG STDMETHODCALLTYPE AddRef()
109 {
110 _ASSERTE( false );
111 return 0;
112 }
113
114 ULONG STDMETHODCALLTYPE Release()
115 {
116 SUPPORTS_DAC_HOST_ONLY;
117 _ASSERTE( false );
118 return 0;
119 }
120
121 HRESULT STDMETHODCALLTYPE QueryInterface( REFIID, PVOID* )
122 {
123 _ASSERTE( false );
124 return E_NOTIMPL;
125 }
126
127 HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead)
128 {
129 _ASSERTE( false );
130 return E_NOTIMPL;
131 }
132
133 HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG *pcbWritten)
134 {
135 m_pos += cb;
136 if (pcbWritten != NULL)
137 {
138 *pcbWritten = cb;
139 }
140 return S_OK;
141 }
142
143 HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
144 {
145 if ( dwOrigin != STREAM_SEEK_CUR || dlibMove.QuadPart != 0 || plibNewPosition == NULL )
146 return E_NOTIMPL;
147
148 plibNewPosition->u.HighPart = 0;
149 plibNewPosition->u.LowPart = m_pos;
150 return S_OK;
151 }
152
153 HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize)
154 {
155 _ASSERTE( false );
156 return E_NOTIMPL;
157 }
158
159 HRESULT STDMETHODCALLTYPE CopyTo(
160 IStream *pstm,
161 ULARGE_INTEGER cb,
162 ULARGE_INTEGER *pcbRead,
163 ULARGE_INTEGER *pcbWritten)
164 {
165 _ASSERTE( false );
166 return E_NOTIMPL;
167 }
168
169 HRESULT STDMETHODCALLTYPE Commit(
170 DWORD grfCommitFlags)
171 {
172 _ASSERTE( false );
173 return E_NOTIMPL;
174 }
175
176 HRESULT STDMETHODCALLTYPE Revert()
177 {
178 _ASSERTE( false );
179 return E_NOTIMPL;
180 }
181
182 HRESULT STDMETHODCALLTYPE LockRegion(
183 ULARGE_INTEGER libOffset,
184 ULARGE_INTEGER cb,
185 DWORD dwLockType)
186 {
187 _ASSERTE( false );
188 return E_NOTIMPL;
189 }
190
191 HRESULT STDMETHODCALLTYPE UnlockRegion(
192 ULARGE_INTEGER libOffset,
193 ULARGE_INTEGER cb,
194 DWORD dwLockType)
195 {
196 _ASSERTE( false );
197 return E_NOTIMPL;
198 }
199
200 HRESULT STDMETHODCALLTYPE Stat(
201 STATSTG *pstatstg,
202 DWORD grfStatFlag)
203 {
204 _ASSERTE( false );
205 return E_NOTIMPL;
206 }
207
208 HRESULT STDMETHODCALLTYPE Clone(
209 IStream **ppstm)
210 {
211 _ASSERTE( false );
212 return E_NOTIMPL;
213 }
214
215private:
216 UINT32 m_pos;
217}; // class NullStream
218
219}; // namespace StreamUtil
220
221#endif
222