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