Пример #1
0
void CInArchive::GetNextFolderItem(CFolder &folder)
{
  CNum numCoders = ReadNum();

  folder.Coders.Clear();
  folder.Coders.Reserve((int)numCoders);
  CNum numInStreams = 0;
  CNum numOutStreams = 0;
  CNum i;
  for (i = 0; i < numCoders; i++)
  {
    folder.Coders.Add(CCoderInfo());
    CCoderInfo &coder = folder.Coders.Back();

    {
      Byte mainByte = ReadByte();
      int idSize = (mainByte & 0xF);
      Byte longID[15];
      ReadBytes(longID, idSize);
      if (idSize > 8)
        ThrowUnsupported();
      UInt64 id = 0;
      for (int j = 0; j < idSize; j++)
        id |= (UInt64)longID[idSize - 1 - j] << (8 * j);
      coder.MethodID = id;

      if ((mainByte & 0x10) != 0)
      {
        coder.NumInStreams = ReadNum();
        coder.NumOutStreams = ReadNum();
      }
      else
      {
        coder.NumInStreams = 1;
        coder.NumOutStreams = 1;
      }
      if ((mainByte & 0x20) != 0)
      {
        CNum propsSize = ReadNum();
        coder.Props.SetCapacity((size_t)propsSize);
        ReadBytes((Byte *)coder.Props, (size_t)propsSize);
      }
      if ((mainByte & 0x80) != 0)
        ThrowUnsupported();
    }
    numInStreams += coder.NumInStreams;
    numOutStreams += coder.NumOutStreams;
  }

  CNum numBindPairs = numOutStreams - 1;
  folder.BindPairs.Clear();
  folder.BindPairs.Reserve(numBindPairs);
  for (i = 0; i < numBindPairs; i++)
  {
    CBindPair bp;
    bp.InIndex = ReadNum();
    bp.OutIndex = ReadNum();
    folder.BindPairs.Add(bp);
  }

  if (numInStreams < numBindPairs)
    ThrowUnsupported();
  CNum numPackStreams = numInStreams - numBindPairs;
  folder.PackStreams.Reserve(numPackStreams);
  if (numPackStreams == 1)
  {
    for (i = 0; i < numInStreams; i++)
      if (folder.FindBindPairForInStream(i) < 0)
      {
        folder.PackStreams.Add(i);
        break;
      }
    if (folder.PackStreams.Size() != 1)
      ThrowUnsupported();
  }
  else
    for (i = 0; i < numPackStreams; i++)
      folder.PackStreams.Add(ReadNum());
}
Пример #2
0
HRESULT CEncoder::CreateMixerCoder(
    DECL_EXTERNAL_CODECS_LOC_VARS
    const UInt64 *inSizeForReduce)
{
  _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
  _mixerCoder = _mixerCoderSpec;
  RINOK(_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();
    encodingInfo.MethodID = methodFull.Id;
    CMyComPtr<ICompressCoder> encoder;
    CMyComPtr<ICompressCoder2> encoder2;
    

    RINOK(CreateCoder(
        EXTERNAL_CODECS_LOC_VARS
        methodFull.Id, encoder, encoder2, true));

    if (!encoder && !encoder2)
      return E_FAIL;

    CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
   
    #ifndef _7ZIP_ST
    {
      CMyComPtr<ICompressSetCoderMt> setCoderMt;
      encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
      if (setCoderMt)
      {
        RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
      }
    }
    #endif


    RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));

    /*
    CMyComPtr<ICryptoResetSalt> resetSalt;
    encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
    if (resetSalt != NULL)
    {
      resetSalt->ResetSalt();
    }
    */

    #ifdef EXTERNAL_CODECS
    CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
    encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
    if (setCompressCodecsInfo)
    {
      RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
    }
    #endif
    
    CMyComPtr<ICryptoSetPassword> cryptoSetPassword = new CCryptoSetPassword;
    encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);

    if (cryptoSetPassword)
    {
	  UString & password = _options.Password;
	  /*
      const UInt32 sizeInBytes = (_options.Password.Length()+1) * 2;
	  
	  CByteBuffer buffer;
      buffer.SetCapacity(sizeInBytes);

	  parallel::_for( 0,password.Length(), 
		  [&buffer, &password]( int i, bool & breakFlag )
		  {
			  if( breakFlag )
				  return;

			  wchar_t c = password[i];
			  ((Byte *)buffer)[i * 2] = (Byte)c;
			  ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
		  }
		  , 4
	  );

	  buffer[sizeInBytes-1] = 0;
	  buffer[sizeInBytes-2] = 0;

	  RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes-2));
	  */
	  RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)(&_options.Password[0]), password.Length()*2));
    }

    if (encoder)
      _mixerCoderSpec->AddCoder(encoder);
    else
      _mixerCoderSpec->AddCoder2(encoder2);
  }
  return S_OK;
}