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