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