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

📄 7zencode.cpp

📁 压缩软件源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Encode.cpp

#include "StdAfx.h"

#include "7zEncode.h"
#include "7zSpecStream.h"
#include "7zMethods.h"

#include "../../IPassword.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/InOutTempBuffer.h"
#include "../../Common/StreamObjects.h"
#include "../Common/FilterCoder.h"

#ifdef COMPRESS_COPY
static NArchive::N7z::CMethodID k_Copy = { { 0x0 }, 1 };
#include "../../Compress/Copy/CopyCoder.h"
#endif

#ifdef COMPRESS_LZMA
#include "../../Compress/LZMA/LZMAEncoder.h"
static NArchive::N7z::CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
#endif

#ifdef COMPRESS_PPMD
#include "../../Compress/PPMD/PPMDEncoder.h"
static NArchive::N7z::CMethodID k_PPMD = { { 0x3, 0x4, 0x1 }, 3 };
#endif

#ifdef COMPRESS_BCJ_X86
static NArchive::N7z::CMethodID k_BCJ_X86 = { { 0x3, 0x3, 0x1, 0x3 }, 4 };
#include "../../Compress/Branch/x86.h"
#endif

#ifdef COMPRESS_BCJ2
static NArchive::N7z::CMethodID k_BCJ2 = { { 0x3, 0x3, 0x1, 0x1B }, 4 };
#include "../../Compress/Branch/x86_2.h"
#endif

#ifdef COMPRESS_DEFLATE
#ifndef COMPRESS_DEFLATE_ENCODER
#define COMPRESS_DEFLATE_ENCODER
#endif
#endif

#ifdef COMPRESS_DEFLATE_ENCODER
#include "../../Compress/Deflate/DeflateEncoder.h"
static NArchive::N7z::CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
#endif

#ifdef COMPRESS_BZIP2
#ifndef COMPRESS_BZIP2_ENCODER
#define COMPRESS_BZIP2_ENCODER
#endif
#endif

#ifdef COMPRESS_BZIP2_ENCODER
#include "../../Compress/BZip2/BZip2Encoder.h"
static NArchive::N7z::CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
#endif

static NArchive::N7z::CMethodID k_AES = { { 0x6, 0xF1, 0x7, 0x1}, 4 };

#ifndef EXCLUDE_COM
static const wchar_t *kCryproMethod = L"7zAES";
/*
// {23170F69-40C1-278B-06F1-070100000100}
DEFINE_GUID(CLSID_CCrypto7zAESEncoder, 
0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x07, 0x01, 0x00, 0x00, 0x01, 0x00);
*/
#endif

#ifdef CRYPTO_7ZAES
#include "../../Crypto/7zAES/7zAES.h"
#endif

