Exemple #1
1
bool LZMADecodeFile ( const char *fromFile, const char *toFile, CProgressInfo7Zip *progress )
{
	CMyComPtr<ISequentialInStream> inStream;
	CInFileStream *inStreamSpec = new CInFileStream;
	inStream = inStreamSpec;

	if ( !inStreamSpec->Open ( GetSystemString(fromFile) ) )
		return false;

	CMyComPtr<ISequentialOutStream> outStream;
	COutFileStream *outStreamSpec = new COutFileStream;
	outStream = outStreamSpec;
	if ( !outStreamSpec->Create ( GetSystemString(toFile), true ) )
		return false;


	NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;

	CMyComPtr<ICompressCoder> decoder = decoderSpec;

	const UInt32 kPropertiesSize = 5;
	Byte properties[kPropertiesSize];
	UInt32 processedSize;
	
	if ( ReadStream (inStream, properties, kPropertiesSize, &processedSize) != S_OK )
		return false;

	if ( processedSize != kPropertiesSize )
		return false;

	if ( decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK )
		return false;

	UInt64 fileSize = 0;
	for (int i = 0; i < 8; i++)
	{
	  Byte b;
	  if ( inStream->Read(&b, 1, &processedSize) != S_OK )
		  return false;

	  if ( processedSize != 1 )
		  return false;
	  fileSize |= ((UInt64)b) << (8 * i);
	}

	if ( progress )
	{
		progress->Init();
		progress->ApprovedStart = 1 << 21;
		progress->SetMax ( fileSize );
	}

	if ( decoder->Code(inStream, outStream, 0, &fileSize, progress) != S_OK )
		// decoder error
		return false;

	return true;
}
Exemple #2
0
HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback)
{
  CInFileStream *inStreamSpec = new CInFileStream;
  CMyComPtr<IInStream> inStream(inStreamSpec);
  inStreamSpec->Open(fileName);
  return archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
}
Exemple #3
0
HRESULT CArc::OpenStreamOrFile(
    CCodecs *codecs,
    int formatIndex,
    bool stdInMode,
    IInStream *stream,
    IArchiveOpenCallback *callback)
{
  CMyComPtr<IInStream> fileStream;
  CMyComPtr<ISequentialInStream> seqStream;
  if (stdInMode)
    seqStream = new CStdInFileStream;
  else if (!stream)
  {
    CInFileStream *fileStreamSpec = new CInFileStream;
    fileStream = fileStreamSpec;
    if (!fileStreamSpec->Open(Path))
      return GetLastError();
    stream = fileStream;
  }

  /*
  if (callback)
  {
    UInt64 fileSize;
    RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
    RINOK(callback->SetTotal(NULL, &fileSize))
  }
  */

  return OpenStream(codecs, formatIndex, stream, seqStream, callback);
}
Exemple #4
0
STDMETHODIMP P7ZipArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
  RINOK(Finilize());

  const CDirItem &dirItem = (*DirItems)[index];
  GetStream2(dirItem.Name);
 
  if (dirItem.isDir())
    return S_OK;

  {
    CInFileStream *inStreamSpec = new CInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
    UString path = DirPrefix + dirItem.FullPath;
    if (!inStreamSpec->Open(path))
    {
      DWORD sysError = ::GetLastError();
      FailedCodes.Add(sysError);
      FailedFiles.Add(path);
      // if (systemError == ERROR_SHARING_VIOLATION)
      {
        PrintNewLine();
        PrintError("WARNING: can't open file");
        // PrintString(NError::MyFormatMessageW(systemError));
        return S_FALSE;
      }
      // return sysError;
    }
    *inStream = inStreamLoc.Detach();
  }
  return S_OK;
}
Exemple #5
0
int open_instream(const string infile,
		CMyComPtr<ISequentialInStream> &inStream,
		UInt64 &fileSize)
{
	CInFileStream *inStreamSpec = new CInFileStream;
	inStream = inStreamSpec;
	if (!inStreamSpec->Open(infile.c_str()))
		throw Exception("Cannot open input file " + infile);

	inStreamSpec->File.GetLength(fileSize);

	return inStreamSpec->File.GetHandle();
}
Exemple #6
0
HRESULT OpenArchive(
    CCodecs *codecs,
    const UString &filePath, 
    IInArchive **archiveResult, 
    int &formatIndex,
    UString &defaultItemName,
    IArchiveOpenCallback *openArchiveCallback)
{
  CInFileStream *inStreamSpec = new CInFileStream;
  CMyComPtr<IInStream> inStream(inStreamSpec);
  if (!inStreamSpec->Open(filePath))
    return GetLastError();
  return OpenArchive(codecs, inStream, ExtractFileNameFromPath(filePath),
    archiveResult, formatIndex,
    defaultItemName, openArchiveCallback);
}
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
  COM_TRY_BEGIN
  const CUpdatePair2 &up = (*UpdatePairs)[index];
  if (!up.NewData)
    return E_FAIL;
  
  RINOK(Callback->CheckBreak());
  RINOK(Callback->Finilize());

  if (up.IsAnti)
  {
    return Callback->GetStream((*ArcItems)[up.ArcIndex].Name, true);
  }
  const CDirItem &di = DirItems->Items[up.DirIndex];
