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 15static 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 22CCompressProgressWrap::CCompressProgressWrap(ICompressProgressInfo *progress) throw() 23{ 24 p.Progress = CompressProgress; 25 Progress = progress; 26 Res = SZ_OK; 27} 28 29static const UInt32 kStreamStepSize = (UInt32)1 << 31; 30 31SRes 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 45static 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 57static 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 72CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream) throw() 73{ 74 p.Read = MyRead; 75 Stream = stream; 76 Processed = 0; 77} 78 79CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw() 80{ 81 p.Write = MyWrite; 82 Stream = stream; 83 Res = SZ_OK; 84 Processed = 0; 85} 86 87HRESULT 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 101static 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 110static 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 127CSeekInStreamWrap::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 138void CByteInBufWrap::Free() throw() 139{ 140 ::MidFree(Buf); 141 Buf = 0; 142} 143 144bool 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 155Byte 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 171static 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 179CByteInBufWrap::CByteInBufWrap(): Buf(0) 180{ 181 p.Read = Wrap_ReadByte; 182} 183 184 185/* ---------- CByteOutBufWrap ---------- */ 186 187void CByteOutBufWrap::Free() throw() 188{ 189 ::MidFree(Buf); 190 Buf = 0; 191} 192 193bool 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 204HRESULT 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 217static 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 227CByteOutBufWrap::CByteOutBufWrap() throw(): Buf(0) 228{ 229 p.Write = Wrap_WriteByte; 230} 231