namespace NArchive {
namespace N7z {

static void ConvertBindInfoToFolderItemInfo(const NCoderMixer2::CBindInfo &bindInfo,
    const CRecordVector<CMethodID> decompressionMethods,
    CFolder &folder)
{
  folder.Coders.Clear();
  // bindInfo.CoderMethodIDs.Clear();
  // folder.OutStreams.Clear();
  folder.PackStreams.Clear();
  folder.BindPairs.Clear();
  int i;
  for (i = 0; i < bindInfo.BindPairs.Size(); i++)
  {
    CBindPair bindPair;
    bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
    bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
    folder.BindPairs.Add(bindPair);
  }
  for (i = 0; i < bindInfo.Coders.Size(); i++)
  {
    CCoderInfo coderInfo;
    const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
    coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
    coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
    
    // coderInfo.MethodID = decompressionMethods[i];
    // if (coderInfo.AltCoders.Size() == 0)
    coderInfo.AltCoders.Add(CAltCoderInfo());
    CAltCoderInfo &altCoderInfo = coderInfo.AltCoders.Front();
    altCoderInfo.MethodID = decompressionMethods[i];

    folder.Coders.Add(coderInfo);
  }
  for (i = 0; i < bindInfo.InStreams.Size(); i++)
    folder.PackStreams.Add(bindInfo.InStreams[i]);
}

HRESULT CEncoder::CreateMixerCoder()
{
  _mixerCoderSpec = new NCoderMixer2::CCoderMixer2MT;
  _mixerCoder = _mixerCoderSpec;
  _mixerCoderSpec->SetBindInfo(_bindInfo);
  for (int i = 0; i < _options.Methods.Size(); i++)
  {
    const CMethodFull &methodFull = _options.Methods[i];
    _codersInfo.Add(CCoderInfo());
    CCoderInfo &encodingInfo = _codersInfo.Back();
    CMyComPtr<ICompressCoder> encoder;
    CMyComPtr<ICompressFilter> filter;
    CMyComPtr<ICompressCoder2> encoder2;
    
    if (methodFull.IsSimpleCoder())
    {
      #ifdef COMPRESS_LZMA
      if (methodFull.MethodID == k_LZMA)
        encoder = new NCompress::NLZMA::CEncoder;
      #endif
      
      #ifdef COMPRESS_PPMD
      if (methodFull.MethodID == k_PPMD)
        encoder = new NCompress::NPPMD::CEncoder;
      #endif
      
      #ifdef COMPRESS_BCJ_X86
      if (methodFull.MethodID == k_BCJ_X86)
        filter = new CBCJ_x86_Encoder;
      #endif
      
      #ifdef COMPRESS_COPY
      if (methodFull.MethodID == k_Copy)
        encoder = new NCompress::CCopyCoder;
      #endif
      
      #ifdef COMPRESS_BZIP2_ENCODER
      if (methodFull.MethodID == k_BZip2)
        encoder = new NCompress::NBZip2::CEncoder;
      #endif
      
      #ifdef COMPRESS_DEFLATE_ENCODER
      if (methodFull.MethodID == k_Deflate)
        encoder = new NCompress::NDeflate::NEncoder::CCOMCoder;
      #endif
      
      #ifdef CRYPTO_7ZAES
      if (methodFull.MethodID == k_AES)
        filter = new NCrypto::NSevenZ::CEncoder;
      #endif

      if (filter)
      {
        CFilterCoder *coderSpec = new CFilterCoder;
        encoder = coderSpec;
        coderSpec->Filter = filter;
      }

      #ifndef EXCLUDE_COM
      if (encoder == 0)
      {
        RINOK(_libraries.CreateCoderSpec(methodFull.FilePath, 
              methodFull.EncoderClassID, &encoder));
      }
      #endif
      
      if (encoder == 0)
        return E_FAIL;
      
    }
    else
    {
      #ifdef COMPRESS_BCJ2
      if (methodFull.MethodID == k_BCJ2)
        encoder2 = new CBCJ2_x86_Encoder;
      #endif
      
      #ifndef EXCLUDE_COM
      if (encoder2 == 0)
      {
        RINOK(_libraries.CreateCoder2(methodFull.FilePath, 
              methodFull.EncoderClassID, &encoder2));
      }
      #else
      
      if (encoder2 == 0)
        return E_FAIL;
      #endif
    }
    
    if (methodFull.CoderProperties.Size() > 0)
    {
      CRecordVector<PROPID> propIDs;
      int numProperties = methodFull.CoderProperties.Size();
      NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
      try
      {
        for (int i = 0; i < numProperties; i++)
        {
          const CProperty &property = methodFull.CoderProperties[i];
          propIDs.Add(property.PropID);
          values[i] = property.Value;
        }
        CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
        if (methodFull.IsSimpleCoder())
        {
          RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, 
            &setCoderProperties));
        }
        else
        {
          RINOK(encoder2.QueryInterface(IID_ICompressSetCoderProperties, 
            &setCoderProperties));
        }
        RINOK(setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties));
      }
      catch(...)
      {
        delete []values;
        throw;
      }
      delete []values;
    }
    
    CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
    
    if (methodFull.IsSimpleCoder())
    {
      encoder.QueryInterface(IID_ICompressWriteCoderProperties, 
          &writeCoderProperties);
    }
    else
    {
      encoder2.QueryInterface(IID_ICompressWriteCoderProperties, 
          &writeCoderProperties);
    }
    
    if (writeCoderProperties != NULL)
    {
      CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
      CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
      outStreamSpec->Init();
      writeCoderProperties->WriteCoderProperties(outStream);
      
      size_t size = outStreamSpec->GetSize();
      
      // encodingInfo.Properties.SetCapacity(size);
      if (encodingInfo.AltCoders.Size() == 0)
        encodingInfo.AltCoders.Add(CAltCoderInfo());
      CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front();
      altCoderInfo.Properties.SetCapacity(size);
      
      memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size);
    }
    
    CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
    if (methodFull.IsSimpleCoder())
    {
      encoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
    }
    else
    {
      encoder2.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
    }

    if (cryptoSetPassword)
    {
      CByteBuffer buffer;
      const UInt32 sizeInBytes = _options.Password.Length() * 2;
      buffer.SetCapacity(sizeInBytes);
      for (int i = 0; i < _options.Password.Length(); i++)
      {
        wchar_t c = _options.Password[i];
        ((Byte *)buffer)[i * 2] = (Byte)c;
        ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
      }
      RINOK(cryptoSetPassword->CryptoSetPassword(
        (const Byte *)buffer, sizeInBytes));
    }

    // public ICompressWriteCoderProperties,
    if (methodFull.IsSimpleCoder())
    {
      _mixerCoderSpec->AddCoder(encoder);
    }
    else

⌨️ 快捷键说明

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