//  RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), false));	// 削除
 
  /* 追加ここから */
  UString strLogPath = DirItems->GetLogPath(up.DirIndex);
  RINOK(Callback->GetStream(strLogPath, false));
  g_StdOut.GetProgressDialog()->AddWorkFile(strLogPath, strLogPath, di.Attrib, false, di.MTime, di.Size, 0, 0, L"");
  /* 追加ここまで */

  if (di.IsDir())
    return S_OK;

  if (StdInMode)
  {
    CStdInFileStream *inStreamSpec = new CStdInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
    *inStream = inStreamLoc.Detach();
  }
  else
  {
    CInFileStream *inStreamSpec = new CInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
    const UString path = DirItems->GetPhyPath(up.DirIndex);
    if (!inStreamSpec->OpenShared(us2fs(path), ShareForWrite))
    {
      return Callback->OpenFileError(path, ::GetLastError());
    }
    *inStream = inStreamLoc.Detach();
  }
  return S_OK;
  COM_TRY_END
}
Exemple #8
0
HRESULT CArchiveLink::ReOpen(CCodecs *codecs, const UString &filePath,
    IArchiveOpenCallback *callback)
{
  if (Arcs.Size() > 1)
    return E_NOTIMPL;

  if (Arcs.Size() == 0)
    return Open2(codecs, CIntVector(), false, NULL, filePath, 0);

  CMyComPtr<IArchiveOpenCallback> openCallbackNew;
  SetCallback(filePath, NULL, callback, openCallbackNew);

  CInFileStream *fileStreamSpec = new CInFileStream;
  CMyComPtr<IInStream> stream(fileStreamSpec);
  if (!fileStreamSpec->Open(filePath))
    return GetLastError();
  HRESULT res = GetArchive()->Open(stream, &kMaxCheckStartPosition, callback);
  IsOpen = (res == S_OK);
  return res;
}
Exemple #9
0
bool vms7zipArchive::Extract(LPCSTR pszArchive, LPCSTR pszOutFolder)
{
	CInFileStream *fileSpec = new CInFileStream;
	CMyComPtr <IInStream> spFile = fileSpec;

	m_errExtract = AEE_GENERIC_ERROR;

	if (false == fileSpec->Open(pszArchive))
		return false;

	CMyComPtr <IInArchive> spArc;

	vms7zipFormatDLL dll;
	if (false == Find7zipDLL (dll, pszArchive, true, spFile, spArc) &&
			false == Find7zipDLL (dll, pszArchive, false, spFile, spArc))
		return false;

	m_errExtract = AEE_NO_ERROR;

	char sz [MY_MAX_PATH];
	fsGetFileName (pszArchive, sz);

	vms7zipArchiveExtractCallback aec (spArc, pszOutFolder, m_pAC, sz);
	HRESULT hr;
	if (FAILED (hr=spArc->Extract (NULL, (UInt32)-1, 0, &aec))) {
		spArc = NULL;
		m_errExtract = aec.is_AbortedByUser () ? AEE_ABORTED_BY_USER : AEE_GENERIC_ERROR;
		return false;
	}

	spArc = NULL;

	if (*aec.get_FurtherExtractFile () != 0) {
		
		bool b = Extract (aec.get_FurtherExtractFile (), pszOutFolder);
		DeleteFile (aec.get_FurtherExtractFile ());
		return b;
	}

	return true;
}
Exemple #10
0
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
  COM_TRY_BEGIN
  const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
  if(!updatePair.NewData)
	return E_FAIL;
  
  RINOK(Callback->CheckBreak());
  RINOK(Callback->Finilize());

  if(updatePair.IsAnti)
  {
	return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
  }
  const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
  RINOK(Callback->GetStream(dirItem.Name, false));
 
  if(dirItem.IsDirectory())
	return S_OK;

  if (StdInMode)
  {
	CStdInFileStream *inStreamSpec = new CStdInFileStream;
	CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
	*inStream = inStreamLoc.Detach();
  }
  else
  {
	CInFileStream *inStreamSpec = new CInFileStream;
	CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
	UString path = DirPrefix + dirItem.FullPath;
	if(!inStreamSpec->OpenShared(path, ShareForWrite))
	{
	  return Callback->OpenFileError(path, ::GetLastError());
	}
	*inStream = inStreamLoc.Detach();
  }
  return S_OK;
  COM_TRY_END
}
Exemple #11
0
STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **inStream)
{
  COM_TRY_BEGIN
  *inStream = NULL;
  if (_subArchiveMode)
    return S_FALSE;

  FString fullPath;
  if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath))
    return S_FALSE;
  if (!_fileInfo.Find(fullPath))
    return S_FALSE;
  if (_fileInfo.IsDir())
    return S_FALSE;
  CInFileStream *inFile = new CInFileStream;
  CMyComPtr<IInStream> inStreamTemp = inFile;
  if (!inFile->Open(fullPath))
    return ::GetLastError();
  *inStream = inStreamTemp.Detach();
  return S_OK;
  COM_TRY_END
}
Exemple #12
0
STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name,
    IInStream **inStream)
{
  *inStream = NULL;
  if (_subArchiveMode)
    return S_FALSE;

  NWindows::NFile::NFind::CFileInfoW fileInfo;

  UString fullPath = _folderPrefix + name;
  if (!NWindows::NFile::NFind::FindFile(fullPath, fileInfo))
    return S_FALSE;
  _fileInfo = fileInfo;
  if (_fileInfo.IsDir())
    return S_FALSE;
  CInFileStream *inFile = new CInFileStream;
  CMyComPtr<IInStream> inStreamTemp = inFile;
  if (!inFile->Open(fullPath))
    return ::GetLastError();
  *inStream = inStreamTemp.Detach();
  return S_OK;
}
HRESULT CArc::OpenStreamOrFile(
    CCodecs *codecs,
    int formatIndex,
    bool stdInMode,
    IInStream *stream,
    IArchiveOpenCallback *callback)
{
  CMyComPtr<IInStream> fileStream;
  CMyComPtr<ISequentialInStream> seqStream;
  if (stdInMode)
    seqStream = new CStdInFileStream;
  else if (!stream)
  {
    CInFileStream *fileStreamSpec = new CInFileStream(true);
    fileStream = fileStreamSpec;
    if (!fileStreamSpec->Open(Path))
      return GetLastError();
    stream = fileStream;
  }

  return OpenStream(codecs, formatIndex, stream, seqStream, callback);
}
Exemple #14
0
int main2(int n, const char *args[])
{
  #ifdef _WIN32
  g_IsNT = IsItWindowsNT();
  #endif

  fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");

  if (n == 1)
  {
	PrintHelp();
	return 0;
  }

  bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
  if (unsupportedTypes)
  {
	fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
	return 1;
  }   

  UStringVector commandStrings;
  WriteArgumentsToStringList(n, args, commandStrings);
  CParser parser(kNumSwitches);
  try
  {
	parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...) 
  {
	IncorrectCommand();
  }

  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
	PrintHelp();
	return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int paramIndex = 0;
  if (paramIndex >= nonSwitchStrings.Size())
	IncorrectCommand();
  const UString &command = nonSwitchStrings[paramIndex++]; 

  bool dictionaryIsDefined = false;
  UInt32 dictionary = (UInt32)-1;
  if(parser[NKey::kDictionary].ThereIs)
  {
	UInt32 dicLog;
	if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
	  IncorrectCommand();
	dictionary = 1 << dicLog;
	dictionaryIsDefined = true;
  }
  UString mf = L"BT4";
  if (parser[NKey::kMatchFinder].ThereIs)
	mf = parser[NKey::kMatchFinder].PostStrings[0];

  UInt32 numThreads = (UInt32)-1;

  #ifdef COMPRESS_MF_MT
  if (parser[NKey::kMultiThread].ThereIs)
  {
	UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
	const UString &s = parser[NKey::kMultiThread].PostStrings[0];
	if (s.IsEmpty())
	  numThreads = numCPUs;
	else
	  if (!GetNumber(s, numThreads))
		IncorrectCommand();
  }
  #endif

  if (command.CompareNoCase(L"b") == 0)
  {
	const UInt32 kNumDefaultItereations = 1;
	UInt32 numIterations = kNumDefaultItereations;
	{
	  if (paramIndex < nonSwitchStrings.Size())
		if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
		  numIterations = kNumDefaultItereations;
	}
	return LzmaBenchCon(stderr, numIterations, numThreads, dictionary);
  }

  if (numThreads == (UInt32)-1)
	numThreads = 1;

  bool encodeMode = false;
  if (command.CompareNoCase(L"e") == 0)
	encodeMode = true;
  else if (command.CompareNoCase(L"d") == 0)
	encodeMode = false;
  else
	IncorrectCommand();

  bool stdInMode = parser[NKey::kStdIn].ThereIs;
  bool stdOutMode = parser[NKey::kStdOut].ThereIs;

  CMyComPtr<ISequentialInStream> inStream;
  CInFileStream *inStreamSpec = 0;
  if (stdInMode)
  {
	inStream = new CStdInFileStream;
	MY_SET_BINARY_MODE(stdin);
  }
  else
  {
	if (paramIndex >= nonSwitchStrings.Size())
	  IncorrectCommand();
	const UString &inputName = nonSwitchStrings[paramIndex++]; 
	inStreamSpec = new CInFileStream;
	inStream = inStreamSpec;
	if (!inStreamSpec->Open(GetSystemString(inputName)))
	{
	  fprintf(stderr, "\nError: can not open input file %s\n", 
		  (const char *)GetOemString(inputName));
	  return 1;
	}
  }

  CMyComPtr<ISequentialOutStream> outStream;
  COutFileStream *outStreamSpec = NULL;
  if (stdOutMode)
  {
	outStream = new CStdOutFileStream;
	MY_SET_BINARY_MODE(stdout);
  }
  else
  {
	if (paramIndex >= nonSwitchStrings.Size())
	  IncorrectCommand();
	const UString &outputName = nonSwitchStrings[paramIndex++]; 
	outStreamSpec = new COutFileStream;
	outStream = outStreamSpec;
	if (!outStreamSpec->Create(GetSystemString(outputName), true))
	{
	  fprintf(stderr, "\nError: can not open output file %s\n", 
		(const char *)GetOemString(outputName));
	  return 1;
	}
  }

  if (parser[NKey::kFilter86].ThereIs)
  {
	// -f86 switch is for x86 filtered mode: BCJ + LZMA.
	if (parser[NKey::kEOS].ThereIs || stdInMode)
	  throw "Can not use stdin in this mode";
	UInt64 fileSize;
	inStreamSpec->File.GetLength(fileSize);
	if (fileSize > 0xF0000000)
	  throw "File is too big";
	UInt32 inSize = (UInt32)fileSize;
	Byte *inBuffer = 0;
	if (inSize != 0)
	{
	  inBuffer = (Byte *)MyAlloc((size_t)inSize); 
	  if (inBuffer == 0)
		throw kCantAllocate;
	}
	
	UInt32 processedSize;
	if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK)
	  throw "Can not read";
	if ((UInt32)inSize != processedSize)
	  throw "Read size error";

	Byte *outBuffer = 0;
	size_t outSizeProcessed;
	if (encodeMode)
	{
	  // we allocate 105% of original size for output buffer
	  size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
	  if (outSize != 0)
	  {
		outBuffer = (Byte *)MyAlloc((size_t)outSize); 
		if (outBuffer == 0)
		  throw kCantAllocate;
	  }
	  if (!dictionaryIsDefined)
		dictionary = 1 << 23;
	  int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, 
		  dictionary, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
	  if (res != 0)
	  {
		fprintf(stderr, "\nEncoder error = %d\n", (int)res);
		return 1;
	  }
	}
	else
	{
	  size_t outSize;
	  if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
		throw "data error";
	  if (outSize != 0)
	  {
		outBuffer = (Byte *)MyAlloc(outSize); 
		if (outBuffer == 0)
		  throw kCantAllocate;
	  }
	  int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
	  if (res != 0)
		throw "LzmaDecoder error";
	}
	if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
	  throw kWriteError;
	MyFree(outBuffer);
	MyFree(inBuffer);
	return 0;
  }


  UInt64 fileSize;
  if (encodeMode)
  {
	NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
	CMyComPtr<ICompressCoder> encoder = encoderSpec;

	if (!dictionaryIsDefined)
	  dictionary = 1 << 23;

	UInt32 posStateBits = 2;
	UInt32 litContextBits = 3; // for normal files
	// UInt32 litContextBits = 0; // for 32-bit data
	UInt32 litPosBits = 0;
	// UInt32 litPosBits = 2; // for 32-bit data
	UInt32 algorithm = 1;
	UInt32 numFastBytes = 128;
	UInt32 matchFinderCycles = 16 + numFastBytes / 2;
	bool matchFinderCyclesDefined = false;

	bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
 
	if(parser[NKey::kMode].ThereIs)
	  if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
		IncorrectCommand();

	if(parser[NKey::kFastBytes].ThereIs)
	  if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
		IncorrectCommand();
	matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs;
	if (matchFinderCyclesDefined)
	  if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles))
		IncorrectCommand();
	if(parser[NKey::kLitContext].ThereIs)
	  if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
		IncorrectCommand();
	if(parser[NKey::kLitPos].ThereIs)
	  if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
		IncorrectCommand();
	if(parser[NKey::kPosBits].ThereIs)
	  if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
		IncorrectCommand();

	PROPID propIDs[] = 
	{
	  NCoderPropID::kDictionarySize,
	  NCoderPropID::kPosStateBits,
	  NCoderPropID::kLitContextBits,
	  NCoderPropID::kLitPosBits,
	  NCoderPropID::kAlgorithm,
	  NCoderPropID::kNumFastBytes,
	  NCoderPropID::kMatchFinder,
	  NCoderPropID::kEndMarker,
	  NCoderPropID::kNumThreads,
	  NCoderPropID::kMatchFinderCycles,
	};
	const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);

	PROPVARIANT properties[kNumPropsMax];
	for (int p = 0; p < 6; p++)
	  properties[p].vt = VT_UI4;

	properties[0].ulVal = (UInt32)dictionary;
	properties[1].ulVal = (UInt32)posStateBits;
	properties[2].ulVal = (UInt32)litContextBits;
	properties[3].ulVal = (UInt32)litPosBits;
	properties[4].ulVal = (UInt32)algorithm;
	properties[5].ulVal = (UInt32)numFastBytes;

	properties[6].vt = VT_BSTR;
	properties[6].bstrVal = (BSTR)(const wchar_t *)mf;

	properties[7].vt = VT_BOOL;
	properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;

	properties[8].vt = VT_UI4;
	properties[8].ulVal = (UInt32)numThreads;

	// it must be last in property list
	properties[9].vt = VT_UI4;
	properties[9].ulVal = (UInt32)matchFinderCycles;

	int numProps = kNumPropsMax;
	if (!matchFinderCyclesDefined)
	  numProps--;

	if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
	  IncorrectCommand();
	encoderSpec->WriteCoderProperties(outStream);

	if (eos || stdInMode)
	  fileSize = (UInt64)(Int64)-1;
	else
	  inStreamSpec->File.GetLength(fileSize);

	for (int i = 0; i < 8; i++)
	{
	  Byte b = Byte(fileSize >> (8 * i));
	  if (outStream->Write(&b, 1, 0) != S_OK)
	  {
		fprintf(stderr, kWriteError);
		return 1;
	  }
	}
	HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
	if (result == E_OUTOFMEMORY)
	{
	  fprintf(stderr, "\nError: Can not allocate memory\n");
	  return 1;
	}   
	else if (result != S_OK)
	{
	  fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
	  return 1;
	}   
  }
  else
  {
Exemple #15
0
STDMETHODIMP CAgent::DoOperation(
    CCodecs *codecs,
    int formatIndex,
    const wchar_t *newArchiveName,
    const Byte *stateActions,
    const wchar_t *sfxModule,
    IFolderArchiveUpdateCallback *updateCallback100)
{
  if (!CanUpdate())
    return E_NOTIMPL;
  NUpdateArchive::CActionSet actionSet;
  int i;
  for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
    actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i];

  CDirItems dirItems;

  {
    UString folderPrefix = _folderPrefix;
    NFile::NName::NormalizeDirPathPrefix(folderPrefix);
    UStringVector errorPaths;
    CRecordVector<DWORD> errorCodes;
    dirItems.EnumerateDirItems2(folderPrefix, _archiveNamePrefix, _names, errorPaths, errorCodes);
    if (errorCodes.Size() > 0)
      return errorCodes.Front();
  }

  CMyComPtr<IOutArchive> outArchive;
  if (GetArchive())
  {
    RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
  }
  else
  {
    if (formatIndex < 0)
      return E_FAIL;
    RINOK(codecs->CreateOutArchive(formatIndex, outArchive));
    #ifdef EXTERNAL_CODECS
    {
      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
      outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
      if (setCompressCodecsInfo)
      {
        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
      }
    }
    #endif

  }

  NFileTimeType::EEnum fileTimeType;
  UInt32 value;
  RINOK(outArchive->GetFileTimeType(&value));

  switch(value)
  {
    case NFileTimeType::kWindows:
    case NFileTimeType::kDOS:
    case NFileTimeType::kUnix:
      fileTimeType = NFileTimeType::EEnum(value);
      break;
    default:
      return E_FAIL;
  }


  CObjectVector<CArcItem> arcItems;
  if (GetArchive())
  {
    RINOK(ReadItems());
    EnumerateArchiveItems(this, _proxyArchive->RootFolder,  L"", arcItems);
  }

  CRecordVector<CUpdatePair2> updatePairs2;

  {
    CRecordVector<CUpdatePair> updatePairs;
    GetUpdatePairInfoList(dirItems, arcItems, fileTimeType, updatePairs);
    CAgUpCallbackImp upCallback(&arcItems, updateCallback100);
    UpdateProduce(updatePairs, actionSet, updatePairs2, &upCallback);
  }

  UInt32 numFiles = 0;
  for (i = 0; i < updatePairs2.Size(); i++)
    if (updatePairs2[i].NewData)
      numFiles++;
  
  if (updateCallback100)
  {
    RINOK(updateCallback100->SetNumFiles(numFiles));
  }
  
  CUpdateCallbackAgent updateCallbackAgent;
  updateCallbackAgent.SetCallback(updateCallback100);
  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec );

  updateCallbackSpec->DirItems = &dirItems;
  updateCallbackSpec->ArcItems = &arcItems;
  updateCallbackSpec->UpdatePairs = &updatePairs2;
  updateCallbackSpec->Archive = GetArchive();
  updateCallbackSpec->Callback = &updateCallbackAgent;

  COutFileStream *outStreamSpec = new COutFileStream;
  CMyComPtr<IOutStream> outStream(outStreamSpec);
  UString archiveName = newArchiveName;
  {
    UString resultPath;
    int pos;
    if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
      return E_FAIL;
    NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
  }
  if (!outStreamSpec->Create(archiveName, true))
  {
    // ShowLastErrorMessage();
    return E_FAIL;
  }
  
  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();
}
Exemple #16
0
bool LZMAEncodeFile ( const char *fromFile, const char *toFile, CProgressInfo7Zip *progress )
{
	bool eos = false;

	CMyComPtr<ISequentialInStream> inStream;
	CInFileStream *inStreamSpec = new CInFileStream;
	inStream = inStreamSpec;

	if ( !inStreamSpec->Open ( GetSystemString(fromFile) ) )
		return false;

	CMyComPtr<ISequentialOutStream> outStream;
	COutFileStream *outStreamSpec = new COutFileStream;
	outStream = outStreamSpec;
	if ( !outStreamSpec->Create ( GetSystemString(toFile), true ) )
		return false;

    NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
    CMyComPtr<ICompressCoder> encoder = encoderSpec;

	UInt32 dictionary = 1 << 21;
    UInt32 posStateBits = 2;
    UInt32 litContextBits = 3; // for normal files
    // UInt32 litContextBits = 0; // for 32-bit data
    UInt32 litPosBits = 0;
    // UInt32 litPosBits = 2; // for 32-bit data
    UInt32 algorithm = 2;
    UInt32 numFastBytes = 128;
    UInt32 matchFinderCycles = 16 + numFastBytes / 2;
    bool matchFinderCyclesDefined = false;

    //bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
 
    PROPID propIDs[] = 
    {
      NCoderPropID::kDictionarySize,
      NCoderPropID::kPosStateBits,
      NCoderPropID::kLitContextBits,
      NCoderPropID::kLitPosBits,
      NCoderPropID::kAlgorithm,
      NCoderPropID::kNumFastBytes,
      NCoderPropID::kMatchFinder,
      NCoderPropID::kEndMarker,
      NCoderPropID::kMatchFinderCycles
    };
    const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);

	UString mf = L"BT4";

    PROPVARIANT properties[kNumPropsMax];
    for (int p = 0; p < 6; p++)
      properties[p].vt = VT_UI4;

    properties[0].ulVal = UInt32(dictionary);
    properties[1].ulVal = UInt32(posStateBits);
    properties[2].ulVal = UInt32(litContextBits);
    properties[3].ulVal = UInt32(litPosBits);
    properties[4].ulVal = UInt32(algorithm);
    properties[5].ulVal = UInt32(numFastBytes);

    properties[8].vt = VT_UI4;
    properties[8].ulVal = UInt32(matchFinderCycles);
    
    properties[6].vt = VT_BSTR;
    properties[6].bstrVal = (BSTR)(const wchar_t *)mf;

    properties[7].vt = VT_BOOL;
    properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;

    int numProps = kNumPropsMax;
    if (!matchFinderCyclesDefined)
      numProps--;

    if ( encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK )
		return false;
    encoderSpec->WriteCoderProperties(outStream);

	UInt64 fileSize = 0;
    if ( eos )
      fileSize = (UInt64)(Int64)-1;
    else
      inStreamSpec->File.GetLength(fileSize);

    for (int i = 0; i < 8; i++)
    {
      Byte b = Byte(fileSize >> (8 * i));
      if (outStream->Write(&b, 1, 0) != S_OK)
		  return false;
    }

	if ( progress )
	{
		progress->Init();
		progress->SetMax ( fileSize );
		progress->ApprovedStart = 1 << 21;
		progress->SetIn ( true );
	}

    HRESULT result = encoder->Code(inStream, outStream, 0, 0, progress );
    if (result == E_OUTOFMEMORY)
		return false;

    else if (result != S_OK)
		return false;

	return true;
}
Exemple #17
0
STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
{
  COM_TRY_BEGIN
  *inStream = NULL;
  const CUpdatePair2 &up = (*UpdatePairs)[index];
  if (!up.NewData)
    return E_FAIL;
  
  RINOK(Callback->CheckBreak());
  // RINOK(Callback->Finalize());

  bool isDir = IsDir(up);

  if (up.IsAnti)
  {
    UString name;
    if (up.ArcIndex >= 0)
      name = (*ArcItems)[up.ArcIndex].Name;
    else if (up.DirIndex >= 0)
      name = DirItems->GetLogPath(up.DirIndex);
    RINOK(Callback->GetStream(name, isDir, true, mode));
    
    /* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
       so we return empty stream */

    if (!isDir)
    {
      CBufInStream *inStreamSpec = new CBufInStream();
      CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
      inStreamSpec->Init(NULL, 0);
      *inStream = inStreamLoc.Detach();
    }
    return S_OK;
  }
  
  RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), isDir, false, mode));
 
  if (isDir)
    return S_OK;

  if (StdInMode)
  {
    if (mode != NUpdateNotifyOp::kAdd &&
        mode != NUpdateNotifyOp::kUpdate)
      return S_OK;

    CStdInFileStream *inStreamSpec = new CStdInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
    *inStream = inStreamLoc.Detach();
  }
  else
  {
    CInFileStream *inStreamSpec = new CInFileStream;
    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);

    inStreamSpec->SupportHardLinks = StoreHardLinks;
    inStreamSpec->Callback = this;
    inStreamSpec->CallbackRef = index;

    const FString path = DirItems->GetPhyPath(up.DirIndex);
    _openFiles_Indexes.Add(index);
    _openFiles_Paths.Add(path);

    #if defined(_WIN32) && !defined(UNDER_CE)
    if (DirItems->Items[up.DirIndex].AreReparseData())
    {
      if (!inStreamSpec->File.OpenReparse(path))
      {
        return Callback->OpenFileError(path, ::GetLastError());
      }
    }
    else
    #endif
    if (!inStreamSpec->OpenShared(path, ShareForWrite))
    {
      DWORD error = ::GetLastError();
      HRESULT hres = Callback->OpenFileError(path, error);
      if (StopAfterOpenError)
        if (hres == S_OK || hres == S_FALSE)
          return HRESULT_FROM_WIN32(error);
      return hres;
    }

    if (StoreHardLinks)
    {
      CStreamFileProps props;
      if (inStreamSpec->GetProps2(&props) == S_OK)
      {
        if (props.NumLinks > 1)
        {
          CKeyKeyValPair pair;
          pair.Key1 = props.VolID;
          pair.Key2 = props.FileID_Low;
          pair.Value = index;
          unsigned numItems = _map.Size();
          unsigned pairIndex = _map.AddToUniqueSorted2(pair);
          if (numItems == _map.Size())
          {
            // const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
            _hardIndex_From = index;
            _hardIndex_To = pairIndex;
            // we could return NULL as stream, but it's better to return real stream
            // return S_OK;
          }
        }
      }
    }

    if (ProcessedItemsStatuses)
    {
      #ifndef _7ZIP_ST
      NSynchronization::CCriticalSectionLock lock(CS);
      #endif
      ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1;
    }
    *inStream = inStreamLoc.Detach();
  }
  
  return S_OK;
  COM_TRY_END
}
Exemple #18
0
int main2(int n, const char *args[])
{
	if (strcmp(args[n - 1], "-notitle") == 0)
		n--; 
	else {
		fprintf(stderr,
			"\nt5lzma 1.00 Copyright (C) 2004 H.Kawai\n"
			" --- based : LZMA 4.03 Copyright (c) 1999-2004 Igor Pavlov  2004-06-18\n"
		);
	}

  if (n == 1)
  {
    PrintHelp();
    return 0;
  }

  if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4)
  {
    fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
    return 1;
  }   

  UStringVector commandStrings;
  WriteArgumentsToStringList(n, args, commandStrings);
  CParser parser(kNumSwitches);
  try
  {
    parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...) 
  {
    IncorrectCommand();
  }

  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
    PrintHelp();
    return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int paramIndex = 0;
  if (paramIndex >= nonSwitchStrings.Size())
    IncorrectCommand();
  const UString &command = nonSwitchStrings[paramIndex++]; 

  if (command.CompareNoCase(L"b") == 0)
  {
    UInt32 dictionary = 1 << 21;
    if(parser[NKey::kDictionary].ThereIs)
    {
      UInt32 dicLog;
      if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
        IncorrectCommand();
      dictionary = 1 << dicLog;
    }
    const UInt32 kNumDefaultItereations = 10;
    UInt32 numIterations = kNumDefaultItereations;
    {
      if (paramIndex < nonSwitchStrings.Size())
        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
          numIterations = kNumDefaultItereations;
    }
    return LzmaBenchmark(numIterations, dictionary);
  }

  bool encodeMode;
  if (command.CompareNoCase(L"e") == 0)
    encodeMode = true;
  else if (command.CompareNoCase(L"d") == 0)
    encodeMode = false;
  else
    IncorrectCommand();

  bool stdInMode = parser[NKey::kStdIn].ThereIs;
  bool stdOutMode = parser[NKey::kStdOut].ThereIs;

  CMyComPtr<ISequentialInStream> inStream;
  CInFileStream *inStreamSpec = 0;
  if (stdInMode)
  {
    inStream = new CStdInFileStream;
    MY_SET_BINARY_MODE(stdin);
  }
  else
  {
    if (paramIndex >= nonSwitchStrings.Size())
      IncorrectCommand();
    const UString &inputName = nonSwitchStrings[paramIndex++]; 
    inStreamSpec = new CInFileStream;
    inStream = inStreamSpec;
    if (!inStreamSpec->Open(GetSystemString(inputName)))
    {
      fprintf(stderr, "\nError: can not open input file %s\n", 
          (const char *)GetOemString(inputName));
      return 1;
    }
  }

  CMyComPtr<ISequentialOutStream> outStream;
  if (stdOutMode)
  {
    outStream = new CStdOutFileStream;
    MY_SET_BINARY_MODE(stdout);
  }
  else
  {
    if (paramIndex >= nonSwitchStrings.Size())
      IncorrectCommand();
    const UString &outputName = nonSwitchStrings[paramIndex++]; 
    COutFileStream *outStreamSpec = new COutFileStream;
    outStream = outStreamSpec;
    if (!outStreamSpec->Open(GetSystemString(outputName)))
    {
      fprintf(stderr, "\nError: can not open output file %s\n", 
        (const char *)GetOemString(outputName));
      return 1;
    }
  }

  UInt64 fileSize;
  if (encodeMode)
  {
    NCompress::NLZMA::CEncoder *encoderSpec = 
      new NCompress::NLZMA::CEncoder;
    CMyComPtr<ICompressCoder> encoder = encoderSpec;

    UInt32 dictionary = 1 << 23;
    UInt32 posStateBits = 0;
    // UInt32 posStateBits = 2;
    // UInt32 litContextBits = 3; // for normal files
    UInt32 litContextBits = 0; // for 32-bit data
    UInt32 litPosBits = 0;
    // UInt32 litPosBits = 2; // for 32-bit data
    UInt32 algorithm = 2;
    UInt32 numFastBytes = 128;
    UString mf = L"BT4";

    bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
 
    if(parser[NKey::kMode].ThereIs)
      if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
        IncorrectCommand();

    if(parser[NKey::kDictionary].ThereIs)
    {
      UInt32 dicLog;
      if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
        IncorrectCommand();
      dictionary = 1 << dicLog;
    }
    if(parser[NKey::kFastBytes].ThereIs)
      if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
        IncorrectCommand();
    if(parser[NKey::kLitContext].ThereIs)
      if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
        IncorrectCommand();
    if(parser[NKey::kLitPos].ThereIs)
      if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
        IncorrectCommand();
    if(parser[NKey::kPosBits].ThereIs)
      if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
        IncorrectCommand();

    if (parser[NKey::kMatchFinder].ThereIs)
      mf = parser[NKey::kMatchFinder].PostStrings[0];

    PROPID propIDs[] = 
    {
      NCoderPropID::kDictionarySize,
      NCoderPropID::kPosStateBits,
      NCoderPropID::kLitContextBits,
      NCoderPropID::kLitPosBits,
      NCoderPropID::kAlgorithm,
      NCoderPropID::kNumFastBytes,
      NCoderPropID::kMatchFinder,
      NCoderPropID::kEndMarker
    };
    const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
    /*
    NWindows::NCOM::CPropVariant properties[kNumProps];
    properties[0] = UInt32(dictionary);
    properties[1] = UInt32(posStateBits);
    properties[2] = UInt32(litContextBits);
   
    properties[3] = UInt32(litPosBits);
    properties[4] = UInt32(algorithm);
    properties[5] = UInt32(numFastBytes);
    properties[6] = mf;
    properties[7] = eos;
    */
    PROPVARIANT properties[kNumProps];
    for (int p = 0; p < 6; p++)
      properties[p].vt = VT_UI4;
    properties[0].ulVal = UInt32(dictionary);
    properties[1].ulVal = UInt32(posStateBits);
    properties[2].ulVal = UInt32(litContextBits);
    properties[3].ulVal = UInt32(litPosBits);
    properties[4].ulVal = UInt32(algorithm);
    properties[5].ulVal = UInt32(numFastBytes);
    
    properties[6].vt = VT_BSTR;
    properties[6].bstrVal = (BSTR)(const wchar_t *)mf;

    properties[7].vt = VT_BOOL;
    properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;

    if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
      IncorrectCommand();
    encoderSpec->WriteCoderProperties(outStream);

    if (eos || stdInMode)
      fileSize = (UInt64)(Int64)-1;
    else
      inStreamSpec->File.GetLength(fileSize);

    for (int i = 0; i < 8; i++)
    {
      Byte b = Byte(fileSize >> (8 * i));
      if (outStream->Write(&b, sizeof(b), 0) != S_OK)
      {
        fprintf(stderr, "Write error");
        return 1;
      }
    }
    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
    if (result == E_OUTOFMEMORY)
    {
      fprintf(stderr, "\nError: Can not allocate memory\n");
      return 1;
    }   
    else if (result != S_OK)
    {
      fprintf(stderr, "\nEncoder error = %X\n", result);
      return 1;
    }   
  }
  else
  {
int main2(int n, const char *args[])
{
  fprintf(stderr, "\nLZMA 4.27 Copyright (c) 1999-2005 Igor Pavlov  2005-08-07\n");

  if (n == 1)
  {
    PrintHelp();
    return 0;
  }

  if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4)
  {
    fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
    return 1;
  }   

  UStringVector commandStrings;
  WriteArgumentsToStringList(n, args, commandStrings);
  CParser parser(kNumSwitches);
  try
  {
    parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...) 
  {
    IncorrectCommand();
  }

  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
    PrintHelp();
    return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int paramIndex = 0;
  if (paramIndex >= nonSwitchStrings.Size())
    IncorrectCommand();
  const UString &command = nonSwitchStrings[paramIndex++]; 

  bool dictionaryIsDefined = false;
  UInt32 dictionary = 1 << 21;
  if(parser[NKey::kDictionary].ThereIs)
  {
    UInt32 dicLog;
    if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
      IncorrectCommand();
    dictionary = 1 << dicLog;
    dictionaryIsDefined = true;
  }
  UString mf = L"BT4";
  if (parser[NKey::kMatchFinder].ThereIs)
    mf = parser[NKey::kMatchFinder].PostStrings[0];

  if (command.CompareNoCase(L"b") == 0)
  {
    const UInt32 kNumDefaultItereations = 10;
    UInt32 numIterations = kNumDefaultItereations;
    {
      if (paramIndex < nonSwitchStrings.Size())
        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
          numIterations = kNumDefaultItereations;
    }
    return LzmaBenchmark(stderr, numIterations, dictionary, 
        mf.CompareNoCase(L"BT4") == 0);
  }

  bool encodeMode = false;
  if (command.CompareNoCase(L"e") == 0)
    encodeMode = true;
  else if (command.CompareNoCase(L"d") == 0)
    encodeMode = false;
  else
    IncorrectCommand();

  bool stdInMode = parser[NKey::kStdIn].ThereIs;
  bool stdOutMode = parser[NKey::kStdOut].ThereIs;

  CMyComPtr<ISequentialInStream> inStream;
  CInFileStream *inStreamSpec = 0;
  if (stdInMode)
  {
    inStream = new CStdInFileStream;
    MY_SET_BINARY_MODE(stdin);
  }
  else
  {
    if (paramIndex >= nonSwitchStrings.Size())
      IncorrectCommand();
    const UString &inputName = nonSwitchStrings[paramIndex++]; 
    inStreamSpec = new CInFileStream;
    inStream = inStreamSpec;
    if (!inStreamSpec->Open(GetSystemString(inputName)))
    {
      fprintf(stderr, "\nError: can not open input file %s\n", 
          (const char *)GetOemString(inputName));
      return 1;
    }
  }

  CMyComPtr<ISequentialOutStream> outStream;
  if (stdOutMode)
  {
    outStream = new CStdOutFileStream;
    MY_SET_BINARY_MODE(stdout);
  }
  else
  {
    if (paramIndex >= nonSwitchStrings.Size())
      IncorrectCommand();
    const UString &outputName = nonSwitchStrings[paramIndex++]; 
    COutFileStream *outStreamSpec = new COutFileStream;
    outStream = outStreamSpec;
    if (!outStreamSpec->Create(GetSystemString(outputName), true))
    {
      fprintf(stderr, "\nError: can not open output file %s\n", 
        (const char *)GetOemString(outputName));
      return 1;
    }
  }

  if (parser[NKey::kFilter86].ThereIs)
  {
    // -f86 switch is for x86 filtered mode: BCJ + LZMA.
    if (parser[NKey::kEOS].ThereIs || stdInMode)
      throw "Can not use stdin in this mode";
    UInt64 fileSize;
    inStreamSpec->File.GetLength(fileSize);
    if (fileSize > 0xF0000000)
      throw "File is too big";
    UInt32 inSize = (UInt32)fileSize;
    Byte *inBuffer = 0;
    if (inSize != 0)
    {
      inBuffer = (Byte *)MyAlloc((size_t)inSize); 
      if (inBuffer == 0)
        throw kCantAllocate;
    }
    
    UInt32 processedSize;
    if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK)
      throw "Can not read";
    if ((UInt32)inSize != processedSize)
      throw "Read size error";

    Byte *outBuffer = 0;
    size_t outSizeProcessed;
    if (encodeMode)
    {
      // we allocate 105% of original size for output buffer
      size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
      if (outSize != 0)
      {
        outBuffer = (Byte *)MyAlloc((size_t)outSize); 
        if (outBuffer == 0)
          throw kCantAllocate;
      }
      if (!dictionaryIsDefined)
        dictionary = 1 << 23;
      int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, 
          dictionary, SZ_FILTER_AUTO);
      if (res != 0)
      {
        fprintf(stderr, "\nEncoder error = %d\n", (int)res);
        return 1;
      }
    }
    else
    {
      size_t outSize;
      if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
        throw "data error";
      if (outSize != 0)
      {
        outBuffer = (Byte *)MyAlloc(outSize); 
        if (outBuffer == 0)
          throw kCantAllocate;
      }
      int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
      if (res != 0)
        throw "LzmaDecoder error";
    }
    if (outStream->Write(outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
      throw "Can not write";
    MyFree(outBuffer);
    MyFree(inBuffer);
    return 0;
  }


  UInt64 fileSize;
  if (encodeMode)
  {
    NCompress::NLZMA::CEncoder *encoderSpec = 
      new NCompress::NLZMA::CEncoder;
    CMyComPtr<ICompressCoder> encoder = encoderSpec;

    if (!dictionaryIsDefined)
      dictionary = 1 << 23;

    UInt32 posStateBits = 2;
    UInt32 litContextBits = 3; // for normal files
    // UInt32 litContextBits = 0; // for 32-bit data
    UInt32 litPosBits = 0;
    // UInt32 litPosBits = 2; // for 32-bit data
    UInt32 algorithm = 2;
    UInt32 numFastBytes = 128;

    bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
 
    if(parser[NKey::kMode].ThereIs)
      if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
        IncorrectCommand();

    if(parser[NKey::kFastBytes].ThereIs)
      if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
        IncorrectCommand();
    if(parser[NKey::kLitContext].ThereIs)
      if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
        IncorrectCommand();
    if(parser[NKey::kLitPos].ThereIs)
      if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
        IncorrectCommand();
    if(parser[NKey::kPosBits].ThereIs)
      if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
        IncorrectCommand();

    PROPID propIDs[] = 
    {
      NCoderPropID::kDictionarySize,
      NCoderPropID::kPosStateBits,
      NCoderPropID::kLitContextBits,
      NCoderPropID::kLitPosBits,
      NCoderPropID::kAlgorithm,
      NCoderPropID::kNumFastBytes,
      NCoderPropID::kMatchFinder,
      NCoderPropID::kEndMarker
    };
    const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
    /*
    NWindows::NCOM::CPropVariant properties[kNumProps];
    properties[0] = UInt32(dictionary);
    properties[1] = UInt32(posStateBits);
    properties[2] = UInt32(litContextBits);
   
    properties[3] = UInt32(litPosBits);
    properties[4] = UInt32(algorithm);
    properties[5] = UInt32(numFastBytes);
    properties[6] = mf;
    properties[7] = eos;
    */
    PROPVARIANT properties[kNumProps];
    for (int p = 0; p < 6; p++)
      properties[p].vt = VT_UI4;
    properties[0].ulVal = UInt32(dictionary);
    properties[1].ulVal = UInt32(posStateBits);
    properties[2].ulVal = UInt32(litContextBits);
    properties[3].ulVal = UInt32(litPosBits);
    properties[4].ulVal = UInt32(algorithm);
    properties[5].ulVal = UInt32(numFastBytes);
    
    properties[6].vt = VT_BSTR;
    properties[6].bstrVal = (BSTR)(const wchar_t *)mf;

    properties[7].vt = VT_BOOL;
    properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;

    if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
      IncorrectCommand();
    encoderSpec->WriteCoderProperties(outStream);

    if (eos || stdInMode)
      fileSize = (UInt64)(Int64)-1;
    else
      inStreamSpec->File.GetLength(fileSize);

    for (int i = 0; i < 8; i++)
    {
      Byte b = Byte(fileSize >> (8 * i));
      if (outStream->Write(&b, sizeof(b), 0) != S_OK)
      {
        fprintf(stderr, "Write error");
        return 1;
      }
    }
    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
    if (result == E_OUTOFMEMORY)
    {
      fprintf(stderr, "\nError: Can not allocate memory\n");
      return 1;
    }   
    else if (result != S_OK)
    {
      fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
      return 1;
    }   
  }
  else
  {
Exemple #20
0
int main2(int numArgs, const char *args[])
{
  NT_CHECK

  PrintMessage("\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");

  if (numArgs == 1)
  {
    PrintHelp();
    return 0;
  }

  bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
  if (unsupportedTypes)
  {
    PrintMessage("Unsupported base types. Edit Common/Types.h and recompile");
    return 1;
  }

  UStringVector commandStrings;
  WriteArgumentsToStringList(numArgs, args, commandStrings);
  CParser parser(kNumSwitches);
  try
  {
    parser.ParseStrings(kSwitchForms, commandStrings);
  }
  catch(...)
  {
    IncorrectCommand();
  }

  if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  {
    PrintHelp();
    return 0;
  }
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;

  int paramIndex = 0;
  if (paramIndex >= nonSwitchStrings.Size())
    IncorrectCommand();
  const UString &command = nonSwitchStrings[paramIndex++];

  CObjectVector<CProperty> props;
  bool dictDefined = false;
  UInt32 dict = (UInt32)(Int32)-1;
  if (parser[NKey::kDict].ThereIs)
  {
    UInt32 dicLog;
    const UString &s = parser[NKey::kDict].PostStrings[0];
    if (!GetNumber(s, dicLog))
      IncorrectCommand();
    dict = 1 << dicLog;
    dictDefined = true;
    CProperty prop;
    prop.Name = L"d";
    prop.Value = s;
    props.Add(prop);
  }
  if (parser[NKey::kLevel].ThereIs)
  {
    UInt32 level = 5;
    const UString &s = parser[NKey::kLevel].PostStrings[0];
    if (!GetNumber(s, level))
      IncorrectCommand();
    CProperty prop;
    prop.Name = L"x";
    prop.Value = s;
    props.Add(prop);
  }
  UString mf = L"BT4";
  if (parser[NKey::kMatchFinder].ThereIs)
    mf = parser[NKey::kMatchFinder].PostStrings[0];

  UInt32 numThreads = (UInt32)(Int32)-1;

  #ifndef _7ZIP_ST
  if (parser[NKey::kMultiThread].ThereIs)
  {
    UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
    const UString &s = parser[NKey::kMultiThread].PostStrings[0];
    if (s.IsEmpty())
      numThreads = numCPUs;
    else
      if (!GetNumber(s, numThreads))
        IncorrectCommand();
    CProperty prop;
    prop.Name = L"mt";
    prop.Value = s;
    props.Add(prop);
  }
  #endif

  if (parser[NKey::kMethod].ThereIs)
  {
    UString s = parser[NKey::kMethod].PostStrings[0];
    if (s.IsEmpty() || s[0] != '=')
      IncorrectCommand();
    CProperty prop;
    prop.Name = L"m";
    prop.Value = s.Mid(1);
    props.Add(prop);
  }

  if (command.CompareNoCase(L"b") == 0)
  {
    const UInt32 kNumDefaultItereations = 1;
    UInt32 numIterations = kNumDefaultItereations;
    {
      if (paramIndex < nonSwitchStrings.Size())
        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
          numIterations = kNumDefaultItereations;
    }
    HRESULT res = BenchCon(props, numIterations, stderr);
    if (res != S_OK)
    {
      if (res != E_ABORT)
      {
        PrintMessage("Benchmark Error");
        return 1;
      }
    }
    return 0;
  }

  if (numThreads == (UInt32)(Int32)-1)
    numThreads = 1;

  bool encodeMode = false;
  if (command.CompareNoCase(L"e") == 0)
    encodeMode = true;
  else if (command.CompareNoCase(L"d") == 0)
    encodeMode = false;
  else
    IncorrectCommand();

  bool stdInMode = parser[NKey::kStdIn].ThereIs;
  bool stdOutMode = parser[NKey::kStdOut].ThereIs;

  CMyComPtr<ISequentialInStream> inStream;
  CInFileStream *inStreamSpec = 0;
  if (stdInMode)
  {
    inStream = new CStdInFileStream;
    MY_SET_BINARY_MODE(stdin);
  }
  else
  {
    if (paramIndex >= nonSwitchStrings.Size())
      IncorrectCommand();
    const UString &inputName = nonSwitchStrings[paramIndex++];
    inStreamSpec = new CInFileStream;
    inStream = inStreamSpec;
    if (!inStreamSpec->Open(us2fs(inputName)))
    {
      fprintf(stderr, "\nError: can not open input file %s\n",
          (const char *)GetOemString(inputName));
      return 1;
    }
  }

  CMyComPtr<ISequentialOutStream> outStream;
  COutFileStream *outStreamSpec = NULL;
  if (stdOutMode)
  {
    outStream = new CStdOutFileStream;
    MY_SET_BINARY_MODE(stdout);
  }
  else
  {
    if (paramIndex >= nonSwitchStrings.Size())
      IncorrectCommand();
    const UString &outputName = nonSwitchStrings[paramIndex++];
    outStreamSpec = new COutFileStream;
    outStream = outStreamSpec;
    if (!outStreamSpec->Create(us2fs(outputName), true))
    {
      fprintf(stderr, "\nError: can not open output file %s\n",
        (const char *)GetOemString(outputName));
      return 1;
    }
  }

  if (parser[NKey::kFilter86].ThereIs)
  {
    // -f86 switch is for x86 filtered mode: BCJ + LZMA.
    if (parser[NKey::kEOS].ThereIs || stdInMode)
      throw "Can not use stdin in this mode";
    UInt64 fileSize;
    inStreamSpec->File.GetLength(fileSize);
    if (fileSize > 0xF0000000)
      throw "File is too big";
    size_t inSize = (size_t)fileSize;
    Byte *inBuffer = 0;
    if (inSize != 0)
    {
      inBuffer = (Byte *)MyAlloc((size_t)inSize);
      if (inBuffer == 0)
        throw kCantAllocate;
    }
    
    if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK)
      throw "Can not read";

    Byte *outBuffer = 0;
    size_t outSize;
    if (encodeMode)
    {
      // we allocate 105% of original size for output buffer
      outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
      if (outSize != 0)
      {
        outBuffer = (Byte *)MyAlloc((size_t)outSize);
        if (outBuffer == 0)
          throw kCantAllocate;
      }
      if (!dictDefined)
        dict = 1 << 23;
      int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize,
          5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
      if (res != 0)
      {
        fprintf(stderr, "\nEncoder error = %d\n", (int)res);
        return 1;
      }
    }
    else
    {
      UInt64 outSize64;
      if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0)
        throw "data error";
      outSize = (size_t)outSize64;
      if (outSize != outSize64)
        throw "too big";
      if (outSize != 0)
      {
        outBuffer = (Byte *)MyAlloc(outSize);
        if (outBuffer == 0)
          throw kCantAllocate;
      }
      int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize);
      if (inSize != (size_t)fileSize)
        throw "incorrect processed size";
      if (res != 0)
        throw "LzmaDecoder error";
    }
    if (WriteStream(outStream, outBuffer, outSize) != S_OK)
      throw kWriteError;
    MyFree(outBuffer);
    MyFree(inBuffer);
    return 0;
  }


  UInt64 fileSize;
  if (encodeMode)
  {
    NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder;
    CMyComPtr<ICompressCoder> encoder = encoderSpec;

    if (!dictDefined)
      dict = 1 << 23;

    UInt32 pb = 2;
    UInt32 lc = 3; // = 0; for 32-bit data
    UInt32 lp = 0; // = 2; for 32-bit data
    UInt32 algo = 1;
    UInt32 fb = 128;
    UInt32 mc = 16 + fb / 2;
    bool mcDefined = false;

    bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
 
    ParseUInt32(parser, NKey::kAlgo, algo);
    ParseUInt32(parser, NKey::kFb, fb);
    ParseUInt32(parser, NKey::kLc, lc);
    ParseUInt32(parser, NKey::kLp, lp);
    ParseUInt32(parser, NKey::kPb, pb);

    mcDefined = parser[NKey::kMc].ThereIs;
    if (mcDefined)
      if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc))
        IncorrectCommand();
    
    const PROPID propIDs[] =
    {
      NCoderPropID::kDictionarySize,
      NCoderPropID::kPosStateBits,
      NCoderPropID::kLitContextBits,
      NCoderPropID::kLitPosBits,
      NCoderPropID::kAlgorithm,
      NCoderPropID::kNumFastBytes,
      NCoderPropID::kMatchFinder,
      NCoderPropID::kEndMarker,
      NCoderPropID::kNumThreads,
      NCoderPropID::kMatchFinderCycles,
    };
    const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);

    PROPVARIANT props[kNumPropsMax];
    for (int p = 0; p < 6; p++)
      props[p].vt = VT_UI4;

    props[0].ulVal = (UInt32)dict;
    props[1].ulVal = (UInt32)pb;
    props[2].ulVal = (UInt32)lc;
    props[3].ulVal = (UInt32)lp;
    props[4].ulVal = (UInt32)algo;
    props[5].ulVal = (UInt32)fb;

    props[6].vt = VT_BSTR;
    props[6].bstrVal = const_cast<BSTR>((const wchar_t *)mf);

    props[7].vt = VT_BOOL;
    props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;

    props[8].vt = VT_UI4;
    props[8].ulVal = (UInt32)numThreads;

    // it must be last in property list
    props[9].vt = VT_UI4;
    props[9].ulVal = (UInt32)mc;

    int numProps = kNumPropsMax;
    if (!mcDefined)
      numProps--;

    if (encoderSpec->SetCoderProperties(propIDs, props, numProps) != S_OK)
      IncorrectCommand();
    encoderSpec->WriteCoderProperties(outStream);

    if (eos || stdInMode)
      fileSize = (UInt64)(Int64)-1;
    else
      inStreamSpec->File.GetLength(fileSize);

    for (int i = 0; i < 8; i++)
    {
      Byte b = Byte(fileSize >> (8 * i));
      if (outStream->Write(&b, 1, 0) != S_OK)
      {
        PrintMessage(kWriteError);
        return 1;
      }
    }
    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
    if (result == E_OUTOFMEMORY)
    {
      PrintMessage("\nError: Can not allocate memory\n");
      return 1;
    }
    else if (result != S_OK)
    {
      fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
      return 1;
    }
  }
  else
  {