From f2902217b38cf2e16e851ae84d61247f8e828180 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 25 Mar 2019 17:53:14 +0100 Subject: Update the 7z installer stub source to 18.05. Tag #1022 --- .../src/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp | 799 +++++++++++++++++++++ 1 file changed, 799 insertions(+) create mode 100644 other-licenses/7zstub/src/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp (limited to 'other-licenses/7zstub/src/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp') diff --git a/other-licenses/7zstub/src/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/other-licenses/7zstub/src/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp new file mode 100644 index 000000000..f27333741 --- /dev/null +++ b/other-licenses/7zstub/src/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp @@ -0,0 +1,799 @@ +// LzmaAlone.cpp + +#include "StdAfx.h" + +#include + +#include "../../../../C/CpuArch.h" + +#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE) +#include +#include +#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY) +#else +#define MY_SET_BINARY_MODE(file) +#endif + +#include "../../../Common/MyWindows.h" +#include "../../../Common/MyInitGuid.h" + +#include "../../../../C/7zVersion.h" +#include "../../../../C/Alloc.h" +#include "../../../../C/Lzma86.h" + +#include "../../../Windows/NtCheck.h" + +#ifndef _7ZIP_ST +#include "../../../Windows/System.h" +#endif + +#include "../../../Common/IntToString.h" +#include "../../../Common/CommandLineParser.h" +#include "../../../Common/StringConvert.h" +#include "../../../Common/StringToInt.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" + +#include "../../Compress/LzmaDecoder.h" +#include "../../Compress/LzmaEncoder.h" + +#include "../../UI/Console/BenchCon.h" +#include "../../UI/Console/ConsoleClose.h" + +bool g_LargePagesMode = false; + +using namespace NCommandLineParser; + +static const unsigned kDictSizeLog = 24; + +#define kCopyrightString "\nLZMA " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n" + +static const char * const kHelpString = + "Usage: lzma [inputFile] [outputFile] [...]\n" + "\n" + "\n" + " e : Encode file\n" + " d : Decode file\n" + " b : Benchmark\n" + "\n" + " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n" + " -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n" + " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n" + " -mc{N} : set number of cycles for match finder\n" + " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n" + " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n" + " -pb{N} : set number of pos bits : [0, 4] : default = 2\n" + " -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n" + " -mt{N} : set number of CPU threads\n" + " -eos : write end of stream marker\n" + " -si : read data from stdin\n" + " -so : write data to stdout\n"; + + +static const char * const kCantAllocate = "Can not allocate memory"; +static const char * const kReadError = "Read error"; +static const char * const kWriteError = "Write error"; + + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kMethod, + kLevel, + kAlgo, + kDict, + kFb, + kMc, + kLc, + kLp, + kPb, + kMatchFinder, + kMultiThread, + kEOS, + kStdIn, + kStdOut, + kFilter86 +}; +} + +static const CSwitchForm kSwitchForms[] = +{ + { "?", NSwitchType::kSimple, false }, + { "H", NSwitchType::kSimple, false }, + { "MM", NSwitchType::kString, false, 1 }, + { "X", NSwitchType::kString, false, 1 }, + { "A", NSwitchType::kString, false, 1 }, + { "D", NSwitchType::kString, false, 1 }, + { "FB", NSwitchType::kString, false, 1 }, + { "MC", NSwitchType::kString, false, 1 }, + { "LC", NSwitchType::kString, false, 1 }, + { "LP", NSwitchType::kString, false, 1 }, + { "PB", NSwitchType::kString, false, 1 }, + { "MF", NSwitchType::kString, false, 1 }, + { "MT", NSwitchType::kString, false, 0 }, + { "EOS", NSwitchType::kSimple, false }, + { "SI", NSwitchType::kSimple, false }, + { "SO", NSwitchType::kSimple, false }, + { "F86", NSwitchType::kChar, false, 0, "+" } +}; + + +static void Convert_UString_to_AString(const UString &s, AString &temp) +{ + int codePage = CP_OEMCP; + /* + int g_CodePage = -1; + int codePage = g_CodePage; + if (codePage == -1) + codePage = CP_OEMCP; + if (codePage == CP_UTF8) + ConvertUnicodeToUTF8(s, temp); + else + */ + UnicodeStringToMultiByte2(temp, s, (UINT)codePage); +} + +static void PrintErr(const char *s) +{ + fputs(s, stderr); +} + +static void PrintErr_LF(const char *s) +{ + PrintErr(s); + fputc('\n', stderr); +} + + +static void PrintError(const char *s) +{ + PrintErr("\nERROR: "); + PrintErr_LF(s); +} + +static void PrintError2(const char *s1, const UString &s2) +{ + PrintError(s1); + AString a; + Convert_UString_to_AString(s2, a); + PrintErr_LF(a); +} + +static void PrintError_int(const char *s, int code) +{ + PrintError(s); + char temp[32]; + ConvertInt64ToString(code, temp); + PrintErr("Error code = "); + PrintErr_LF(temp); +} + + + +static void Print(const char *s) +{ + fputs(s, stdout); +} + +static void Print_UInt64(UInt64 v) +{ + char temp[32]; + ConvertUInt64ToString(v, temp); + Print(temp); +} + +static void Print_MB(UInt64 v) +{ + Print_UInt64(v); + Print(" MiB"); +} + +static void Print_Size(const char *s, UInt64 v) +{ + Print(s); + Print_UInt64(v); + Print(" ("); + Print_MB(v >> 20); + Print(")\n"); +} + +static void PrintTitle() +{ + Print(kCopyrightString); +} + +static void PrintHelp() +{ + PrintTitle(); + Print(kHelpString); +} + +class CProgressPrint: + public ICompressProgressInfo, + public CMyUnknownImp +{ + UInt64 _size1; + UInt64 _size2; +public: + CProgressPrint(): _size1(0), _size2(0) {} + + void ClosePrint(); + + MY_UNKNOWN_IMP1(ICompressProgressInfo) + + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); +}; + +#define BACK_STR \ +"\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" +static const char * const kBackSpaces = +BACK_STR +" " +BACK_STR; + + +void CProgressPrint::ClosePrint() +{ + Print(kBackSpaces); +} + +STDMETHODIMP CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + if (inSize) + { + UInt64 v1 = *inSize >> 20; + UInt64 v2 = _size2; + if (outSize) + v2 = *outSize >> 20; + if (v1 != _size1 || v2 != _size2) + { + _size1 = v1; + _size2 = v2; + ClosePrint(); + Print_MB(_size1); + Print(" -> "); + Print_MB(_size2); + } + } + return S_OK; +} + + +static void IncorrectCommand() +{ + throw "Incorrect command"; +} + +static UInt32 GetNumber(const wchar_t *s) +{ + const wchar_t *end; + UInt32 v = ConvertStringToUInt32(s, &end); + if (*end != 0) + IncorrectCommand(); + return v; +} + +static void ParseUInt32(const CParser &parser, unsigned index, UInt32 &res) +{ + if (parser[index].ThereIs) + res = GetNumber(parser[index].PostStrings[0]); +} + + +static int Error_HRESULT(const char *s, HRESULT res) +{ + if (res == E_ABORT) + { + Print("\n\nBreak signaled\n"); + return 255; + } + + PrintError(s); + + if (res == E_OUTOFMEMORY) + { + PrintErr_LF(kCantAllocate); + return 8; + } + if (res == E_INVALIDARG) + { + PrintErr_LF("Ununsupported parameter"); + } + else + { + char temp[32]; + ConvertUInt32ToHex(res, temp); + PrintErr("Error code = 0x"); + PrintErr_LF(temp); + } + return 1; +} + +#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1; + +static void AddProp(CObjectVector &props2, const char *name, const wchar_t *val) +{ + CProperty &prop = props2.AddNew(); + prop.Name = name; + prop.Value = val; +} + +static int main2(int numArgs, const char *args[]) +{ + NT_CHECK + + if (numArgs == 1) + { + PrintHelp(); + return 0; + } + + /* + bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 8); + if (unsupportedTypes) + throw "Unsupported base types. Edit Common/Types.h and recompile"; + */ + + UStringVector commandStrings; + for (int i = 1; i < numArgs; i++) + commandStrings.Add(MultiByteToUnicodeString(args[i])); + + CParser parser; + try + { + if (!parser.ParseStrings(kSwitchForms, ARRAY_SIZE(kSwitchForms), commandStrings)) + { + PrintError2(parser.ErrorMessage, parser.ErrorLine); + return 1; + } + } + catch(...) + { + IncorrectCommand(); + } + + if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs) + { + PrintHelp(); + return 0; + } + + bool stdInMode = parser[NKey::kStdIn].ThereIs; + bool stdOutMode = parser[NKey::kStdOut].ThereIs; + + if (!stdOutMode) + PrintTitle(); + + const UStringVector ¶ms = parser.NonSwitchStrings; + + unsigned paramIndex = 0; + if (paramIndex >= params.Size()) + IncorrectCommand(); + const UString &command = params[paramIndex++]; + + CObjectVector props2; + bool dictDefined = false; + UInt32 dict = (UInt32)(Int32)-1; + + if (parser[NKey::kDict].ThereIs) + { + UInt32 dictLog; + const UString &s = parser[NKey::kDict].PostStrings[0]; + dictLog = GetNumber(s); + dict = 1 << dictLog; + dictDefined = true; + AddProp(props2, "d", s); + } + + if (parser[NKey::kLevel].ThereIs) + { + const UString &s = parser[NKey::kLevel].PostStrings[0]; + /* UInt32 level = */ GetNumber(s); + AddProp(props2, "x", s); + } + + UString mf ("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) + { + const UString &s = parser[NKey::kMultiThread].PostStrings[0]; + if (s.IsEmpty()) + numThreads = NWindows::NSystem::GetNumberOfProcessors(); + else + numThreads = GetNumber(s); + AddProp(props2, "mt", s); + } + + #endif + + + if (parser[NKey::kMethod].ThereIs) + { + const UString &s = parser[NKey::kMethod].PostStrings[0]; + if (s.IsEmpty() || s[0] != '=') + IncorrectCommand(); + AddProp(props2, "m", s.Ptr(1)); + } + + if (StringsAreEqualNoCase_Ascii(command, "b")) + { + UInt32 numIterations = 1; + if (paramIndex < params.Size()) + numIterations = GetNumber(params[paramIndex++]); + if (params.Size() != paramIndex) + IncorrectCommand(); + + HRESULT res = BenchCon(props2, numIterations, stdout); + + if (res == S_OK) + return 0; + return Error_HRESULT("Benchmark error", res); + } + + { + UInt32 needParams = 3; + if (stdInMode) needParams--; + if (stdOutMode) needParams--; + if (needParams != params.Size()) + IncorrectCommand(); + } + + if (numThreads == (UInt32)(Int32)-1) + numThreads = 1; + + bool encodeMode = false; + + if (StringsAreEqualNoCase_Ascii(command, "e")) + encodeMode = true; + else if (!StringsAreEqualNoCase_Ascii(command, "d")) + IncorrectCommand(); + + CMyComPtr inStream; + CInFileStream *inStreamSpec = NULL; + + if (stdInMode) + { + inStream = new CStdInFileStream; + MY_SET_BINARY_MODE(stdin); + } + else + { + const UString &inputName = params[paramIndex++]; + inStreamSpec = new CInFileStream; + inStream = inStreamSpec; + if (!inStreamSpec->Open(us2fs(inputName))) + { + PrintError2("can not open input file", inputName); + return 1; + } + } + + CMyComPtr outStream; + COutFileStream *outStreamSpec = NULL; + + if (stdOutMode) + { + outStream = new CStdOutFileStream; + MY_SET_BINARY_MODE(stdout); + } + else + { + const UString &outputName = params[paramIndex++]; + outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + if (!outStreamSpec->Create(us2fs(outputName), true)) + { + PrintError2("can not open output file", outputName); + return 1; + } + } + + bool fileSizeDefined = false; + UInt64 fileSize = 0; + + if (inStreamSpec) + { + if (!inStreamSpec->File.GetLength(fileSize)) + throw "Can not get file length"; + fileSizeDefined = true; + if (!stdOutMode) + Print_Size("Input size: ", fileSize); + } + + if (encodeMode && !dictDefined) + { + dict = 1 << kDictSizeLog; + if (fileSizeDefined) + { + unsigned i; + for (i = 16; i < kDictSizeLog; i++) + if ((UInt32)((UInt32)1 << i) >= fileSize) + break; + dict = (UInt32)1 << i; + } + } + + if (parser[NKey::kFilter86].ThereIs) + { + /* -f86 switch is for x86 filtered mode: BCJ + LZMA. + It uses modified header format. + It's not recommended to use -f86 mode now. + You can use xz format instead, if you want to use filters */ + + if (parser[NKey::kEOS].ThereIs || stdInMode) + throw "Can not use stdin in this mode"; + + size_t inSize = (size_t)fileSize; + + if (inSize != fileSize) + throw "File is too big"; + + Byte *inBuffer = NULL; + + if (inSize != 0) + { + inBuffer = (Byte *)MyAlloc((size_t)inSize); + if (!inBuffer) + throw kCantAllocate; + } + + if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK) + throw "Can not read"; + + Byte *outBuffer = NULL; + size_t outSize; + + if (encodeMode) + { + // we allocate 105% of original size for output buffer + UInt64 outSize64 = fileSize / 20 * 21 + (1 << 16); + + outSize = (size_t)outSize64; + + if (outSize != outSize64) + throw "File is too big"; + + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc((size_t)outSize); + if (!outBuffer) + throw kCantAllocate; + } + + int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize, + 5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO); + + if (res != 0) + { + PrintError_int("Encode error", (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 "Unpack size is too big"; + if (outSize != 0) + { + outBuffer = (Byte *)MyAlloc(outSize); + if (!outBuffer) + throw kCantAllocate; + } + + int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize); + + if (inSize != (size_t)fileSize) + throw "incorrect processed size"; + if (res != 0) + { + PrintError_int("Decode error", (int)res); + return 1; + } + } + + if (WriteStream(outStream, outBuffer, outSize) != S_OK) + throw kWriteError; + + MyFree(outBuffer); + MyFree(inBuffer); + } + else + { + + CProgressPrint *progressSpec = NULL; + CMyComPtr progress; + + if (!stdOutMode) + { + progressSpec = new CProgressPrint; + progress = progressSpec; + } + + if (encodeMode) + { + NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder; + CMyComPtr encoder = encoderSpec; + + 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) + mc = GetNumber(parser[NKey::kMc].PostStrings[0]); + + const PROPID propIDs[] = + { + NCoderPropID::kDictionarySize, + NCoderPropID::kPosStateBits, + NCoderPropID::kLitContextBits, + NCoderPropID::kLitPosBits, + NCoderPropID::kAlgorithm, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinder, + NCoderPropID::kEndMarker, + NCoderPropID::kNumThreads, + NCoderPropID::kMatchFinderCycles, + }; + + const unsigned kNumPropsMax = ARRAY_SIZE(propIDs); + + 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((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; + + unsigned numProps = kNumPropsMax; + if (!mcDefined) + numProps--; + + HRESULT res = encoderSpec->SetCoderProperties(propIDs, props, numProps); + if (res != S_OK) + return Error_HRESULT("incorrect encoder properties", res); + + if (encoderSpec->WriteCoderProperties(outStream) != S_OK) + throw kWriteError; + + bool fileSizeWasUsed = true; + if (eos || stdInMode) + { + fileSize = (UInt64)(Int64)-1; + fileSizeWasUsed = false; + } + + { + Byte temp[8]; + for (int i = 0; i < 8; i++) + temp[i]= (Byte)(fileSize >> (8 * i)); + if (WriteStream(outStream, temp, 8) != S_OK) + throw kWriteError; + } + + res = encoder->Code(inStream, outStream, NULL, NULL, progress); + if (progressSpec) + progressSpec->ClosePrint(); + + if (res != S_OK) + return Error_HRESULT("Encoding error", res); + + UInt64 processedSize = encoderSpec->GetInputProcessedSize(); + + if (fileSizeWasUsed && processedSize != fileSize) + throw "Incorrect size of processed data"; + } + else + { + NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder; + CMyComPtr decoder = decoderSpec; + + decoderSpec->FinishStream = true; + + const unsigned kPropertiesSize = 5; + Byte header[kPropertiesSize + 8]; + + if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK) + throw kReadError; + + if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK) + throw "SetDecoderProperties error"; + + UInt64 unpackSize = 0; + for (int i = 0; i < 8; i++) + unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i); + + bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1); + + HRESULT res = decoder->Code(inStream, outStream, NULL, unpackSizeDefined ? &unpackSize : NULL, progress); + if (progressSpec) + progressSpec->ClosePrint(); + + if (res != S_OK) + { + if (res == S_FALSE) + { + PrintError("Decoding error"); + return 1; + } + return Error_HRESULT("Decoding error", res); + } + + if (unpackSizeDefined && unpackSize != decoderSpec->GetOutputProcessedSize()) + throw "incorrect uncompressed size in header"; + } + } + + if (outStreamSpec) + { + if (!stdOutMode) + Print_Size("Output size: ", outStreamSpec->ProcessedSize); + if (outStreamSpec->Close() != S_OK) + throw "File closing error"; + } + + return 0; +} + +int MY_CDECL main(int numArgs, const char *args[]) +{ + NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; + + try { return main2(numArgs, args); } + catch (const char *s) + { + PrintError(s); + return 1; + } + catch(...) + { + PrintError("Unknown Error"); + return 1; + } +} -- cgit v1.2.3