1 // CWrappers.h
2 
3 #include "StdAfx.h"
4 
5 #include "../../../C/Alloc.h"
6 
7 #include "CWrappers.h"
8 
9 #include "StreamUtils.h"
10 
11 #define PROGRESS_UNKNOWN_VALUE ((UInt64)(Int64)-1)
12 
13 #define CONVERT_PR_VAL(x) (x == PROGRESS_UNKNOWN_VALUE ? NULL : &x)
14 
CompressProgress(void * pp,UInt64 inSize,UInt64 outSize)15 static SRes CompressProgress(void *pp, UInt64 inSize, UInt64 outSize) throw()
16 {
17   CCompressProgressWrap *p = (CCompressProgressWrap *)pp;
18   p->Res = p->Progress->SetRatioInfo(CONVERT_PR_VAL(inSize), CONVERT_PR_VAL(outSize));
19   return (SRes)p->Res;
20 }
21 
CCompressProgressWrap(ICompressProgressInfo * progress)22 CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw()
23 {
24   p.Progress = CompressProgress;
25   Progress = progress;
26   Res = SZ_OK;
27 }
28 
29 static const UInt32 kStreamStepSize = (UInt32)1 << 31;
30 
HRESULT_To_SRes(HRESULT res,SRes defaultRes)31 SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
32 {
33   switch (res)
34   {
35     case S_OK: return SZ_OK;
36     case E_OUTOFMEMORY: return SZ_ERROR_MEM;
37     case E_INVALIDARG: return SZ_ERROR_PARAM;
38     case E_ABORT: return SZ_ERROR_PROGRESS;
39     case S_FALSE: return SZ_ERROR_DATA;
40     case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
41   }
42   return defaultRes;
43 }
44 
MyRead(void * object,void * data,size_t * size)45 static SRes MyRead(void *object, void *data, size_t *size) throw()
46 {
47   CSeqInStreamWrap *p = (CSeqInStreamWrap *)object;
48   UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
49   p->Res = (p->Stream->Read(data, curSize, &curSize));
50   *size = curSize;
51   p->Processed += curSize;
52   if (p->Res == S_OK)
53     return SZ_OK;
54   return HRESULT_To_SRes(p->Res, SZ_ERROR_READ);
55 }
56 
MyWrite(void * object,const void * data,size_t size)57 static size_t MyWrite(void *object, const void *data, size_t size) throw()
58 {
59   CSeqOutStreamWrap *p = (CSeqOutStreamWrap *)object;
60   if (p->Stream)
61   {
62     p->Res = WriteStream(p->Stream, data, size);
63     if (p->Res != 0)
64       return 0;
65   }
66   else
67     p->Res = S_OK;
68   p->Processed += size;
69   return size;
70 }
71 
CSeqInStreamWrap(ISequentialInStream * stream)72 CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw()
73 {
74   p.Read = MyRead;
75   Stream = stream;
76   Processed = 0;
77 }
78 
CSeqOutStreamWrap(ISequentialOutStream * stream)79 CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw()
80 {
81   p.Write = MyWrite;
82   Stream = stream;
83   Res = SZ_OK;
84   Processed = 0;
85 }
86 
SResToHRESULT(SRes res)87 HRESULT SResToHRESULT(SRes res) throw()
88 {
89   switch(res)
90   {
91     case SZ_OK: return S_OK;
92     case SZ_ERROR_MEM: return E_OUTOFMEMORY;
93     case SZ_ERROR_PARAM: return E_INVALIDARG;
94     case SZ_ERROR_PROGRESS: return E_ABORT;
95     case SZ_ERROR_DATA: return S_FALSE;
96     case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
97   }
98   return E_FAIL;
99 }
100 
InStreamWrap_Read(void * pp,void * data,size_t * size)101 static SRes InStreamWrap_Read(void *pp, void *data, size_t *size) throw()
102 {
103   CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
104   UInt32 curSize = ((*size < kStreamStepSize) ? (UInt32)*size : kStreamStepSize);
105   p->Res = p->Stream->Read(data, curSize, &curSize);
106   *size = curSize;
107   return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
108 }
109 
InStreamWrap_Seek(void * pp,Int64 * offset,ESzSeek origin)110 static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw()
111 {
112   CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp;
113   UInt32 moveMethod;
114   switch(origin)
115   {
116     case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break;
117     case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break;
118     case SZ_SEEK_END: moveMethod = STREAM_SEEK_END; break;
119     default: return SZ_ERROR_PARAM;
120   }
121   UInt64 newPosition;
122   p->Res = p->Stream->Seek(*offset, moveMethod, &newPosition);
123   *offset = (Int64)newPosition;
124   return (p->Res == S_OK) ? SZ_OK : SZ_ERROR_READ;
125 }
126 
CSeekInStreamWrap(IInStream * stream)127 CSeekInStreamWrap::CSeekInStreamWrap(IInStream *stream) throw()
128 {
129   Stream = stream;
130   p.Read = InStreamWrap_Read;
131   p.Seek = InStreamWrap_Seek;
132   Res = S_OK;
133 }
134 
135 
136 /* ---------- CByteInBufWrap ---------- */
137 
Free()138 void CByteInBufWrap::Free() throw()
139 {
140   ::MidFree(Buf);
141   Buf = 0;
142 }
143 
Alloc(UInt32 size)144 bool CByteInBufWrap::Alloc(UInt32 size) throw()
145 {
146   if (Buf == 0 || size != Size)
147   {
148     Free();
149     Lim = Cur = Buf = (Byte *)::MidAlloc((size_t)size);
150     Size = size;
151   }
152   return (Buf != 0);
153 }
154 
ReadByteFromNewBlock()155 Byte CByteInBufWrap::ReadByteFromNewBlock() throw()
156 {
157   if (Res == S_OK)
158   {
159     UInt32 avail;
160     Processed += (Cur - Buf);
161     Res = Stream->Read(Buf, Size, &avail);
162     Cur = Buf;
163     Lim = Buf + avail;
164     if (avail != 0)
165       return *Cur++;
166   }
167   Extra = true;
168   return 0;
169 }
170 
Wrap_ReadByte(void * pp)171 static Byte Wrap_ReadByte(void *pp) throw()
172 {
173   CByteInBufWrap *p = (CByteInBufWrap *)pp;
174   if (p->Cur != p->Lim)
175     return *p->Cur++;
176   return p->ReadByteFromNewBlock();
177 }
178 
CByteInBufWrap()179 CByteInBufWrap::CByteInBufWrap(): Buf(0)
180 {
181   p.Read = Wrap_ReadByte;
182 }
183 
184 
185 /* ---------- CByteOutBufWrap ---------- */
186 
Free()187 void CByteOutBufWrap::Free() throw()
188 {
189   ::MidFree(Buf);
190   Buf = 0;
191 }
192 
Alloc(size_t size)193 bool CByteOutBufWrap::Alloc(size_t size) throw()
194 {
195   if (Buf == 0 || size != Size)
196   {
197     Free();
198     Buf = (Byte *)::MidAlloc(size);
199     Size = size;
200   }
201   return (Buf != 0);
202 }
203 
Flush()204 HRESULT CByteOutBufWrap::Flush() throw()
205 {
206   if (Res == S_OK)
207   {
208     size_t size = (Cur - Buf);
209     Res = WriteStream(Stream, Buf, size);
210     if (Res == S_OK)
211       Processed += size;
212     Cur = Buf;
213   }
214   return Res;
215 }
216 
Wrap_WriteByte(void * pp,Byte b)217 static void Wrap_WriteByte(void *pp, Byte b) throw()
218 {
219   CByteOutBufWrap *p = (CByteOutBufWrap *)pp;
220   Byte *dest = p->Cur;
221   *dest = b;
222   p->Cur = ++dest;
223   if (dest == p->Lim)
224     p->Flush();
225 }
226 
CByteOutBufWrap()227 CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0)
228 {
229   p.Write = Wrap_WriteByte;
230 }
231