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

📄 agentout.cpp

📁 7z一个高压缩比的压缩程序源代码,重要的是里面的算法值得学习
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  
  CMyComPtr<ISetProperties> setProperties;
  if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
  {
    if (m_PropNames.Size() == 0)
    {
      RINOK(setProperties->SetProperties(0, 0, 0));
    }
    else
    {
      CRecordVector<const wchar_t *> names;
      for(i = 0; i < m_PropNames.Size(); i++)
        names.Add((const wchar_t *)m_PropNames[i]);

      NWindows::NCOM::CPropVariant *propValues = new NWindows::NCOM::CPropVariant[m_PropValues.Size()];
      try
      {
        for (int i = 0; i < m_PropValues.Size(); i++)
          propValues[i] = m_PropValues[i];
        RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size()));
      }
      catch(...)
      {
        delete []propValues;
        return E_FAIL;
      }
      delete []propValues;
    }
  }
  m_PropNames.Clear();
  m_PropValues.Clear();

  if (sfxModule != NULL)
  {
    CInFileStream *sfxStreamSpec = new CInFileStream;
    CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
    if (!sfxStreamSpec->Open(sfxModule))
      return E_FAIL;
      // throw "Can't open sfx module";
    RINOK(CopyBlock(sfxStream, outStream));
  }

  RINOK(outArchive->UpdateItems(outStream, updatePairs2.Size(),updateCallback));
  return outStreamSpec->Close();
}

STDMETHODIMP CAgent::DoOperation2(
    const wchar_t *newArchiveName,
    const Byte *stateActions,
    const wchar_t *sfxModule,
    IFolderArchiveUpdateCallback *updateCallback100)
{
  return DoOperation(_codecs, -1, newArchiveName,
    stateActions, sfxModule, updateCallback100);
}

HRESULT CAgent::CommonUpdate(
    const wchar_t *newArchiveName,
    int numUpdateItems,
    IArchiveUpdateCallback *updateCallback)
{
  if (!CanUpdate())
    return E_NOTIMPL;
  CMyComPtr<IOutArchive> outArchive;
  RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));

  COutFileStream *outStreamSpec = new COutFileStream;
  CMyComPtr<IOutStream> outStream(outStreamSpec);

  UString archiveName = newArchiveName;
  {
    UString resultPath;
    int pos;
    if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
      throw 141716;
    NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
  }

  /*
  bool isOK = false;
  for (int i = 0; i < (1 << 16); i++)
  {
    resultName = newArchiveName;
    if (i > 0)
    {
      wchar_t s[32];
      ConvertUInt64ToString(i, s);
      resultName += s;
    }
    if (outStreamSpec->Open(realPath))
    {
      isOK = true;
      break;
    }
    if (::GetLastError() != ERROR_FILE_EXISTS)
      return ::GetLastError();
  }
  if (!isOK)
    return ::GetLastError();
  */
  if (!outStreamSpec->Create(archiveName, true))
  {
    // ShowLastErrorMessage();
    return E_FAIL;
  }
  
  RINOK(outArchive->UpdateItems(outStream, numUpdateItems, updateCallback));
  return outStreamSpec->Close();
}


STDMETHODIMP CAgent::DeleteItems(
    const wchar_t *newArchiveName,
    const UInt32 *indices, UInt32 numItems,
    IFolderArchiveUpdateCallback *updateCallback100)
{
  if (!CanUpdate())
    return E_NOTIMPL;
  CUpdateCallbackAgent updateCallbackAgent;
  updateCallbackAgent.SetCallback(updateCallback100);
  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
  
  CUIntVector realIndices;
  _agentFolder->GetRealIndices(indices, numItems, realIndices);
  CRecordVector<CUpdatePair2> updatePairs;
  int curIndex = 0;
  UInt32 numItemsInArchive;
  RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
  for (UInt32 i = 0; i < numItemsInArchive; i++)
  {
    if (curIndex < realIndices.Size())
      if (realIndices[curIndex] == i)
      {
        curIndex++;
        continue;
      }
    CUpdatePair2 up2;
    up2.NewData = up2.NewProps = false;
    up2.IsAnti = false; // check it. Maybe it can be undefined
    up2.ArcIndex = i;
    updatePairs.Add(up2);
  }
  updateCallbackSpec->UpdatePairs = &updatePairs;
  updateCallbackSpec->Archive = GetArchive();
  updateCallbackSpec->Callback = &updateCallbackAgent;
  return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
}

