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; }
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); }
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); }
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; }
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(); }
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 }
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; }
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; }
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 }
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 }
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); }
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 {
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(); }
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; }
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 }
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 {
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 {