tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XzEncoder.cpp (5772B)


      1 // XzEncoder.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../C/Alloc.h"
      6 
      7 #include "../../Common/MyString.h"
      8 #include "../../Common/StringToInt.h"
      9 
     10 #include "../Common/CWrappers.h"
     11 #include "../Common/StreamUtils.h"
     12 
     13 #include "XzEncoder.h"
     14 
     15 namespace NCompress {
     16 
     17 namespace NLzma2 {
     18 
     19 HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzma2Props);
     20 
     21 }
     22 
     23 namespace NXz {
     24 
     25 void CEncoder::InitCoderProps()
     26 {
     27  XzProps_Init(&xzProps);
     28 }
     29 
     30 CEncoder::CEncoder()
     31 {
     32  XzProps_Init(&xzProps);
     33  _encoder = NULL;
     34  _encoder = XzEnc_Create(&g_Alloc, &g_BigAlloc);
     35  if (!_encoder)
     36    throw 1;
     37 }
     38 
     39 CEncoder::~CEncoder()
     40 {
     41  if (_encoder)
     42    XzEnc_Destroy(_encoder);
     43 }
     44 
     45 
     46 struct CMethodNamePair
     47 {
     48  UInt32 Id;
     49  const char *Name;
     50 };
     51 
     52 static const CMethodNamePair g_NamePairs[] =
     53 {
     54  { XZ_ID_Delta, "Delta" },
     55  { XZ_ID_X86, "BCJ" },
     56  { XZ_ID_PPC, "PPC" },
     57  { XZ_ID_IA64, "IA64" },
     58  { XZ_ID_ARM, "ARM" },
     59  { XZ_ID_ARMT, "ARMT" },
     60  { XZ_ID_SPARC, "SPARC" }
     61  // { XZ_ID_LZMA2, "LZMA2" }
     62 };
     63 
     64 static int FilterIdFromName(const wchar_t *name)
     65 {
     66  for (unsigned i = 0; i < ARRAY_SIZE(g_NamePairs); i++)
     67  {
     68    const CMethodNamePair &pair = g_NamePairs[i];
     69    if (StringsAreEqualNoCase_Ascii(name, pair.Name))
     70      return (int)pair.Id;
     71  }
     72  return -1;
     73 }
     74 
     75 
     76 HRESULT CEncoder::SetCheckSize(UInt32 checkSizeInBytes)
     77 {
     78  unsigned id;
     79  switch (checkSizeInBytes)
     80  {
     81    case  0: id = XZ_CHECK_NO; break;
     82    case  4: id = XZ_CHECK_CRC32; break;
     83    case  8: id = XZ_CHECK_CRC64; break;
     84    case 32: id = XZ_CHECK_SHA256; break;
     85    default: return E_INVALIDARG;
     86  }
     87  xzProps.checkId = id;
     88  return S_OK;
     89 }
     90 
     91 
     92 HRESULT CEncoder::SetCoderProp(PROPID propID, const PROPVARIANT &prop)
     93 {
     94  if (propID == NCoderPropID::kNumThreads)
     95  {
     96    if (prop.vt != VT_UI4)
     97      return E_INVALIDARG;
     98    xzProps.numTotalThreads = (int)(prop.ulVal);
     99    return S_OK;
    100  }
    101 
    102  if (propID == NCoderPropID::kCheckSize)
    103  {
    104    if (prop.vt != VT_UI4)
    105      return E_INVALIDARG;
    106    return SetCheckSize(prop.ulVal);
    107  }
    108 
    109  if (propID == NCoderPropID::kBlockSize2)
    110  {
    111    if (prop.vt == VT_UI4)
    112      xzProps.blockSize = prop.ulVal;
    113    else if (prop.vt == VT_UI8)
    114      xzProps.blockSize = prop.uhVal.QuadPart;
    115    else
    116      return E_INVALIDARG;
    117    return S_OK;
    118  }
    119 
    120  if (propID == NCoderPropID::kReduceSize)
    121  {
    122    if (prop.vt == VT_UI8)
    123      xzProps.reduceSize = prop.uhVal.QuadPart;
    124    else
    125      return E_INVALIDARG;
    126    return S_OK;
    127  }
    128 
    129  if (propID == NCoderPropID::kFilter)
    130  {
    131    if (prop.vt == VT_UI4)
    132    {
    133      UInt32 id32 = prop.ulVal;
    134      if (id32 == XZ_ID_Delta)
    135        return E_INVALIDARG;
    136      xzProps.filterProps.id = prop.ulVal;
    137    }
    138    else
    139    {
    140      if (prop.vt != VT_BSTR)
    141        return E_INVALIDARG;
    142      
    143      const wchar_t *name = prop.bstrVal;
    144      const wchar_t *end;
    145 
    146      UInt32 id32 = ConvertStringToUInt32(name, &end);
    147      
    148      if (end != name)
    149        name = end;
    150      else
    151      {
    152        if (IsString1PrefixedByString2_NoCase_Ascii(name, "Delta"))
    153        {
    154          name += 5; // strlen("Delta");
    155          id32 = XZ_ID_Delta;
    156        }
    157        else
    158        {
    159          int filterId = FilterIdFromName(prop.bstrVal);
    160          if (filterId < 0 /* || filterId == XZ_ID_LZMA2 */)
    161            return E_INVALIDARG;
    162          id32 = filterId;
    163        }
    164      }
    165      
    166      if (id32 == XZ_ID_Delta)
    167      {
    168        wchar_t c = *name;
    169        if (c != '-' && c != ':')
    170          return E_INVALIDARG;
    171        name++;
    172        UInt32 delta = ConvertStringToUInt32(name, &end);
    173        if (end == name || *end != 0 || delta == 0 || delta > 256)
    174          return E_INVALIDARG;
    175        xzProps.filterProps.delta = delta;
    176      }
    177      
    178      xzProps.filterProps.id = id32;
    179    }
    180    
    181    return S_OK;
    182  }
    183 
    184  return NLzma2::SetLzma2Prop(propID, prop, xzProps.lzma2Props);
    185 }
    186 
    187 
    188 STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
    189    const PROPVARIANT *coderProps, UInt32 numProps)
    190 {
    191  XzProps_Init(&xzProps);
    192 
    193  for (UInt32 i = 0; i < numProps; i++)
    194  {
    195    RINOK(SetCoderProp(propIDs[i], coderProps[i]));
    196  }
    197  
    198  return S_OK;
    199  // return SResToHRESULT(XzEnc_SetProps(_encoder, &xzProps));
    200 }
    201 
    202 
    203 STDMETHODIMP CEncoder::SetCoderPropertiesOpt(const PROPID *propIDs,
    204    const PROPVARIANT *coderProps, UInt32 numProps)
    205 {
    206  for (UInt32 i = 0; i < numProps; i++)
    207  {
    208    const PROPVARIANT &prop = coderProps[i];
    209    PROPID propID = propIDs[i];
    210    if (propID == NCoderPropID::kExpectedDataSize)
    211      if (prop.vt == VT_UI8)
    212        XzEnc_SetDataSize(_encoder, prop.uhVal.QuadPart);
    213  }
    214  return S_OK;
    215 }
    216 
    217 
    218 #define RET_IF_WRAP_ERROR(wrapRes, sRes, sResErrorCode) \
    219  if (wrapRes != S_OK /* && (sRes == SZ_OK || sRes == sResErrorCode) */) return wrapRes;
    220 
    221 STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
    222    const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
    223 {
    224  CSeqInStreamWrap inWrap;
    225  CSeqOutStreamWrap outWrap;
    226  CCompressProgressWrap progressWrap;
    227 
    228  inWrap.Init(inStream);
    229  outWrap.Init(outStream);
    230  progressWrap.Init(progress);
    231 
    232  SRes res = XzEnc_SetProps(_encoder, &xzProps);
    233  if (res == SZ_OK)
    234    res = XzEnc_Encode(_encoder, &outWrap.vt, &inWrap.vt, progress ? &progressWrap.vt : NULL);
    235 
    236  // SRes res = Xz_Encode(&outWrap.vt, &inWrap.vt, &xzProps, progress ? &progressWrap.vt : NULL);
    237 
    238  RET_IF_WRAP_ERROR(inWrap.Res, res, SZ_ERROR_READ)
    239  RET_IF_WRAP_ERROR(outWrap.Res, res, SZ_ERROR_WRITE)
    240  RET_IF_WRAP_ERROR(progressWrap.Res, res, SZ_ERROR_PROGRESS)
    241 
    242  return SResToHRESULT(res);
    243 }
    244  
    245 }}