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(const ICompressProgress * pp,UInt64 inSize,UInt64 outSize)60 static SRes CompressProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize) throw()
61 {
62   CCompressProgressWrap *p = CONTAINER_FROM_VTBL(pp, CCompressProgressWrap, vt);
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(const ISeqInStream * pp,void * data,size_t * size)76 static SRes MyRead(const ISeqInStream *pp, void *data, size_t *size) throw()
77 {
78   CSeqInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqInStreamWrap, vt);
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(const ISeqOutStream * pp,const void * data,size_t size)88 static size_t MyWrite(const ISeqOutStream *pp, const void *data, size_t size) throw()
89 {
90   CSeqOutStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeqOutStreamWrap, vt);
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(const ISeekInStream * pp,void * data,size_t * size)121 static SRes InStreamWrap_Read(const ISeekInStream *pp, void *data, size_t *size) throw()
122 {
123   CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt);
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(const ISeekInStream * pp,Int64 * offset,ESzSeek origin)130 static SRes InStreamWrap_Seek(const ISeekInStream *pp, Int64 *offset, ESzSeek origin) throw()
131 {
132   CSeekInStreamWrap *p = CONTAINER_FROM_VTBL(pp, CSeekInStreamWrap, vt);
133   UInt32 moveMethod;
134   switch (origin)
135   {
136     case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break;
137     case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break;
138     case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break;
139     default: return SZ_ERROR_PARAM;
140   }
141   UInt64 newPosition;
142   p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition);
143   *offset = (Int64)newPosition;
144   return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
145 }
146 
Init(IInStream * stream)147 void CSeekInStreamWrap::Init(IInStream *stream) throw()
148 {
149   Stream = stream;
150   vt.Read = InStreamWrap_Read;
151   vt.Seek = InStreamWrap_Seek;
152   Res = S_OK;
153 }
154 
155 
156 /* ---------- CByteInBufWrap ---------- */
157 
Free()158 void CByteInBufWrap::Free() throw()
159 {
160   ::MidFree(Buf);
161   Buf = NULL;
162 }
163 
Alloc(UInt32 size)164 bool CByteInBufWrap::Alloc(UInt32 size) throw()
165 {
166   if (!Buf || size != Size)
167   {
168     Free();
169     Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size);
170     Size = size;
171   }
172   return (Buf != NULL);
173 }
174 
ReadByteFromNewBlock()175 Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
176 {
177   if (!Extra && Res == S_OK)
178   {
179     UInt32 avail;
180     Res = Stream->Read(Buf, Size, &avail);
181     Processed += (size_t)(Cur - Buf);
182     Cur = Buf;
183     Lim = Buf + avail;
184     if (avail != 0)
185       return *Cur++;
186   }
187   Extra = true;
188   return 0;
189 }
190 
Wrap_ReadByte(const IByteIn * pp)191 static Byte Wrap_ReadByte(const IByteIn *pp) throw()
192 {
193   CByteInBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteInBufWrap, vt);
194   if (p->Cur != p->Lim)
195     return *p->Cur++;
196   return p->ReadByteFromNewBlock();
197 }
198 
CByteInBufWrap()199 CByteInBufWrap::CByteInBufWrap(): Buf(NULL)
200 {
201   vt.Read = Wrap_ReadByte;
202 }
203 
204 
205 
206 /* ---------- CByteOutBufWrap ---------- */
207 
208 /*
209 void CLookToSequentialWrap::Free() throw()
210 {
211   ::MidFree(BufBase);
212   BufBase = NULL;
213 }
214 
215 bool CLookToSequentialWrap::Alloc(UInt32 size) throw()
216 {
217   if (!BufBase || size != Size)
218   {
219     Free();
220     BufBase = (Byte *)::MidAlloc((size_t)size);
221     Size = size;
222   }
223   return (BufBase != NULL);
224 }
225 */
226 
227 /*
228 EXTERN_C_BEGIN
229 
230 void CLookToSequentialWrap_Look(ILookInSeqStream *pp)
231 {
232   CLookToSequentialWrap *p = (CLookToSequentialWrap *)pp->Obj;
233 
234   if (p->Extra || p->Res != S_OK)
235     return;
236   {
237     UInt32 avail;
238     p->Res = p->Stream->Read(p->BufBase, p->Size, &avail);
239     p->Processed += avail;
240     pp->Buf = p->BufBase;
241     pp->Limit = pp->Buf + avail;
242     if (avail == 0)
243       p->Extra = true;
244   }
245 }
246 
247 EXTERN_C_END
248 */
249 
250 
251 /* ---------- CByteOutBufWrap ---------- */
252 
Free()253 void CByteOutBufWrap::Free() throw()
254 {
255   ::MidFree(Buf);
256   Buf = NULL;
257 }
258 
Alloc(size_t size)259 bool CByteOutBufWrap::Alloc(size_t size) throw()
260 {
261   if (!Buf || size != Size)
262   {
263     Free();
264     Buf = (Byte *)::MidAlloc(size);
265     Size = size;
266   }
267   return (Buf != NULL);
268 }
269 
Flush()270 HRESULT CByteOutBufWrap::Flush() throw()
271 {
272   if (Res == S_OK)
273   {
274     const size_t size = (size_t)(Cur - Buf);
275     Res = WriteStream(Stream, Buf, size);
276     if (Res == S_OK)
277       Processed += size;
278     // else throw 11;
279   }
280   Cur = Buf; // reset pointer for later Wrap_WriteByte()
281   return Res;
282 }
283 
Wrap_WriteByte(const IByteOut * pp,Byte b)284 static void Wrap_WriteByte(const IByteOut *pp, Byte b) throw()
285 {
286   CByteOutBufWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CByteOutBufWrap, vt);
287   Byte *dest = p->Cur;
288   *dest = b;
289   p->Cur = ++dest;
290   if (dest == p->Lim)
291     p->Flush();
292 }
293 
CByteOutBufWrap()294 CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0)
295 {
296   vt.Write = Wrap_WriteByte;
297 }
298 
299 
300 /* ---------- CLookOutWrap ---------- */
301 
302 /*
303 void CLookOutWrap::Free() throw()
304 {
305   ::MidFree(Buf);
306   Buf = NULL;
307 }
308 
309 bool CLookOutWrap::Alloc(size_t size) throw()
310 {
311   if (!Buf || size != Size)
312   {
313     Free();
314     Buf = (Byte *)::MidAlloc(size);
315     Size = size;
316   }
317   return (Buf != NULL);
318 }
319 
320 static size_t LookOutWrap_GetOutBuf(const ILookOutStream *pp, void **buf) throw()
321 {
322   CLookOutWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt);
323   *buf = p->Buf;
324   return p->Size;
325 }
326 
327 static size_t LookOutWrap_Write(const ILookOutStream *pp, size_t size) throw()
328 {
329   CLookOutWrap *p = CONTAINER_FROM_VTBL_CLS(pp, CLookOutWrap, vt);
330   if (p->Res == S_OK && size != 0)
331   {
332     p->Res = WriteStream(p->Stream, p->Buf, size);
333     if (p->Res == S_OK)
334     {
335       p->Processed += size;
336       return size;
337     }
338   }
339   return 0;
340 }
341 
342 CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0)
343 {
344   vt.GetOutBuf = LookOutWrap_GetOutBuf;
345   vt.Write = LookOutWrap_Write;
346 }
347 */
348