HRESULT CAgent::CreateFolder(
    const wchar_t *newArchiveName,
    const wchar_t *folderName,
    IFolderArchiveUpdateCallback *updateCallback100)
{
  if (!CanUpdate())
    return E_NOTIMPL;
  CUpdateCallbackAgent updateCallbackAgent;
  updateCallbackAgent.SetCallback(updateCallback100);
  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);

  CRecordVector<CUpdatePair2> updatePairs;
  UInt32 numItemsInArchive;
  RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
  for (UInt32 i = 0; i < numItemsInArchive; i++)
  {
    CUpdatePair2 up2;
    up2.NewData = up2.NewProps = false;
    up2.IsAnti = false;  // check it.
    up2.ArcIndex = i;
    updatePairs.Add(up2);
  }
  CUpdatePair2 up2;
  up2.NewData = up2.NewProps = true;
  up2.IsAnti = false;
  up2.DirIndex = 0;

  updatePairs.Add(up2);

  updatePairs.ReserveDown();

  CDirItems dirItems;
  CDirItem di;

  di.Attrib = FILE_ATTRIBUTE_DIRECTORY;
  di.Size = 0;
  di.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName;

  FILETIME ft;
  NTime::GetCurUtcFileTime(ft);
  di.CTime = di.ATime = di.MTime = ft;

  dirItems.Items.Add(di);

  updateCallbackSpec->Callback = &updateCallbackAgent;
  updateCallbackSpec->DirItems = &dirItems;
  updateCallbackSpec->UpdatePairs = &updatePairs;
  updateCallbackSpec->Archive = GetArchive();
  return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
}


HRESULT CAgent::RenameItem(
    const wchar_t *newArchiveName,
    const UInt32 *indices, UInt32 numItems,
    const wchar_t *newItemName,
    IFolderArchiveUpdateCallback *updateCallback100)
{
  if (!CanUpdate())
    return E_NOTIMPL;
  if (numItems != 1)
    return E_INVALIDARG;
  CUpdateCallbackAgent updateCallbackAgent;
  updateCallbackAgent.SetCallback(updateCallback100);
  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
  
  CUIntVector realIndices;
  _agentFolder->GetRealIndices(indices, numItems, realIndices);

  UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]);
  UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
  UString newItemPath = fullPrefix + newItemName;

  CRecordVector<CUpdatePair2> updatePairs;
  UStringVector newNames;

  int curIndex = 0;
  UInt32 numItemsInArchive;
  RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
  for (UInt32 i = 0; i < numItemsInArchive; i++)
  {
    if (curIndex < realIndices.Size())
      if (realIndices[curIndex] == i)
      {
        CUpdatePair2 up2;
        up2.NewData = false;
        up2.NewProps = true;
        RINOK(IsArchiveItemAnti(GetArchive(), i, up2.IsAnti));
        up2.ArcIndex = i;

        UString oldFullPath;
        RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath));

        if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0)
          return E_INVALIDARG;

        up2.NewNameIndex = newNames.Add(newItemPath + oldFullPath.Mid(oldItemPath.Length()));
        updatePairs.Add(up2);
        curIndex++;
        continue;
      }
    CUpdatePair2 up2;
    up2.NewData = up2.NewProps = false;
    up2.IsAnti = false;
    up2.ArcIndex = i;
    updatePairs.Add(up2);
  }
  updateCallbackSpec->Callback = &updateCallbackAgent;
  updateCallbackSpec->UpdatePairs = &updatePairs;
  updateCallbackSpec->NewNames = &newNames;
  updateCallbackSpec->Archive = GetArchive();
  return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
}

STDMETHODIMP CAgent::SetProperties(const wchar_t **names,
    const PROPVARIANT *values, INT32 numProperties)
{
  m_PropNames.Clear();
  m_PropValues.Clear();
  for (int i = 0; i < numProperties; i++)
  {
    m_PropNames.Add(names[i]);
    m_PropValues.Add(values[i]);
  }
  return S_OK;
}

⌨️ 快捷键说明

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