⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 handlerout.cpp

📁 一个7ZIP的解压源码。比较详细。里面含有四种语言的实现代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:

HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
{
  CProp 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.Id = NCoderPropID::kDictionarySize;
    else
      property.Id = NCoderPropID::kUsedMemorySize;
    property.Value = dicSize;
    oneMethodInfo.Properties.Add(property);
  }
  else
  {
    int index = FindPropIdFromStringName(name);
    if (index < 0)
      return E_INVALIDARG;
    
    const CNameToPropID &nameToPropID = g_NameToPropID[index];
    property.Id = nameToPropID.PropID;
    
    NCOM::CPropVariant propValue;
    
    if (nameToPropID.VarType == VT_BSTR)
      propValue = value;
    else if (nameToPropID.VarType == VT_BOOL)
    {
      bool res;
      if (!StringToBool(value, res))
        return E_INVALIDARG;
      propValue = res;
    }
    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.Properties.Add(property);
  }
  return S_OK;
}

HRESULT COutHandler::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 COutHandler::SetSolidSettings(const UString &s)
{
  bool res;
  if (StringToBool(s, res))
  {
    if (res)
      InitSolid();
    else
      _numSolidFiles = 1;
    return S_OK;
  }
  UString s2 = s;
  s2.MakeUpper();
  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 COutHandler::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;
  }
}

void COutHandler::Init()
{
  _removeSfxBlock = false;
  _compressHeaders = true;
  _encryptHeaders = false;
  
  WriteModified = true;
  WriteCreated = false;
  WriteAccessed = false;
  
  #ifdef COMPRESS_MT
  _numThreads = NWindows::NSystem::GetNumberOfProcessors();
  #endif
  
  _level = 5;
  _autoFilter = true;
  _volumeMode = false;
  _crcSize = 4;
  InitSolid();
}

void COutHandler::BeforeSetProperty()
{
  Init();
  #ifdef COMPRESS_MT
  numProcessors = NSystem::GetNumberOfProcessors();
  #endif

  mainDicSize = 0xFFFFFFFF;
  mainDicMethodIndex = 0xFFFFFFFF;
  minNumber = 0;
  _crcSize = 4;
}

HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
  UString name = nameSpec;
  name.MakeUpper();
  if (name.IsEmpty())
    return E_INVALIDARG;
  
  if (name[0] == 'X')
  {
    name.Delete(0);
    _level = 9;
    return ParsePropValue(name, value, _level);
  }
  
  if (name[0] == L'S')
  {
    name.Delete(0);
    if (name.IsEmpty())
      return SetSolidSettings(value);
    if (value.vt != VT_EMPTY)
      return E_INVALIDARG;
    return SetSolidSettings(name);
  }
  
  if (name == L"CRC")
  {
    _crcSize = 4;
    name.Delete(0, 3);
    return ParsePropValue(name, value, _crcSize);
  }
  
  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
      return S_OK;
    }
    if (name.CompareNoCase(L"RSFX") == 0)
      return SetBoolProperty(_removeSfxBlock, value);
    if (name.CompareNoCase(L"F") == 0)
      return SetBoolProperty(_autoFilter, value);
    if (name.CompareNoCase(L"HC") == 0)
      return SetBoolProperty(_compressHeaders, value);
    if (name.CompareNoCase(L"HCF") == 0)
    {
      bool compressHeadersFull = true;
      RINOK(SetBoolProperty(compressHeadersFull, value));
      if (!compressHeadersFull)
        return E_INVALIDARG;
      return S_OK;
    }
    if (name.CompareNoCase(L"HE") == 0)
      return SetBoolProperty(_encryptHeaders, value);
    if (name.CompareNoCase(L"TM") == 0)
      return SetBoolProperty(WriteModified, value);
    if (name.CompareNoCase(L"TC") == 0)
      return SetBoolProperty(WriteCreated, value);
    if (name.CompareNoCase(L"TA") == 0)
      return SetBoolProperty(WriteAccessed, value);
    if (name.CompareNoCase(L"V") == 0)
      return SetBoolProperty(_volumeMode, value);
    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;
    
    RINOK(SetParams(oneMethodInfo, value.bstrVal));
  }
  else
  {
    CProp property;
    if (realName.Left(1).CompareNoCase(L"D") == 0)
    {
      UInt32 dicSize;
      RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
      property.Id = NCoderPropID::kDictionarySize;
      property.Value = dicSize;
      oneMethodInfo.Properties.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.Id = NCoderPropID::kUsedMemorySize;
      property.Value = dicSize;
      oneMethodInfo.Properties.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.Id = nameToPropID.PropID;
      
      if (!ConvertProperty(value, nameToPropID.VarType, property.Value))
        return E_INVALIDARG;
      
      oneMethodInfo.Properties.Add(property);
    }
  }
  return S_OK;
}  

}

⌨️ 快捷键说明

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