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