Home | History | Annotate | Download | only in Common
      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 
     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 
     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 
     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 
     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 
     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 
     70 CSeqInStreamWrap::CSeqInStreamWrap(ISequentialInStream *stream)
     71 {
     72   p.Read = MyRead;
     73   Stream = stream;
     74 }
     75 
     76 CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream)
     77 {
     78   p.Write = MyWrite;
     79   Stream = stream;
     80   Res = SZ_OK;
     81   Processed = 0;
     82 }
     83 
     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 
     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 
    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 
    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 
    134 void CByteInBufWrap::Free()
    135 {
    136   ::MidFree(Buf);
    137   Buf = 0;
    138 }
    139 
    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 
    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 
    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 
    175 CByteInBufWrap::CByteInBufWrap(): Buf(0)
    176 {
    177   p.Read = Wrap_ReadByte;
    178 }
    179 
    180 
    181 /* ---------- CByteOutBufWrap ---------- */
    182 
    183 void CByteOutBufWrap::Free()
    184 {
    185   ::MidFree(Buf);
    186   Buf = 0;
    187 }
    188 
    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 
    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 
    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 
    223 CByteOutBufWrap::CByteOutBufWrap(): Buf(0)
    224 {
    225   p.Write = Wrap_WriteByte;
    226 }
    227