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