xref: /third_party/lzma/CPP/7zip/Common/CWrappers.cpp (revision 370b324c)
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
11SRes 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
26HRESULT 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
60static 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
67void CCompressProgressWrap::Init(ICompressProgressInfo *progress) throw()
68{
69  vt.Progress = CompressProgress;
70  Progress = progress;
71  Res = SZ_OK;
72}
73
74static const UInt32 kStreamStepSize = (UInt32)1 << 31;
75
76static 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
88static 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
104void CSeqInStreamWrap::Init(ISequentialInStream *stream) throw()
105{
106  vt.Read = MyRead;
107  Stream = stream;
108  Processed = 0;
109  Res = S_OK;
110}
111
112void CSeqOutStreamWrap::Init(ISequentialOutStream *stream) throw()
113{
114  vt.Write = MyWrite;
115  Stream = stream;
116  Res = SZ_OK;
117  Processed = 0;
118}
119
120
121static 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
130static 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
150void 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
161void CByteInBufWrap::Free() throw()
162{
163  ::MidFree(Buf);
164  Buf = NULL;
165}
166
167bool 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
178Byte 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
196static 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
205CByteInBufWrap::CByteInBufWrap() throw(): Buf(NULL)
206{
207  vt.Read = Wrap_ReadByte;
208}
209
210
211
212/* ---------- CByteOutBufWrap ---------- */
213
214/*
215void CLookToSequentialWrap::Free() throw()
216{
217  ::MidFree(BufBase);
218  BufBase = NULL;
219}
220
221bool 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/*
234EXTERN_C_BEGIN
235
236void 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
253EXTERN_C_END
254*/
255
256
257/* ---------- CByteOutBufWrap ---------- */
258
259void CByteOutBufWrap::Free() throw()
260{
261  ::MidFree(Buf);
262  Buf = NULL;
263}
264
265bool 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
276HRESULT 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
290static 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
301CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(NULL), Size(0)
302{
303  vt.Write = Wrap_WriteByte;
304}
305
306
307/* ---------- CLookOutWrap ---------- */
308
309/*
310void CLookOutWrap::Free() throw()
311{
312  ::MidFree(Buf);
313  Buf = NULL;
314}
315
316bool 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
327static 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
334static 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
349CLookOutWrap::CLookOutWrap() throw(): Buf(NULL), Size(0)
350{
351  vt.GetOutBuf = LookOutWrap_GetOutBuf;
352  vt.Write = LookOutWrap_Write;
353}
354*/
355