7zhandlerout.cpp

来自「著名的7zip的压缩算法,压缩比最高,但是压缩时间也比较长!」· C++ 代码 · 共 1,124 行 · 第 1/3 页

CPP
1,124
字号
{
  stream = 0;
  int index = ParseStringToUInt32(srcString, coder);
  if (index == 0)
    return E_INVALIDARG;
  srcString.Delete(0, index);
  if (srcString[0] == 'S')
  {
    srcString.Delete(0);
    int index = ParseStringToUInt32(srcString, stream);
    if (index == 0)
      return E_INVALIDARG;
    srcString.Delete(0, index);
  }
  return S_OK;
}

static HRESULT GetBindInfo(UString &srcString, CBind &bind)
{
  RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
  if (srcString[0] != ':')
    return E_INVALIDARG;
  srcString.Delete(0);
  RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
  if (!srcString.IsEmpty())
    return E_INVALIDARG;
  return S_OK;
}

static void SplitParams(const UString &srcString, UStringVector &subStrings)
{
  subStrings.Clear();
  UString name;
  int len = srcString.Length();
  if (len == 0)
    return;
  for (int i = 0; i < len; i++)
  {
    wchar_t c = srcString[i];
    if (c == L':')
    {
      subStrings.Add(name);
      name.Empty();
    }
    else
      name += c;
  }
  subStrings.Add(name);
}

static void SplitParam(const UString &param, UString &name, UString &value)
{
  int eqPos = param.Find(L'=');
  if (eqPos >= 0)
  {
    name = param.Left(eqPos);
    value = param.Mid(eqPos + 1);
    return;
  }
  for(int i = 0; i < param.Length(); i++)
  {
    wchar_t c = param[i];
    if (c >= L'0' && c <= L'9')
    {
      name = param.Left(i);
      value = param.Mid(i);
      return;
    }
  }
  name = param;
}

HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
{
  CProperty property;
  if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
  {
    UInt32 dicSize;
    RINOK(ParsePropDictionaryValue(value, dicSize));
    if (name.CompareNoCase(L"D") == 0)
      property.PropID = NCoderPropID::kDictionarySize;
    else
      property.PropID = NCoderPropID::kUsedMemorySize;
    property.Value = dicSize;
    oneMethodInfo.CoderProperties.Add(property);
  }
  else
  {
    int index = FindPropIdFromStringName(name);
    if (index < 0)
      return E_INVALIDARG;
    
    const CNameToPropID &nameToPropID = g_NameToPropID[index];
    property.PropID = nameToPropID.PropID;
    
    NCOM::CPropVariant propValue;
    
    
    if (nameToPropID.VarType == VT_BSTR)
      propValue = value;
    else
    {
      UInt32 number;
      if (ParseStringToUInt32(value, number) == value.Length())
        propValue = number;
      else
        propValue = value;
    }
    
    if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value))
      return E_INVALIDARG;
    
    oneMethodInfo.CoderProperties.Add(property);
  }
  return S_OK;
}

HRESULT CHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
{
  UStringVector params;
  SplitParams(srcString, params);
  if (params.Size() > 0)
    oneMethodInfo.MethodName = params[0];
  for (int i = 1; i < params.Size(); i++)
  {
    const UString &param = params[i];
    UString name, value;
    SplitParam(param, name, value);
    RINOK(SetParam(oneMethodInfo, name, value));
  }
  return S_OK;
}

HRESULT CHandler::SetSolidSettings(const UString &s)
{
  UString s2 = s;
  s2.MakeUpper();
  if (s2.IsEmpty() || s2.Compare(L"ON") == 0)
  {
    InitSolid();
    return S_OK;
  }
  if (s2.Compare(L"OFF") == 0)
  {
    _numSolidFiles = 1;
    return S_OK;
  }
  for (int i = 0; i < s2.Length();)
  {
    const wchar_t *start = ((const wchar_t *)s2) + i;
    const wchar_t *end;
    UInt64 v = ConvertStringToUInt64(start, &end);
    if (start == end)
    {
      if (s2[i++] != 'E')
        return E_INVALIDARG;
      _solidExtension = true;
      continue;
    }
    i += (int)(end - start);
    if (i == s2.Length())
      return E_INVALIDARG;
    wchar_t c = s2[i++];
    switch(c)
    {
      case 'F':
        if (v < 1)
          v = 1;
        _numSolidFiles = v;
        break;
      case 'B':
        _numSolidBytes = v;
        _numSolidBytesDefined = true;
        break;
      case 'K':
        _numSolidBytes = (v << 10);
        _numSolidBytesDefined = true;
        break;
      case 'M':
        _numSolidBytes = (v << 20);
        _numSolidBytesDefined = true;
        break;
      case 'G':
        _numSolidBytes = (v << 30);
        _numSolidBytesDefined = true;
        break;
      default:
        return E_INVALIDARG;
    }
  }
  return S_OK;
}

HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
{
  switch(value.vt)
  {
    case VT_EMPTY:
      InitSolid();
      return S_OK;
    case VT_BSTR:
      return SetSolidSettings(value.bstrVal);
    default:
      return E_INVALIDARG;
  }
}

STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
  COM_TRY_BEGIN
  _methods.Clear();
  _binds.Clear();
  Init();
  #ifdef COMPRESS_MT
  const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
  #endif

  UInt32 mainDicSize = 0xFFFFFFFF;
  UInt32 mainDicMethodIndex = 0xFFFFFFFF;

  UInt32 minNumber = 0;

  for (int i = 0; i < numProperties; i++)
  {
    UString name = names[i];
    name.MakeUpper();
    if (name.IsEmpty())
      return E_INVALIDARG;

    const PROPVARIANT &value = values[i];

    if (name[0] == 'X')
    {
      name.Delete(0);
      _level = 9;
      RINOK(ParsePropValue(name, value, _level));
      continue;
    }

    if (name[0] == 'B')
    {
      name.Delete(0);
      CBind bind;
      RINOK(GetBindInfo(name, bind));
      _binds.Add(bind);
      continue;
    }

    if (name[0] == L'S')
    {
      name.Delete(0);
      if (name.IsEmpty())
      {
        RINOK(SetSolidSettings(value));
      }
      else
      {
        RINOK(SetSolidSettings(name));
      }
      continue;
    }
    
      
    UInt32 number;
    int index = ParseStringToUInt32(name, number);
    UString realName = name.Mid(index);
    if (index == 0)
    {
      if(name.Left(2).CompareNoCase(L"MT") == 0)
      {
        #ifdef COMPRESS_MT
        RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
        #endif
        continue;
      }
      else if (name.CompareNoCase(L"RSFX") == 0)
      {
        RINOK(SetBoolProperty(_removeSfxBlock, value));
        continue;
      }
      else if (name.CompareNoCase(L"F") == 0)
      {
        RINOK(SetBoolProperty(_autoFilter, value));
        continue;
      }
      else if (name.CompareNoCase(L"HC") == 0)
      {
        RINOK(SetBoolProperty(_compressHeaders, value));
        continue;
      }
      else if (name.CompareNoCase(L"HCF") == 0)
      {
        RINOK(SetBoolProperty(_compressHeadersFull, value));
        continue;
      }
      else if (name.CompareNoCase(L"HE") == 0)
      {
        RINOK(SetBoolProperty(_encryptHeaders, value));
        continue;
      }
      else if (name.CompareNoCase(L"V") == 0)
      {
        RINOK(SetBoolProperty(_volumeMode, value));
        continue;
      }
      number = 0;
    }
    if (number > 10000)
      return E_FAIL;
    if (number < minNumber)
      return E_INVALIDARG;
    number -= minNumber;
    for(int j = _methods.Size(); j <= (int)number; j++)
    {
      COneMethodInfo oneMethodInfo;
      _methods.Add(oneMethodInfo);
    }

    COneMethodInfo &oneMethodInfo = _methods[number];

    if (realName.Length() == 0)
    {
      if (value.vt != VT_BSTR)
        return E_INVALIDARG;
      
      // oneMethodInfo.MethodName = UnicodeStringToMultiByte(UString(value.bstrVal));
      RINOK(SetParams(oneMethodInfo, value.bstrVal));
    }
    else
    {
      CProperty property;
      if (realName.Left(1).CompareNoCase(L"D") == 0)
      {
        UInt32 dicSize;
        RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
        property.PropID = NCoderPropID::kDictionarySize;
        property.Value = dicSize;
        oneMethodInfo.CoderProperties.Add(property);
        if (number <= mainDicMethodIndex)
          mainDicSize = dicSize;
      }
      else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
      {
        UInt32 dicSize;
        RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
        property.PropID = NCoderPropID::kUsedMemorySize;
        property.Value = dicSize;
        oneMethodInfo.CoderProperties.Add(property);
        if (number <= mainDicMethodIndex)
          mainDicSize = dicSize;
      }
      else
      {
        int index = FindPropIdFromStringName(realName);
        if (index < 0)
          return E_INVALIDARG;
        
        const CNameToPropID &nameToPropID = g_NameToPropID[index];
        property.PropID = nameToPropID.PropID;
        
        if (!ConvertProperty(value, nameToPropID.VarType, property.Value))
          return E_INVALIDARG;
        
        oneMethodInfo.CoderProperties.Add(property);
      }
    }
  }

  return S_OK;
  COM_TRY_END
}  

}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?