1 // CWrappers.c
2
3 #include "StdAfx.h"
4
5 #include "../../../C/Alloc.h"
6
7 #include "CWrappers.h"
8
9 #include "StreamUtils.h"
10
HRESULT_To_SRes(HRESULT res, SRes defaultRes)11 SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes) throw()
12 {
13 switch (res)
14 {
15 case S_OK: return SZ_OK;
16 case E_OUTOFMEMORY: return SZ_ERROR_MEM;
17 case E_INVALIDARG: return SZ_ERROR_PARAM;
18 case E_ABORT: return SZ_ERROR_PROGRESS;
19 case S_FALSE: return SZ_ERROR_DATA;
20 case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
21 }
22 return defaultRes;
23 }
24
25
SResToHRESULT(SRes res)26 HRESULT SResToHRESULT(SRes res) throw()
27 {
28 switch (res)
29 {
30 case SZ_OK: return S_OK;
31
32 case SZ_ERROR_DATA:
33 case SZ_ERROR_CRC:
34 case SZ_ERROR_INPUT_EOF:
35 return S_FALSE;
36
37 case SZ_ERROR_MEM: return E_OUTOFMEMORY;
38 case SZ_ERROR_PARAM: return E_INVALIDARG;
39 case SZ_ERROR_PROGRESS: return E_ABORT;
40 case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
41 // case SZ_ERROR_OUTPUT_EOF:
42 // case SZ_ERROR_READ:
43 // case SZ_ERROR_WRITE:
44 // case SZ_ERROR_THREAD:
45 // case SZ_ERROR_ARCHIVE:
46 // case SZ_ERROR_NO_ARCHIVE:
47 // return E_FAIL;
48 }
49 if (res < 0)
50 return res;
51 return E_FAIL;
52 }
53
54
55 #define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1)
56
57 #define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
58
59
CompressProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize)60 static SRes CompressProgress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) throw()
61 {
62 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CCompressProgressWrap)
63 p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
64 return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS);
65 }
66
Init(ICompressProgressInfo *progress)67 void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw()
68 {
69 vt.Progress = CompressProgress;
70 Progress = progress;
71 Res = SZ_OK;
72 }
73
74 static const UInt32 kStreamStepSize = (UInt32)1 << 31;
75
MyRead(ISeqInStreamPtr pp, void *data, size_t *size)76 static SRes MyRead(ISeqInStreamPtr pp, void *data, size_t *size) throw()
77 {
78 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInStreamWrap)
79 UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
80 p->Res = (p->Stream->Read(data, curSize, &curSize));
81 *size = curSize;
82 p->Processed += curSize;
83 if (p->Res == S_OK)
84 return SZ_OK;
85 return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
86 }
87
MyWrite(ISeqOutStreamPtr pp, const void *data, size_t size)88 static size_t MyWrite(ISeqOutStreamPtr pp, const void *data, size_t size) throw()
89 {
90 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqOutStreamWrap)
91 if (p->Stream)
92 {
93 p->Res = WriteStream(p->Stream, data, size);
94 if (p->Res != 0)
95 return 0;
96 }
97 else
98 p->Res = S_OK;
99 p->Processed += size;
100 return size;
101 }
102
103
Init(ISequentialInStream *stream)104 void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw()
105 {
106 vt.Read = MyRead;
107 Stream = stream;
108 Processed = 0;
109 Res = S_OK;
110 }
111
Init(ISequentialOutStream *stream)112 void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw()
113 {
114 vt.Write = MyWrite;
115 Stream = stream;
116 Res = SZ_OK;
117 Processed = 0;
118 }
119
120
InStreamWrap_Read(ISeekInStreamPtr pp, void *data, size_t *size)121 static SRes InStreamWrap_Read(ISeekInStreamPtr pp, void *data, size_t *size) throw()
122 {
123 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap)
124 UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
125 p->Res = p->Stream->Read(data, curSize, &curSize);
126 *size = curSize;
127 return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
128 }
129
InStreamWrap_Seek(ISeekInStreamPtr pp, Int64 *offset, ESzSeek origin)130 static SRes InStreamWrap_Seek(ISeekInStreamPtr pp, Int64 *offset, ESzSeek origin) throw()
131 {
132 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeekInStreamWrap)
133 UInt32 moveMethod;
134 /* we need (int)origin to eliminate the clang warning:
135 default label in switch which covers all enumeration values
136 [-Wcovered-switch-default */
137 switch ((int)origin)
138 {
139 case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break;
140 case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break;
141 case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break;
142 default: return SZ_ERROR_PARAM;
143 }
144 UInt64 newPosition;
145 p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition);
146 *offset = (Int64)newPosition;
147 return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
148 }
149
Init(IInStream *stream)150 void CSeekInStreamWrap::Init(IInStream *stream) throw()
151 {
152 Stream = stream;
153 vt.Read = InStreamWrap_Read;
154 vt.Seek = InStreamWrap_Seek;
155 Res = S_OK;
156 }
157
158
159 /* ---------- CByteInBufWrap ---------- */
160
Free()161 void CByteInBufWrap::Free() throw()
162 {
163 ::MidFree(Buf);
164 Buf = NULL;
165 }
166
Alloc(UInt32 size)167 bool CByteInBufWrap::Alloc(UInt32 size) throw()
168 {
169 if (!Buf || size != Size)
170 {
171 Free();
172 Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size);
173 Size = size;
174 }
175 return (Buf != NULL);
176 }
177
ReadByteFromNewBlock()178 Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
179 {
180 if (!Extra && Res == S_OK)
181 {
182 UInt32 avail;
183 Res = Stream->Read(Buf, Size, &avail);
184 Processed += (size_t)(Cur - Buf);
185 Cur = Buf;
186 Lim = Buf + avail;
187 if (avail != 0)
188 return *Cur++;
189 }
190 Extra = true;
191 return 0;
192 }
193
194 // #pragma GCC diagnostic ignored "-Winvalid-offsetof"
195
Wrap_ReadByte(IByteInPtr pp)196 static Byte Wrap_ReadByte(IByteInPtr pp) throw()
197 {
198 CByteInBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt);
199 // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInBufWrap)
200 if (p->Cur != p->Lim)
201 return *p->Cur++;
202 return p->ReadByteFromNewBlock();
203 }
204
CByteInBufWrap()205 CByteInBufWrap::CByteInBufWrap() throw(): Buf(NULL)
206 {
207 vt.Read = Wrap_ReadByte;
208 }
209
210
211
212 /* ---------- CByteOutBufWrap ---------- */
213
214 /*
215 void CLookToSequentialWrap::Free() throw()
216 {
217 ::MidFree(BufBase);
218 BufBase = NULL;
219 }
220
221 bool CLookToSequentialWrap::Alloc(UInt32 size) throw()
222 {
223 if (!BufBase || size != Size)
224 {
225 Free();
226 BufBase = (Byte *)::MidAlloc((size_t)size);
227 Size = size;
228 }
229 return (BufBase != NULL);
230 }
231 */
232
233 /*
234 EXTERN_C_BEGIN
235
236 void CLookToSequentialWrap_Look(ILookInSeqStreamPtr pp)
237 {
238 CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj;
239
240 if (p->Extra || p->Res != S_OK)
241 return;
242 {
243 UInt32 avail;
244 p->Res = p->Stream->Read(p->BufBase, p->Size, &avail);
245 p->Processed += avail;
246 pp->Buf = p->BufBase;
247 pp->Limit = pp->Buf + avail;
248 if (avail == 0)
249 p->Extra = true;
250 }
251 }
252
253 EXTERN_C_END
254 */
255
256
257 /* ---------- CByteOutBufWrap ---------- */
258
Free()259 void CByteOutBufWrap::Free() throw()
260 {
261 ::MidFree(Buf);
262 Buf = NULL;
263 }
264
Alloc(size_t size)265 bool CByteOutBufWrap::Alloc(size_t size) throw()
266 {
267 if (!Buf || size != Size)
268 {
269 Free();
270 Buf = (Byte *)::MidAlloc(size);
271 Size = size;
272 }
273 return (Buf != NULL);
274 }
275
Flush()276 HRESULT CByteOutBufWrap::Flush() throw()
277 {
278 if (Res == S_OK)
279 {
280 const size_t size = (size_t)(Cur - Buf);
281 Res = WriteStream(Stream, Buf, size);
282 if (Res == S_OK)
283 Processed += size;
284 // else throw 11;
285 }
286 Cur = Buf; // reset pointer for later Wrap_WriteByte()
287 return Res;
288 }
289
Wrap_WriteByte(IByteOutPtr pp, Byte b)290 static void Wrap_WriteByte(IByteOutPtr pp, Byte b) throw()
291 {
292 CByteOutBufWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt);
293 // Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteOutBufWrap)
294 Byte *dest = p->Cur;
295 *dest = b;
296 p->Cur = ++dest;
297 if (dest == p->Lim)
298 p->Flush();
299 }
300
CByteOutBufWrap()301 CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0)
302 {
303 vt.Write = Wrap_WriteByte;
304 }
305
306
307 /* ---------- CLookOutWrap ---------- */
308
309 /*
310 void CLookOutWrap::Free() throw()
311 {
312 ::MidFree(Buf);
313 Buf = NULL;
314 }
315
316 bool CLookOutWrap::Alloc(size_t size) throw()
317 {
318 if (!Buf || size != Size)
319 {
320 Free();
321 Buf = (Byte *)::MidAlloc(size);
322 Size = size;
323 }
324 return (Buf != NULL);
325 }
326
327 static size_t LookOutWrap_GetOutBuf(ILookOutStreamPtr pp, void **buf) throw()
328 {
329 CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt);
330 *buf = p->Buf;
331 return p->Size;
332 }
333
334 static size_t LookOutWrap_Write(ILookOutStreamPtr pp, size_t size) throw()
335 {
336 CLookOutWrap *p = Z7_CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt);
337 if (p->Res == S_OK && size != 0)
338 {
339 p->Res = WriteStream(p->Stream, p->Buf, size);
340 if (p->Res == S_OK)
341 {
342 p->Processed += size;
343 return size;
344 }
345 }
346 return 0;
347 }
348
349 CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0)
350 {
351 vt.GetOutBuf = LookOutWrap_GetOutBuf;
352 vt.Write = LookOutWrap_Write;
353 }
354 */
355