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