xref: /aosp_15_r20/external/lzma/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker   // LzmaAlone.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE)
8*f6dc9357SAndroid Build Coastguard Worker #include <fcntl.h>
9*f6dc9357SAndroid Build Coastguard Worker #include <io.h>
10*f6dc9357SAndroid Build Coastguard Worker #define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)
11*f6dc9357SAndroid Build Coastguard Worker #else
12*f6dc9357SAndroid Build Coastguard Worker #define MY_SET_BINARY_MODE(file)
13*f6dc9357SAndroid Build Coastguard Worker #endif
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/7zVersion.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/Alloc.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/Lzma86.h"
19*f6dc9357SAndroid Build Coastguard Worker 
20*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyWindows.h"
21*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/MyInitGuid.h"
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/NtCheck.h"
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_ST
26*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/System.h"
27*f6dc9357SAndroid Build Coastguard Worker #endif
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
30*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/CommandLineParser.h"
31*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
32*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringToInt.h"
33*f6dc9357SAndroid Build Coastguard Worker 
34*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/FileStreams.h"
35*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StreamUtils.h"
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/LzmaDecoder.h"
38*f6dc9357SAndroid Build Coastguard Worker #include "../../Compress/LzmaEncoder.h"
39*f6dc9357SAndroid Build Coastguard Worker 
40*f6dc9357SAndroid Build Coastguard Worker #include "../../UI/Console/BenchCon.h"
41*f6dc9357SAndroid Build Coastguard Worker #include "../../UI/Console/ConsoleClose.h"
42*f6dc9357SAndroid Build Coastguard Worker 
43*f6dc9357SAndroid Build Coastguard Worker extern
44*f6dc9357SAndroid Build Coastguard Worker bool g_LargePagesMode;
45*f6dc9357SAndroid Build Coastguard Worker bool g_LargePagesMode = false;
46*f6dc9357SAndroid Build Coastguard Worker 
47*f6dc9357SAndroid Build Coastguard Worker using namespace NCommandLineParser;
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker static const unsigned kDictSizeLog = 24;
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker #define kCopyrightString "\nLZMA " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker static const char * const kHelpString =
54*f6dc9357SAndroid Build Coastguard Worker     "Usage:  lzma <command> [inputFile] [outputFile] [<switches>...]\n"
55*f6dc9357SAndroid Build Coastguard Worker     "\n"
56*f6dc9357SAndroid Build Coastguard Worker     "<command>\n"
57*f6dc9357SAndroid Build Coastguard Worker     "  e : Encode file\n"
58*f6dc9357SAndroid Build Coastguard Worker     "  d : Decode file\n"
59*f6dc9357SAndroid Build Coastguard Worker     "  b : Benchmark\n"
60*f6dc9357SAndroid Build Coastguard Worker     "<switches>\n"
61*f6dc9357SAndroid Build Coastguard Worker     "  -a{N}  : set compression mode : [0, 1] : default = 1 (max)\n"
62*f6dc9357SAndroid Build Coastguard Worker     "  -d{N}  : set dictionary size : [12, 31] : default = 24 (16 MiB)\n"
63*f6dc9357SAndroid Build Coastguard Worker     "  -fb{N} : set number of fast bytes : [5, 273] : default = 128\n"
64*f6dc9357SAndroid Build Coastguard Worker     "  -mc{N} : set number of cycles for match finder\n"
65*f6dc9357SAndroid Build Coastguard Worker     "  -lc{N} : set number of literal context bits : [0, 8] : default = 3\n"
66*f6dc9357SAndroid Build Coastguard Worker     "  -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n"
67*f6dc9357SAndroid Build Coastguard Worker     "  -pb{N} : set number of pos bits : [0, 4] : default = 2\n"
68*f6dc9357SAndroid Build Coastguard Worker     "  -mf{M} : set match finder: [hc4, hc5, bt2, bt3, bt4, bt5] : default = bt4\n"
69*f6dc9357SAndroid Build Coastguard Worker     "  -mt{N} : set number of CPU threads\n"
70*f6dc9357SAndroid Build Coastguard Worker     "  -eos   : write end of stream marker\n"
71*f6dc9357SAndroid Build Coastguard Worker     "  -si    : read data from stdin\n"
72*f6dc9357SAndroid Build Coastguard Worker     "  -so    : write data to stdout\n";
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker static const char * const kCantAllocate = "Cannot allocate memory";
76*f6dc9357SAndroid Build Coastguard Worker static const char * const kReadError = "Read error";
77*f6dc9357SAndroid Build Coastguard Worker static const char * const kWriteError = "Write error";
78*f6dc9357SAndroid Build Coastguard Worker 
79*f6dc9357SAndroid Build Coastguard Worker 
80*f6dc9357SAndroid Build Coastguard Worker namespace NKey {
81*f6dc9357SAndroid Build Coastguard Worker enum Enum
82*f6dc9357SAndroid Build Coastguard Worker {
83*f6dc9357SAndroid Build Coastguard Worker   kHelp1 = 0,
84*f6dc9357SAndroid Build Coastguard Worker   kHelp2,
85*f6dc9357SAndroid Build Coastguard Worker   kMethod,
86*f6dc9357SAndroid Build Coastguard Worker   kLevel,
87*f6dc9357SAndroid Build Coastguard Worker   kAlgo,
88*f6dc9357SAndroid Build Coastguard Worker   kDict,
89*f6dc9357SAndroid Build Coastguard Worker   kFb,
90*f6dc9357SAndroid Build Coastguard Worker   kMc,
91*f6dc9357SAndroid Build Coastguard Worker   kLc,
92*f6dc9357SAndroid Build Coastguard Worker   kLp,
93*f6dc9357SAndroid Build Coastguard Worker   kPb,
94*f6dc9357SAndroid Build Coastguard Worker   kMatchFinder,
95*f6dc9357SAndroid Build Coastguard Worker   kMultiThread,
96*f6dc9357SAndroid Build Coastguard Worker   kEOS,
97*f6dc9357SAndroid Build Coastguard Worker   kStdIn,
98*f6dc9357SAndroid Build Coastguard Worker   kStdOut,
99*f6dc9357SAndroid Build Coastguard Worker   kFilter86
100*f6dc9357SAndroid Build Coastguard Worker };
101*f6dc9357SAndroid Build Coastguard Worker }
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker #define SWFRM_3(t, mu, mi) t, mu, mi, NULL
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker #define SWFRM_1(t) SWFRM_3(t, false, 0)
106*f6dc9357SAndroid Build Coastguard Worker #define SWFRM_SIMPLE SWFRM_1(NSwitchType::kSimple)
107*f6dc9357SAndroid Build Coastguard Worker #define SWFRM_STRING SWFRM_1(NSwitchType::kString)
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker #define SWFRM_STRING_SINGL(mi) SWFRM_3(NSwitchType::kString, false, mi)
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker static const CSwitchForm kSwitchForms[] =
112*f6dc9357SAndroid Build Coastguard Worker {
113*f6dc9357SAndroid Build Coastguard Worker   { "?",  SWFRM_SIMPLE },
114*f6dc9357SAndroid Build Coastguard Worker   { "H",  SWFRM_SIMPLE },
115*f6dc9357SAndroid Build Coastguard Worker   { "MM", SWFRM_STRING_SINGL(1) },
116*f6dc9357SAndroid Build Coastguard Worker   { "X", SWFRM_STRING_SINGL(1) },
117*f6dc9357SAndroid Build Coastguard Worker   { "A", SWFRM_STRING_SINGL(1) },
118*f6dc9357SAndroid Build Coastguard Worker   { "D", SWFRM_STRING_SINGL(1) },
119*f6dc9357SAndroid Build Coastguard Worker   { "FB", SWFRM_STRING_SINGL(1) },
120*f6dc9357SAndroid Build Coastguard Worker   { "MC", SWFRM_STRING_SINGL(1) },
121*f6dc9357SAndroid Build Coastguard Worker   { "LC", SWFRM_STRING_SINGL(1) },
122*f6dc9357SAndroid Build Coastguard Worker   { "LP", SWFRM_STRING_SINGL(1) },
123*f6dc9357SAndroid Build Coastguard Worker   { "PB", SWFRM_STRING_SINGL(1) },
124*f6dc9357SAndroid Build Coastguard Worker   { "MF", SWFRM_STRING_SINGL(1) },
125*f6dc9357SAndroid Build Coastguard Worker   { "MT", SWFRM_STRING },
126*f6dc9357SAndroid Build Coastguard Worker   { "EOS", SWFRM_SIMPLE },
127*f6dc9357SAndroid Build Coastguard Worker   { "SI",  SWFRM_SIMPLE },
128*f6dc9357SAndroid Build Coastguard Worker   { "SO",  SWFRM_SIMPLE },
129*f6dc9357SAndroid Build Coastguard Worker   { "F86",  NSwitchType::kChar, false, 0, "+" }
130*f6dc9357SAndroid Build Coastguard Worker };
131*f6dc9357SAndroid Build Coastguard Worker 
132*f6dc9357SAndroid Build Coastguard Worker 
Convert_UString_to_AString(const UString & s,AString & temp)133*f6dc9357SAndroid Build Coastguard Worker static void Convert_UString_to_AString(const UString &s, AString &temp)
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker   int codePage = CP_OEMCP;
136*f6dc9357SAndroid Build Coastguard Worker   /*
137*f6dc9357SAndroid Build Coastguard Worker   int g_CodePage = -1;
138*f6dc9357SAndroid Build Coastguard Worker   int codePage = g_CodePage;
139*f6dc9357SAndroid Build Coastguard Worker   if (codePage == -1)
140*f6dc9357SAndroid Build Coastguard Worker     codePage = CP_OEMCP;
141*f6dc9357SAndroid Build Coastguard Worker   if (codePage == CP_UTF8)
142*f6dc9357SAndroid Build Coastguard Worker     ConvertUnicodeToUTF8(s, temp);
143*f6dc9357SAndroid Build Coastguard Worker   else
144*f6dc9357SAndroid Build Coastguard Worker   */
145*f6dc9357SAndroid Build Coastguard Worker     UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
146*f6dc9357SAndroid Build Coastguard Worker }
147*f6dc9357SAndroid Build Coastguard Worker 
PrintErr(const char * s)148*f6dc9357SAndroid Build Coastguard Worker static void PrintErr(const char *s)
149*f6dc9357SAndroid Build Coastguard Worker {
150*f6dc9357SAndroid Build Coastguard Worker   fputs(s, stderr);
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker 
PrintErr_LF(const char * s)153*f6dc9357SAndroid Build Coastguard Worker static void PrintErr_LF(const char *s)
154*f6dc9357SAndroid Build Coastguard Worker {
155*f6dc9357SAndroid Build Coastguard Worker   PrintErr(s);
156*f6dc9357SAndroid Build Coastguard Worker   fputc('\n', stderr);
157*f6dc9357SAndroid Build Coastguard Worker }
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker 
PrintError(const char * s)160*f6dc9357SAndroid Build Coastguard Worker static void PrintError(const char *s)
161*f6dc9357SAndroid Build Coastguard Worker {
162*f6dc9357SAndroid Build Coastguard Worker   PrintErr("\nERROR: ");
163*f6dc9357SAndroid Build Coastguard Worker   PrintErr_LF(s);
164*f6dc9357SAndroid Build Coastguard Worker }
165*f6dc9357SAndroid Build Coastguard Worker 
PrintError2(const char * s1,const UString & s2)166*f6dc9357SAndroid Build Coastguard Worker static void PrintError2(const char *s1, const UString &s2)
167*f6dc9357SAndroid Build Coastguard Worker {
168*f6dc9357SAndroid Build Coastguard Worker   PrintError(s1);
169*f6dc9357SAndroid Build Coastguard Worker   AString a;
170*f6dc9357SAndroid Build Coastguard Worker   Convert_UString_to_AString(s2, a);
171*f6dc9357SAndroid Build Coastguard Worker   PrintErr_LF(a);
172*f6dc9357SAndroid Build Coastguard Worker }
173*f6dc9357SAndroid Build Coastguard Worker 
PrintError_int(const char * s,int code)174*f6dc9357SAndroid Build Coastguard Worker static void PrintError_int(const char *s, int code)
175*f6dc9357SAndroid Build Coastguard Worker {
176*f6dc9357SAndroid Build Coastguard Worker   PrintError(s);
177*f6dc9357SAndroid Build Coastguard Worker   char temp[32];
178*f6dc9357SAndroid Build Coastguard Worker   ConvertInt64ToString(code, temp);
179*f6dc9357SAndroid Build Coastguard Worker   PrintErr("Error code = ");
180*f6dc9357SAndroid Build Coastguard Worker   PrintErr_LF(temp);
181*f6dc9357SAndroid Build Coastguard Worker }
182*f6dc9357SAndroid Build Coastguard Worker 
183*f6dc9357SAndroid Build Coastguard Worker 
184*f6dc9357SAndroid Build Coastguard Worker 
Print(const char * s)185*f6dc9357SAndroid Build Coastguard Worker static void Print(const char *s)
186*f6dc9357SAndroid Build Coastguard Worker {
187*f6dc9357SAndroid Build Coastguard Worker   fputs(s, stdout);
188*f6dc9357SAndroid Build Coastguard Worker }
189*f6dc9357SAndroid Build Coastguard Worker 
Print_UInt64(UInt64 v)190*f6dc9357SAndroid Build Coastguard Worker static void Print_UInt64(UInt64 v)
191*f6dc9357SAndroid Build Coastguard Worker {
192*f6dc9357SAndroid Build Coastguard Worker   char temp[32];
193*f6dc9357SAndroid Build Coastguard Worker   ConvertUInt64ToString(v, temp);
194*f6dc9357SAndroid Build Coastguard Worker   Print(temp);
195*f6dc9357SAndroid Build Coastguard Worker }
196*f6dc9357SAndroid Build Coastguard Worker 
Print_MB(UInt64 v)197*f6dc9357SAndroid Build Coastguard Worker static void Print_MB(UInt64 v)
198*f6dc9357SAndroid Build Coastguard Worker {
199*f6dc9357SAndroid Build Coastguard Worker   Print_UInt64(v);
200*f6dc9357SAndroid Build Coastguard Worker   Print(" MiB");
201*f6dc9357SAndroid Build Coastguard Worker }
202*f6dc9357SAndroid Build Coastguard Worker 
Print_Size(const char * s,UInt64 v)203*f6dc9357SAndroid Build Coastguard Worker static void Print_Size(const char *s, UInt64 v)
204*f6dc9357SAndroid Build Coastguard Worker {
205*f6dc9357SAndroid Build Coastguard Worker   Print(s);
206*f6dc9357SAndroid Build Coastguard Worker   Print_UInt64(v);
207*f6dc9357SAndroid Build Coastguard Worker   Print(" (");
208*f6dc9357SAndroid Build Coastguard Worker   Print_MB(v >> 20);
209*f6dc9357SAndroid Build Coastguard Worker   Print(")\n");
210*f6dc9357SAndroid Build Coastguard Worker }
211*f6dc9357SAndroid Build Coastguard Worker 
PrintTitle()212*f6dc9357SAndroid Build Coastguard Worker static void PrintTitle()
213*f6dc9357SAndroid Build Coastguard Worker {
214*f6dc9357SAndroid Build Coastguard Worker   Print(kCopyrightString);
215*f6dc9357SAndroid Build Coastguard Worker }
216*f6dc9357SAndroid Build Coastguard Worker 
PrintHelp()217*f6dc9357SAndroid Build Coastguard Worker static void PrintHelp()
218*f6dc9357SAndroid Build Coastguard Worker {
219*f6dc9357SAndroid Build Coastguard Worker   PrintTitle();
220*f6dc9357SAndroid Build Coastguard Worker   Print(kHelpString);
221*f6dc9357SAndroid Build Coastguard Worker }
222*f6dc9357SAndroid Build Coastguard Worker 
223*f6dc9357SAndroid Build Coastguard Worker 
224*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_COM_1(
225*f6dc9357SAndroid Build Coastguard Worker   CProgressPrint,
226*f6dc9357SAndroid Build Coastguard Worker   ICompressProgressInfo
227*f6dc9357SAndroid Build Coastguard Worker )
228*f6dc9357SAndroid Build Coastguard Worker   UInt64 _size1;
229*f6dc9357SAndroid Build Coastguard Worker   UInt64 _size2;
230*f6dc9357SAndroid Build Coastguard Worker public:
231*f6dc9357SAndroid Build Coastguard Worker   CProgressPrint(): _size1(0), _size2(0) {}
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker   void ClosePrint();
234*f6dc9357SAndroid Build Coastguard Worker };
235*f6dc9357SAndroid Build Coastguard Worker 
236*f6dc9357SAndroid Build Coastguard Worker #define BACK_STR \
237*f6dc9357SAndroid Build Coastguard Worker "\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"
238*f6dc9357SAndroid Build Coastguard Worker static const char * const kBackSpaces =
239*f6dc9357SAndroid Build Coastguard Worker BACK_STR
240*f6dc9357SAndroid Build Coastguard Worker "                                                                "
241*f6dc9357SAndroid Build Coastguard Worker BACK_STR;
242*f6dc9357SAndroid Build Coastguard Worker 
243*f6dc9357SAndroid Build Coastguard Worker 
244*f6dc9357SAndroid Build Coastguard Worker void CProgressPrint::ClosePrint()
245*f6dc9357SAndroid Build Coastguard Worker {
246*f6dc9357SAndroid Build Coastguard Worker   Print(kBackSpaces);
247*f6dc9357SAndroid Build Coastguard Worker }
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CProgressPrint::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
250*f6dc9357SAndroid Build Coastguard Worker {
251*f6dc9357SAndroid Build Coastguard Worker   if (NConsoleClose::TestBreakSignal())
252*f6dc9357SAndroid Build Coastguard Worker     return E_ABORT;
253*f6dc9357SAndroid Build Coastguard Worker   if (inSize)
254*f6dc9357SAndroid Build Coastguard Worker   {
255*f6dc9357SAndroid Build Coastguard Worker     UInt64 v1 = *inSize >> 20;
256*f6dc9357SAndroid Build Coastguard Worker     UInt64 v2 = _size2;
257*f6dc9357SAndroid Build Coastguard Worker     if (outSize)
258*f6dc9357SAndroid Build Coastguard Worker       v2 = *outSize >> 20;
259*f6dc9357SAndroid Build Coastguard Worker     if (v1 != _size1 || v2 != _size2)
260*f6dc9357SAndroid Build Coastguard Worker     {
261*f6dc9357SAndroid Build Coastguard Worker       _size1 = v1;
262*f6dc9357SAndroid Build Coastguard Worker       _size2 = v2;
263*f6dc9357SAndroid Build Coastguard Worker       ClosePrint();
264*f6dc9357SAndroid Build Coastguard Worker       Print_MB(_size1);
265*f6dc9357SAndroid Build Coastguard Worker       Print(" -> ");
266*f6dc9357SAndroid Build Coastguard Worker       Print_MB(_size2);
267*f6dc9357SAndroid Build Coastguard Worker     }
268*f6dc9357SAndroid Build Coastguard Worker   }
269*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
270*f6dc9357SAndroid Build Coastguard Worker }
271*f6dc9357SAndroid Build Coastguard Worker 
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker Z7_ATTR_NORETURN
274*f6dc9357SAndroid Build Coastguard Worker static void IncorrectCommand()
275*f6dc9357SAndroid Build Coastguard Worker {
276*f6dc9357SAndroid Build Coastguard Worker   throw "Incorrect command";
277*f6dc9357SAndroid Build Coastguard Worker }
278*f6dc9357SAndroid Build Coastguard Worker 
279*f6dc9357SAndroid Build Coastguard Worker static UInt32 GetNumber(const wchar_t *s)
280*f6dc9357SAndroid Build Coastguard Worker {
281*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *end;
282*f6dc9357SAndroid Build Coastguard Worker   UInt32 v = ConvertStringToUInt32(s, &end);
283*f6dc9357SAndroid Build Coastguard Worker   if (*end != 0)
284*f6dc9357SAndroid Build Coastguard Worker     IncorrectCommand();
285*f6dc9357SAndroid Build Coastguard Worker   return v;
286*f6dc9357SAndroid Build Coastguard Worker }
287*f6dc9357SAndroid Build Coastguard Worker 
288*f6dc9357SAndroid Build Coastguard Worker static void ParseUInt32(const CParser &parser, unsigned index, UInt32 &res)
289*f6dc9357SAndroid Build Coastguard Worker {
290*f6dc9357SAndroid Build Coastguard Worker   if (parser[index].ThereIs)
291*f6dc9357SAndroid Build Coastguard Worker     res = GetNumber(parser[index].PostStrings[0]);
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker 
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker static int Error_HRESULT(const char *s, HRESULT res)
296*f6dc9357SAndroid Build Coastguard Worker {
297*f6dc9357SAndroid Build Coastguard Worker   if (res == E_ABORT)
298*f6dc9357SAndroid Build Coastguard Worker   {
299*f6dc9357SAndroid Build Coastguard Worker     Print("\n\nBreak signaled\n");
300*f6dc9357SAndroid Build Coastguard Worker     return 255;
301*f6dc9357SAndroid Build Coastguard Worker   }
302*f6dc9357SAndroid Build Coastguard Worker 
303*f6dc9357SAndroid Build Coastguard Worker   PrintError(s);
304*f6dc9357SAndroid Build Coastguard Worker 
305*f6dc9357SAndroid Build Coastguard Worker   if (res == E_OUTOFMEMORY)
306*f6dc9357SAndroid Build Coastguard Worker   {
307*f6dc9357SAndroid Build Coastguard Worker     PrintErr_LF(kCantAllocate);
308*f6dc9357SAndroid Build Coastguard Worker     return 8;
309*f6dc9357SAndroid Build Coastguard Worker   }
310*f6dc9357SAndroid Build Coastguard Worker   if (res == E_INVALIDARG)
311*f6dc9357SAndroid Build Coastguard Worker   {
312*f6dc9357SAndroid Build Coastguard Worker     PrintErr_LF("Ununsupported parameter");
313*f6dc9357SAndroid Build Coastguard Worker   }
314*f6dc9357SAndroid Build Coastguard Worker   else
315*f6dc9357SAndroid Build Coastguard Worker   {
316*f6dc9357SAndroid Build Coastguard Worker     char temp[32];
317*f6dc9357SAndroid Build Coastguard Worker     ConvertUInt32ToHex((UInt32)res, temp);
318*f6dc9357SAndroid Build Coastguard Worker     PrintErr("Error code = 0x");
319*f6dc9357SAndroid Build Coastguard Worker     PrintErr_LF(temp);
320*f6dc9357SAndroid Build Coastguard Worker   }
321*f6dc9357SAndroid Build Coastguard Worker   return 1;
322*f6dc9357SAndroid Build Coastguard Worker }
323*f6dc9357SAndroid Build Coastguard Worker 
324*f6dc9357SAndroid Build Coastguard Worker #if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
325*f6dc9357SAndroid Build Coastguard Worker #define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
326*f6dc9357SAndroid Build Coastguard Worker #endif
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker static void AddProp(CObjectVector<CProperty> &props2, const char *name, const wchar_t *val)
329*f6dc9357SAndroid Build Coastguard Worker {
330*f6dc9357SAndroid Build Coastguard Worker   CProperty &prop = props2.AddNew();
331*f6dc9357SAndroid Build Coastguard Worker   prop.Name = name;
332*f6dc9357SAndroid Build Coastguard Worker   prop.Value = val;
333*f6dc9357SAndroid Build Coastguard Worker }
334*f6dc9357SAndroid Build Coastguard Worker 
335*f6dc9357SAndroid Build Coastguard Worker static int main2(int numArgs, const char *args[])
336*f6dc9357SAndroid Build Coastguard Worker {
337*f6dc9357SAndroid Build Coastguard Worker   NT_CHECK
338*f6dc9357SAndroid Build Coastguard Worker 
339*f6dc9357SAndroid Build Coastguard Worker   if (numArgs == 1)
340*f6dc9357SAndroid Build Coastguard Worker   {
341*f6dc9357SAndroid Build Coastguard Worker     PrintHelp();
342*f6dc9357SAndroid Build Coastguard Worker     return 0;
343*f6dc9357SAndroid Build Coastguard Worker   }
344*f6dc9357SAndroid Build Coastguard Worker 
345*f6dc9357SAndroid Build Coastguard Worker   /*
346*f6dc9357SAndroid Build Coastguard Worker   bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 8);
347*f6dc9357SAndroid Build Coastguard Worker   if (unsupportedTypes)
348*f6dc9357SAndroid Build Coastguard Worker     throw "Unsupported base types. Edit Common/Types.h and recompile";
349*f6dc9357SAndroid Build Coastguard Worker   */
350*f6dc9357SAndroid Build Coastguard Worker 
351*f6dc9357SAndroid Build Coastguard Worker   UStringVector commandStrings;
352*f6dc9357SAndroid Build Coastguard Worker   for (int i = 1; i < numArgs; i++)
353*f6dc9357SAndroid Build Coastguard Worker     commandStrings.Add(MultiByteToUnicodeString(args[i]));
354*f6dc9357SAndroid Build Coastguard Worker 
355*f6dc9357SAndroid Build Coastguard Worker   CParser parser;
356*f6dc9357SAndroid Build Coastguard Worker   try
357*f6dc9357SAndroid Build Coastguard Worker   {
358*f6dc9357SAndroid Build Coastguard Worker     if (!parser.ParseStrings(kSwitchForms, Z7_ARRAY_SIZE(kSwitchForms), commandStrings))
359*f6dc9357SAndroid Build Coastguard Worker     {
360*f6dc9357SAndroid Build Coastguard Worker       PrintError2(parser.ErrorMessage, parser.ErrorLine);
361*f6dc9357SAndroid Build Coastguard Worker       return 1;
362*f6dc9357SAndroid Build Coastguard Worker     }
363*f6dc9357SAndroid Build Coastguard Worker   }
364*f6dc9357SAndroid Build Coastguard Worker   catch(...)
365*f6dc9357SAndroid Build Coastguard Worker   {
366*f6dc9357SAndroid Build Coastguard Worker     IncorrectCommand();
367*f6dc9357SAndroid Build Coastguard Worker   }
368*f6dc9357SAndroid Build Coastguard Worker 
369*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
370*f6dc9357SAndroid Build Coastguard Worker   {
371*f6dc9357SAndroid Build Coastguard Worker     PrintHelp();
372*f6dc9357SAndroid Build Coastguard Worker     return 0;
373*f6dc9357SAndroid Build Coastguard Worker   }
374*f6dc9357SAndroid Build Coastguard Worker 
375*f6dc9357SAndroid Build Coastguard Worker   const bool stdInMode = parser[NKey::kStdIn].ThereIs;
376*f6dc9357SAndroid Build Coastguard Worker   const bool stdOutMode = parser[NKey::kStdOut].ThereIs;
377*f6dc9357SAndroid Build Coastguard Worker 
378*f6dc9357SAndroid Build Coastguard Worker   if (!stdOutMode)
379*f6dc9357SAndroid Build Coastguard Worker     PrintTitle();
380*f6dc9357SAndroid Build Coastguard Worker 
381*f6dc9357SAndroid Build Coastguard Worker   const UStringVector &params = parser.NonSwitchStrings;
382*f6dc9357SAndroid Build Coastguard Worker 
383*f6dc9357SAndroid Build Coastguard Worker   unsigned paramIndex = 0;
384*f6dc9357SAndroid Build Coastguard Worker   if (paramIndex >= params.Size())
385*f6dc9357SAndroid Build Coastguard Worker     IncorrectCommand();
386*f6dc9357SAndroid Build Coastguard Worker   const UString &command = params[paramIndex++];
387*f6dc9357SAndroid Build Coastguard Worker 
388*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CProperty> props2;
389*f6dc9357SAndroid Build Coastguard Worker   bool dictDefined = false;
390*f6dc9357SAndroid Build Coastguard Worker   UInt32 dict = (UInt32)(Int32)-1;
391*f6dc9357SAndroid Build Coastguard Worker 
392*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kDict].ThereIs)
393*f6dc9357SAndroid Build Coastguard Worker   {
394*f6dc9357SAndroid Build Coastguard Worker     UInt32 dictLog;
395*f6dc9357SAndroid Build Coastguard Worker     const UString &s = parser[NKey::kDict].PostStrings[0];
396*f6dc9357SAndroid Build Coastguard Worker     dictLog = GetNumber(s);
397*f6dc9357SAndroid Build Coastguard Worker     if (dictLog >= 32)
398*f6dc9357SAndroid Build Coastguard Worker       throw "unsupported dictionary size";
399*f6dc9357SAndroid Build Coastguard Worker     // we only want to use dictionary sizes that are powers of 2,
400*f6dc9357SAndroid Build Coastguard Worker     // because 7-zip only recognizes such dictionary sizes in the lzma header.#if 0
401*f6dc9357SAndroid Build Coastguard Worker #if 0
402*f6dc9357SAndroid Build Coastguard Worker     if (dictLog == 32)
403*f6dc9357SAndroid Build Coastguard Worker       dict = (UInt32)3840 << 20;
404*f6dc9357SAndroid Build Coastguard Worker     else
405*f6dc9357SAndroid Build Coastguard Worker #endif
406*f6dc9357SAndroid Build Coastguard Worker     dict = (UInt32)1 << dictLog;
407*f6dc9357SAndroid Build Coastguard Worker     dictDefined = true;
408*f6dc9357SAndroid Build Coastguard Worker     AddProp(props2, "d", s);
409*f6dc9357SAndroid Build Coastguard Worker   }
410*f6dc9357SAndroid Build Coastguard Worker 
411*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kLevel].ThereIs)
412*f6dc9357SAndroid Build Coastguard Worker   {
413*f6dc9357SAndroid Build Coastguard Worker     const UString &s = parser[NKey::kLevel].PostStrings[0];
414*f6dc9357SAndroid Build Coastguard Worker     /* UInt32 level = */ GetNumber(s);
415*f6dc9357SAndroid Build Coastguard Worker     AddProp(props2, "x", s);
416*f6dc9357SAndroid Build Coastguard Worker   }
417*f6dc9357SAndroid Build Coastguard Worker 
418*f6dc9357SAndroid Build Coastguard Worker   UString mf ("BT4");
419*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kMatchFinder].ThereIs)
420*f6dc9357SAndroid Build Coastguard Worker     mf = parser[NKey::kMatchFinder].PostStrings[0];
421*f6dc9357SAndroid Build Coastguard Worker 
422*f6dc9357SAndroid Build Coastguard Worker   UInt32 numThreads = (UInt32)(Int32)-1;
423*f6dc9357SAndroid Build Coastguard Worker 
424*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_ST
425*f6dc9357SAndroid Build Coastguard Worker 
426*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kMultiThread].ThereIs)
427*f6dc9357SAndroid Build Coastguard Worker   {
428*f6dc9357SAndroid Build Coastguard Worker     const UString &s = parser[NKey::kMultiThread].PostStrings[0];
429*f6dc9357SAndroid Build Coastguard Worker     if (s.IsEmpty())
430*f6dc9357SAndroid Build Coastguard Worker       numThreads = NWindows::NSystem::GetNumberOfProcessors();
431*f6dc9357SAndroid Build Coastguard Worker     else
432*f6dc9357SAndroid Build Coastguard Worker       numThreads = GetNumber(s);
433*f6dc9357SAndroid Build Coastguard Worker     AddProp(props2, "mt", s);
434*f6dc9357SAndroid Build Coastguard Worker   }
435*f6dc9357SAndroid Build Coastguard Worker 
436*f6dc9357SAndroid Build Coastguard Worker   #endif
437*f6dc9357SAndroid Build Coastguard Worker 
438*f6dc9357SAndroid Build Coastguard Worker 
439*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kMethod].ThereIs)
440*f6dc9357SAndroid Build Coastguard Worker   {
441*f6dc9357SAndroid Build Coastguard Worker     const UString &s = parser[NKey::kMethod].PostStrings[0];
442*f6dc9357SAndroid Build Coastguard Worker     if (s.IsEmpty() || s[0] != '=')
443*f6dc9357SAndroid Build Coastguard Worker       IncorrectCommand();
444*f6dc9357SAndroid Build Coastguard Worker     AddProp(props2, "m", s.Ptr(1));
445*f6dc9357SAndroid Build Coastguard Worker   }
446*f6dc9357SAndroid Build Coastguard Worker 
447*f6dc9357SAndroid Build Coastguard Worker   if (StringsAreEqualNoCase_Ascii(command, "b"))
448*f6dc9357SAndroid Build Coastguard Worker   {
449*f6dc9357SAndroid Build Coastguard Worker     UInt32 numIterations = 1;
450*f6dc9357SAndroid Build Coastguard Worker     if (paramIndex < params.Size())
451*f6dc9357SAndroid Build Coastguard Worker       numIterations = GetNumber(params[paramIndex++]);
452*f6dc9357SAndroid Build Coastguard Worker     if (params.Size() != paramIndex)
453*f6dc9357SAndroid Build Coastguard Worker       IncorrectCommand();
454*f6dc9357SAndroid Build Coastguard Worker 
455*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = BenchCon(props2, numIterations, stdout);
456*f6dc9357SAndroid Build Coastguard Worker 
457*f6dc9357SAndroid Build Coastguard Worker     if (res == S_OK)
458*f6dc9357SAndroid Build Coastguard Worker       return 0;
459*f6dc9357SAndroid Build Coastguard Worker     return Error_HRESULT("Benchmark error", res);
460*f6dc9357SAndroid Build Coastguard Worker   }
461*f6dc9357SAndroid Build Coastguard Worker 
462*f6dc9357SAndroid Build Coastguard Worker   {
463*f6dc9357SAndroid Build Coastguard Worker     UInt32 needParams = 3;
464*f6dc9357SAndroid Build Coastguard Worker     if (stdInMode) needParams--;
465*f6dc9357SAndroid Build Coastguard Worker     if (stdOutMode) needParams--;
466*f6dc9357SAndroid Build Coastguard Worker     if (needParams != params.Size())
467*f6dc9357SAndroid Build Coastguard Worker       IncorrectCommand();
468*f6dc9357SAndroid Build Coastguard Worker   }
469*f6dc9357SAndroid Build Coastguard Worker 
470*f6dc9357SAndroid Build Coastguard Worker   if (numThreads == (UInt32)(Int32)-1)
471*f6dc9357SAndroid Build Coastguard Worker     numThreads = 1;
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker   bool encodeMode = false;
474*f6dc9357SAndroid Build Coastguard Worker 
475*f6dc9357SAndroid Build Coastguard Worker   if (StringsAreEqualNoCase_Ascii(command, "e"))
476*f6dc9357SAndroid Build Coastguard Worker     encodeMode = true;
477*f6dc9357SAndroid Build Coastguard Worker   else if (!StringsAreEqualNoCase_Ascii(command, "d"))
478*f6dc9357SAndroid Build Coastguard Worker     IncorrectCommand();
479*f6dc9357SAndroid Build Coastguard Worker 
480*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialInStream> inStream;
481*f6dc9357SAndroid Build Coastguard Worker   CInFileStream *inStreamSpec = NULL;
482*f6dc9357SAndroid Build Coastguard Worker 
483*f6dc9357SAndroid Build Coastguard Worker   if (stdInMode)
484*f6dc9357SAndroid Build Coastguard Worker   {
485*f6dc9357SAndroid Build Coastguard Worker     inStream = new CStdInFileStream;
486*f6dc9357SAndroid Build Coastguard Worker     MY_SET_BINARY_MODE(stdin);
487*f6dc9357SAndroid Build Coastguard Worker   }
488*f6dc9357SAndroid Build Coastguard Worker   else
489*f6dc9357SAndroid Build Coastguard Worker   {
490*f6dc9357SAndroid Build Coastguard Worker     const UString &inputName = params[paramIndex++];
491*f6dc9357SAndroid Build Coastguard Worker     inStreamSpec = new CInFileStream;
492*f6dc9357SAndroid Build Coastguard Worker     inStream = inStreamSpec;
493*f6dc9357SAndroid Build Coastguard Worker     if (!inStreamSpec->Open(us2fs(inputName)))
494*f6dc9357SAndroid Build Coastguard Worker     {
495*f6dc9357SAndroid Build Coastguard Worker       PrintError2("Cannot open input file", inputName);
496*f6dc9357SAndroid Build Coastguard Worker       return 1;
497*f6dc9357SAndroid Build Coastguard Worker     }
498*f6dc9357SAndroid Build Coastguard Worker   }
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ISequentialOutStream> outStream;
501*f6dc9357SAndroid Build Coastguard Worker   COutFileStream *outStreamSpec = NULL;
502*f6dc9357SAndroid Build Coastguard Worker 
503*f6dc9357SAndroid Build Coastguard Worker   if (stdOutMode)
504*f6dc9357SAndroid Build Coastguard Worker   {
505*f6dc9357SAndroid Build Coastguard Worker     outStream = new CStdOutFileStream;
506*f6dc9357SAndroid Build Coastguard Worker     MY_SET_BINARY_MODE(stdout);
507*f6dc9357SAndroid Build Coastguard Worker   }
508*f6dc9357SAndroid Build Coastguard Worker   else
509*f6dc9357SAndroid Build Coastguard Worker   {
510*f6dc9357SAndroid Build Coastguard Worker     const UString &outputName = params[paramIndex++];
511*f6dc9357SAndroid Build Coastguard Worker     outStreamSpec = new COutFileStream;
512*f6dc9357SAndroid Build Coastguard Worker     outStream = outStreamSpec;
513*f6dc9357SAndroid Build Coastguard Worker     if (!outStreamSpec->Create_ALWAYS(us2fs(outputName)))
514*f6dc9357SAndroid Build Coastguard Worker     {
515*f6dc9357SAndroid Build Coastguard Worker       PrintError2("Cannot open output file", outputName);
516*f6dc9357SAndroid Build Coastguard Worker       return 1;
517*f6dc9357SAndroid Build Coastguard Worker     }
518*f6dc9357SAndroid Build Coastguard Worker   }
519*f6dc9357SAndroid Build Coastguard Worker 
520*f6dc9357SAndroid Build Coastguard Worker   bool fileSizeDefined = false;
521*f6dc9357SAndroid Build Coastguard Worker   UInt64 fileSize = 0;
522*f6dc9357SAndroid Build Coastguard Worker 
523*f6dc9357SAndroid Build Coastguard Worker   if (inStreamSpec)
524*f6dc9357SAndroid Build Coastguard Worker   {
525*f6dc9357SAndroid Build Coastguard Worker     if (!inStreamSpec->GetLength(fileSize))
526*f6dc9357SAndroid Build Coastguard Worker       throw "Cannot get file length";
527*f6dc9357SAndroid Build Coastguard Worker     fileSizeDefined = true;
528*f6dc9357SAndroid Build Coastguard Worker     if (!stdOutMode)
529*f6dc9357SAndroid Build Coastguard Worker       Print_Size("Input size:  ", fileSize);
530*f6dc9357SAndroid Build Coastguard Worker   }
531*f6dc9357SAndroid Build Coastguard Worker 
532*f6dc9357SAndroid Build Coastguard Worker   if (encodeMode && !dictDefined)
533*f6dc9357SAndroid Build Coastguard Worker   {
534*f6dc9357SAndroid Build Coastguard Worker     dict = (UInt32)1 << kDictSizeLog;
535*f6dc9357SAndroid Build Coastguard Worker     if (fileSizeDefined)
536*f6dc9357SAndroid Build Coastguard Worker     {
537*f6dc9357SAndroid Build Coastguard Worker       unsigned i;
538*f6dc9357SAndroid Build Coastguard Worker       for (i = 16; i < kDictSizeLog; i++)
539*f6dc9357SAndroid Build Coastguard Worker         if ((UInt32)((UInt32)1 << i) >= fileSize)
540*f6dc9357SAndroid Build Coastguard Worker           break;
541*f6dc9357SAndroid Build Coastguard Worker       dict = (UInt32)1 << i;
542*f6dc9357SAndroid Build Coastguard Worker     }
543*f6dc9357SAndroid Build Coastguard Worker   }
544*f6dc9357SAndroid Build Coastguard Worker 
545*f6dc9357SAndroid Build Coastguard Worker   if (parser[NKey::kFilter86].ThereIs)
546*f6dc9357SAndroid Build Coastguard Worker   {
547*f6dc9357SAndroid Build Coastguard Worker     /* -f86 switch is for x86 filtered mode: BCJ + LZMA.
548*f6dc9357SAndroid Build Coastguard Worker        It uses modified header format.
549*f6dc9357SAndroid Build Coastguard Worker        It's not recommended to use -f86 mode now.
550*f6dc9357SAndroid Build Coastguard Worker        You can use xz format instead, if you want to use filters */
551*f6dc9357SAndroid Build Coastguard Worker 
552*f6dc9357SAndroid Build Coastguard Worker     if (parser[NKey::kEOS].ThereIs || stdInMode)
553*f6dc9357SAndroid Build Coastguard Worker       throw "Cannot use stdin in this mode";
554*f6dc9357SAndroid Build Coastguard Worker 
555*f6dc9357SAndroid Build Coastguard Worker     size_t inSize = (size_t)fileSize;
556*f6dc9357SAndroid Build Coastguard Worker 
557*f6dc9357SAndroid Build Coastguard Worker     if (inSize != fileSize)
558*f6dc9357SAndroid Build Coastguard Worker       throw "File is too big";
559*f6dc9357SAndroid Build Coastguard Worker 
560*f6dc9357SAndroid Build Coastguard Worker     Byte *inBuffer = NULL;
561*f6dc9357SAndroid Build Coastguard Worker 
562*f6dc9357SAndroid Build Coastguard Worker     if (inSize != 0)
563*f6dc9357SAndroid Build Coastguard Worker     {
564*f6dc9357SAndroid Build Coastguard Worker       inBuffer = (Byte *)MyAlloc((size_t)inSize);
565*f6dc9357SAndroid Build Coastguard Worker       if (!inBuffer)
566*f6dc9357SAndroid Build Coastguard Worker         throw kCantAllocate;
567*f6dc9357SAndroid Build Coastguard Worker     }
568*f6dc9357SAndroid Build Coastguard Worker 
569*f6dc9357SAndroid Build Coastguard Worker     if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK)
570*f6dc9357SAndroid Build Coastguard Worker       throw "Cannot read";
571*f6dc9357SAndroid Build Coastguard Worker 
572*f6dc9357SAndroid Build Coastguard Worker     Byte *outBuffer = NULL;
573*f6dc9357SAndroid Build Coastguard Worker     size_t outSize;
574*f6dc9357SAndroid Build Coastguard Worker 
575*f6dc9357SAndroid Build Coastguard Worker     if (encodeMode)
576*f6dc9357SAndroid Build Coastguard Worker     {
577*f6dc9357SAndroid Build Coastguard Worker       // we allocate 105% of original size for output buffer
578*f6dc9357SAndroid Build Coastguard Worker       UInt64 outSize64 = fileSize / 20 * 21 + (1 << 16);
579*f6dc9357SAndroid Build Coastguard Worker 
580*f6dc9357SAndroid Build Coastguard Worker       outSize = (size_t)outSize64;
581*f6dc9357SAndroid Build Coastguard Worker 
582*f6dc9357SAndroid Build Coastguard Worker       if (outSize != outSize64)
583*f6dc9357SAndroid Build Coastguard Worker         throw "File is too big";
584*f6dc9357SAndroid Build Coastguard Worker 
585*f6dc9357SAndroid Build Coastguard Worker       if (outSize != 0)
586*f6dc9357SAndroid Build Coastguard Worker       {
587*f6dc9357SAndroid Build Coastguard Worker         outBuffer = (Byte *)MyAlloc((size_t)outSize);
588*f6dc9357SAndroid Build Coastguard Worker         if (!outBuffer)
589*f6dc9357SAndroid Build Coastguard Worker           throw kCantAllocate;
590*f6dc9357SAndroid Build Coastguard Worker       }
591*f6dc9357SAndroid Build Coastguard Worker 
592*f6dc9357SAndroid Build Coastguard Worker       int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize,
593*f6dc9357SAndroid Build Coastguard Worker           5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
594*f6dc9357SAndroid Build Coastguard Worker 
595*f6dc9357SAndroid Build Coastguard Worker       if (res != 0)
596*f6dc9357SAndroid Build Coastguard Worker       {
597*f6dc9357SAndroid Build Coastguard Worker         PrintError_int("Encode error", (int)res);
598*f6dc9357SAndroid Build Coastguard Worker         return 1;
599*f6dc9357SAndroid Build Coastguard Worker       }
600*f6dc9357SAndroid Build Coastguard Worker     }
601*f6dc9357SAndroid Build Coastguard Worker     else
602*f6dc9357SAndroid Build Coastguard Worker     {
603*f6dc9357SAndroid Build Coastguard Worker       UInt64 outSize64;
604*f6dc9357SAndroid Build Coastguard Worker 
605*f6dc9357SAndroid Build Coastguard Worker       if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0)
606*f6dc9357SAndroid Build Coastguard Worker         throw "data error";
607*f6dc9357SAndroid Build Coastguard Worker 
608*f6dc9357SAndroid Build Coastguard Worker       outSize = (size_t)outSize64;
609*f6dc9357SAndroid Build Coastguard Worker       if (outSize != outSize64)
610*f6dc9357SAndroid Build Coastguard Worker         throw "Unpack size is too big";
611*f6dc9357SAndroid Build Coastguard Worker       if (outSize != 0)
612*f6dc9357SAndroid Build Coastguard Worker       {
613*f6dc9357SAndroid Build Coastguard Worker         outBuffer = (Byte *)MyAlloc(outSize);
614*f6dc9357SAndroid Build Coastguard Worker         if (!outBuffer)
615*f6dc9357SAndroid Build Coastguard Worker           throw kCantAllocate;
616*f6dc9357SAndroid Build Coastguard Worker       }
617*f6dc9357SAndroid Build Coastguard Worker 
618*f6dc9357SAndroid Build Coastguard Worker       int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize);
619*f6dc9357SAndroid Build Coastguard Worker 
620*f6dc9357SAndroid Build Coastguard Worker       if (inSize != (size_t)fileSize)
621*f6dc9357SAndroid Build Coastguard Worker         throw "incorrect processed size";
622*f6dc9357SAndroid Build Coastguard Worker       if (res != 0)
623*f6dc9357SAndroid Build Coastguard Worker       {
624*f6dc9357SAndroid Build Coastguard Worker         PrintError_int("Decode error", (int)res);
625*f6dc9357SAndroid Build Coastguard Worker         return 1;
626*f6dc9357SAndroid Build Coastguard Worker       }
627*f6dc9357SAndroid Build Coastguard Worker     }
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker     if (WriteStream(outStream, outBuffer, outSize) != S_OK)
630*f6dc9357SAndroid Build Coastguard Worker       throw kWriteError;
631*f6dc9357SAndroid Build Coastguard Worker 
632*f6dc9357SAndroid Build Coastguard Worker     MyFree(outBuffer);
633*f6dc9357SAndroid Build Coastguard Worker     MyFree(inBuffer);
634*f6dc9357SAndroid Build Coastguard Worker   }
635*f6dc9357SAndroid Build Coastguard Worker   else
636*f6dc9357SAndroid Build Coastguard Worker   {
637*f6dc9357SAndroid Build Coastguard Worker 
638*f6dc9357SAndroid Build Coastguard Worker   CProgressPrint *progressSpec = NULL;
639*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressProgressInfo> progress;
640*f6dc9357SAndroid Build Coastguard Worker 
641*f6dc9357SAndroid Build Coastguard Worker   if (!stdOutMode)
642*f6dc9357SAndroid Build Coastguard Worker   {
643*f6dc9357SAndroid Build Coastguard Worker     progressSpec = new CProgressPrint;
644*f6dc9357SAndroid Build Coastguard Worker     progress = progressSpec;
645*f6dc9357SAndroid Build Coastguard Worker   }
646*f6dc9357SAndroid Build Coastguard Worker 
647*f6dc9357SAndroid Build Coastguard Worker   if (encodeMode)
648*f6dc9357SAndroid Build Coastguard Worker   {
649*f6dc9357SAndroid Build Coastguard Worker     NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder;
650*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressCoder> encoder = encoderSpec;
651*f6dc9357SAndroid Build Coastguard Worker 
652*f6dc9357SAndroid Build Coastguard Worker     UInt32 pb = 2;
653*f6dc9357SAndroid Build Coastguard Worker     UInt32 lc = 3; // = 0; for 32-bit data
654*f6dc9357SAndroid Build Coastguard Worker     UInt32 lp = 0; // = 2; for 32-bit data
655*f6dc9357SAndroid Build Coastguard Worker     UInt32 algo = 1;
656*f6dc9357SAndroid Build Coastguard Worker     UInt32 fb = 128;
657*f6dc9357SAndroid Build Coastguard Worker     UInt32 mc = 16 + fb / 2;
658*f6dc9357SAndroid Build Coastguard Worker     bool mcDefined = false;
659*f6dc9357SAndroid Build Coastguard Worker 
660*f6dc9357SAndroid Build Coastguard Worker     bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
661*f6dc9357SAndroid Build Coastguard Worker 
662*f6dc9357SAndroid Build Coastguard Worker     ParseUInt32(parser, NKey::kAlgo, algo);
663*f6dc9357SAndroid Build Coastguard Worker     ParseUInt32(parser, NKey::kFb, fb);
664*f6dc9357SAndroid Build Coastguard Worker     ParseUInt32(parser, NKey::kLc, lc);
665*f6dc9357SAndroid Build Coastguard Worker     ParseUInt32(parser, NKey::kLp, lp);
666*f6dc9357SAndroid Build Coastguard Worker     ParseUInt32(parser, NKey::kPb, pb);
667*f6dc9357SAndroid Build Coastguard Worker 
668*f6dc9357SAndroid Build Coastguard Worker     mcDefined = parser[NKey::kMc].ThereIs;
669*f6dc9357SAndroid Build Coastguard Worker     if (mcDefined)
670*f6dc9357SAndroid Build Coastguard Worker       mc = GetNumber(parser[NKey::kMc].PostStrings[0]);
671*f6dc9357SAndroid Build Coastguard Worker 
672*f6dc9357SAndroid Build Coastguard Worker     const PROPID propIDs[] =
673*f6dc9357SAndroid Build Coastguard Worker     {
674*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kDictionarySize,
675*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kPosStateBits,
676*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kLitContextBits,
677*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kLitPosBits,
678*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kAlgorithm,
679*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kNumFastBytes,
680*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kMatchFinder,
681*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kEndMarker,
682*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kNumThreads,
683*f6dc9357SAndroid Build Coastguard Worker       NCoderPropID::kMatchFinderCycles,
684*f6dc9357SAndroid Build Coastguard Worker     };
685*f6dc9357SAndroid Build Coastguard Worker 
686*f6dc9357SAndroid Build Coastguard Worker     const unsigned kNumPropsMax = Z7_ARRAY_SIZE(propIDs);
687*f6dc9357SAndroid Build Coastguard Worker 
688*f6dc9357SAndroid Build Coastguard Worker     PROPVARIANT props[kNumPropsMax];
689*f6dc9357SAndroid Build Coastguard Worker     for (int p = 0; p < 6; p++)
690*f6dc9357SAndroid Build Coastguard Worker       props[p].vt = VT_UI4;
691*f6dc9357SAndroid Build Coastguard Worker 
692*f6dc9357SAndroid Build Coastguard Worker     props[0].ulVal = (UInt32)dict;
693*f6dc9357SAndroid Build Coastguard Worker     props[1].ulVal = (UInt32)pb;
694*f6dc9357SAndroid Build Coastguard Worker     props[2].ulVal = (UInt32)lc;
695*f6dc9357SAndroid Build Coastguard Worker     props[3].ulVal = (UInt32)lp;
696*f6dc9357SAndroid Build Coastguard Worker     props[4].ulVal = (UInt32)algo;
697*f6dc9357SAndroid Build Coastguard Worker     props[5].ulVal = (UInt32)fb;
698*f6dc9357SAndroid Build Coastguard Worker 
699*f6dc9357SAndroid Build Coastguard Worker     props[6].vt = VT_BSTR;
700*f6dc9357SAndroid Build Coastguard Worker     props[6].bstrVal = const_cast<BSTR>((const wchar_t *)mf);
701*f6dc9357SAndroid Build Coastguard Worker 
702*f6dc9357SAndroid Build Coastguard Worker     props[7].vt = VT_BOOL;
703*f6dc9357SAndroid Build Coastguard Worker     props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
704*f6dc9357SAndroid Build Coastguard Worker 
705*f6dc9357SAndroid Build Coastguard Worker     props[8].vt = VT_UI4;
706*f6dc9357SAndroid Build Coastguard Worker     props[8].ulVal = (UInt32)numThreads;
707*f6dc9357SAndroid Build Coastguard Worker 
708*f6dc9357SAndroid Build Coastguard Worker     // it must be last in property list
709*f6dc9357SAndroid Build Coastguard Worker     props[9].vt = VT_UI4;
710*f6dc9357SAndroid Build Coastguard Worker     props[9].ulVal = (UInt32)mc;
711*f6dc9357SAndroid Build Coastguard Worker 
712*f6dc9357SAndroid Build Coastguard Worker     unsigned numProps = kNumPropsMax;
713*f6dc9357SAndroid Build Coastguard Worker     if (!mcDefined)
714*f6dc9357SAndroid Build Coastguard Worker       numProps--;
715*f6dc9357SAndroid Build Coastguard Worker 
716*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = encoderSpec->SetCoderProperties(propIDs, props, numProps);
717*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
718*f6dc9357SAndroid Build Coastguard Worker       return Error_HRESULT("incorrect encoder properties", res);
719*f6dc9357SAndroid Build Coastguard Worker 
720*f6dc9357SAndroid Build Coastguard Worker     if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
721*f6dc9357SAndroid Build Coastguard Worker       throw kWriteError;
722*f6dc9357SAndroid Build Coastguard Worker 
723*f6dc9357SAndroid Build Coastguard Worker     bool fileSizeWasUsed = true;
724*f6dc9357SAndroid Build Coastguard Worker     if (eos || stdInMode)
725*f6dc9357SAndroid Build Coastguard Worker     {
726*f6dc9357SAndroid Build Coastguard Worker       fileSize = (UInt64)(Int64)-1;
727*f6dc9357SAndroid Build Coastguard Worker       fileSizeWasUsed = false;
728*f6dc9357SAndroid Build Coastguard Worker     }
729*f6dc9357SAndroid Build Coastguard Worker 
730*f6dc9357SAndroid Build Coastguard Worker     {
731*f6dc9357SAndroid Build Coastguard Worker       Byte temp[8];
732*f6dc9357SAndroid Build Coastguard Worker       for (int i = 0; i < 8; i++)
733*f6dc9357SAndroid Build Coastguard Worker         temp[i]= (Byte)(fileSize >> (8 * i));
734*f6dc9357SAndroid Build Coastguard Worker       if (WriteStream(outStream, temp, 8) != S_OK)
735*f6dc9357SAndroid Build Coastguard Worker         throw kWriteError;
736*f6dc9357SAndroid Build Coastguard Worker     }
737*f6dc9357SAndroid Build Coastguard Worker 
738*f6dc9357SAndroid Build Coastguard Worker     res = encoder->Code(inStream, outStream, NULL, NULL, progress);
739*f6dc9357SAndroid Build Coastguard Worker     if (progressSpec)
740*f6dc9357SAndroid Build Coastguard Worker       progressSpec->ClosePrint();
741*f6dc9357SAndroid Build Coastguard Worker 
742*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
743*f6dc9357SAndroid Build Coastguard Worker       return Error_HRESULT("Encoding error", res);
744*f6dc9357SAndroid Build Coastguard Worker 
745*f6dc9357SAndroid Build Coastguard Worker     UInt64 processedSize = encoderSpec->GetInputProcessedSize();
746*f6dc9357SAndroid Build Coastguard Worker 
747*f6dc9357SAndroid Build Coastguard Worker     if (fileSizeWasUsed && processedSize != fileSize)
748*f6dc9357SAndroid Build Coastguard Worker       throw "Incorrect size of processed data";
749*f6dc9357SAndroid Build Coastguard Worker   }
750*f6dc9357SAndroid Build Coastguard Worker   else
751*f6dc9357SAndroid Build Coastguard Worker   {
752*f6dc9357SAndroid Build Coastguard Worker     NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder;
753*f6dc9357SAndroid Build Coastguard Worker     CMyComPtr<ICompressCoder> decoder = decoderSpec;
754*f6dc9357SAndroid Build Coastguard Worker 
755*f6dc9357SAndroid Build Coastguard Worker     decoderSpec->FinishStream = true;
756*f6dc9357SAndroid Build Coastguard Worker 
757*f6dc9357SAndroid Build Coastguard Worker     const unsigned kPropertiesSize = 5;
758*f6dc9357SAndroid Build Coastguard Worker     Byte header[kPropertiesSize + 8];
759*f6dc9357SAndroid Build Coastguard Worker 
760*f6dc9357SAndroid Build Coastguard Worker     if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK)
761*f6dc9357SAndroid Build Coastguard Worker       throw kReadError;
762*f6dc9357SAndroid Build Coastguard Worker 
763*f6dc9357SAndroid Build Coastguard Worker     if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK)
764*f6dc9357SAndroid Build Coastguard Worker       throw "SetDecoderProperties error";
765*f6dc9357SAndroid Build Coastguard Worker 
766*f6dc9357SAndroid Build Coastguard Worker     UInt64 unpackSize = 0;
767*f6dc9357SAndroid Build Coastguard Worker     for (unsigned i = 0; i < 8; i++)
768*f6dc9357SAndroid Build Coastguard Worker       unpackSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i);
769*f6dc9357SAndroid Build Coastguard Worker 
770*f6dc9357SAndroid Build Coastguard Worker     bool unpackSizeDefined = (unpackSize != (UInt64)(Int64)-1);
771*f6dc9357SAndroid Build Coastguard Worker 
772*f6dc9357SAndroid Build Coastguard Worker     HRESULT res = decoder->Code(inStream, outStream, NULL, unpackSizeDefined ? &unpackSize : NULL, progress);
773*f6dc9357SAndroid Build Coastguard Worker     if (progressSpec)
774*f6dc9357SAndroid Build Coastguard Worker       progressSpec->ClosePrint();
775*f6dc9357SAndroid Build Coastguard Worker 
776*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
777*f6dc9357SAndroid Build Coastguard Worker     {
778*f6dc9357SAndroid Build Coastguard Worker       if (res == S_FALSE)
779*f6dc9357SAndroid Build Coastguard Worker       {
780*f6dc9357SAndroid Build Coastguard Worker         PrintError("Decoding error");
781*f6dc9357SAndroid Build Coastguard Worker         return 1;
782*f6dc9357SAndroid Build Coastguard Worker       }
783*f6dc9357SAndroid Build Coastguard Worker       return Error_HRESULT("Decoding error", res);
784*f6dc9357SAndroid Build Coastguard Worker     }
785*f6dc9357SAndroid Build Coastguard Worker 
786*f6dc9357SAndroid Build Coastguard Worker     if (unpackSizeDefined && unpackSize != decoderSpec->GetOutputProcessedSize())
787*f6dc9357SAndroid Build Coastguard Worker       throw "incorrect uncompressed size in header";
788*f6dc9357SAndroid Build Coastguard Worker   }
789*f6dc9357SAndroid Build Coastguard Worker   }
790*f6dc9357SAndroid Build Coastguard Worker 
791*f6dc9357SAndroid Build Coastguard Worker   if (outStreamSpec)
792*f6dc9357SAndroid Build Coastguard Worker   {
793*f6dc9357SAndroid Build Coastguard Worker     if (!stdOutMode)
794*f6dc9357SAndroid Build Coastguard Worker       Print_Size("Output size: ", outStreamSpec->ProcessedSize);
795*f6dc9357SAndroid Build Coastguard Worker     if (outStreamSpec->Close() != S_OK)
796*f6dc9357SAndroid Build Coastguard Worker       throw "File closing error";
797*f6dc9357SAndroid Build Coastguard Worker   }
798*f6dc9357SAndroid Build Coastguard Worker 
799*f6dc9357SAndroid Build Coastguard Worker   return 0;
800*f6dc9357SAndroid Build Coastguard Worker }
801*f6dc9357SAndroid Build Coastguard Worker 
802*f6dc9357SAndroid Build Coastguard Worker int Z7_CDECL main(int numArgs, const char *args[])
803*f6dc9357SAndroid Build Coastguard Worker {
804*f6dc9357SAndroid Build Coastguard Worker   NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
805*f6dc9357SAndroid Build Coastguard Worker 
806*f6dc9357SAndroid Build Coastguard Worker   try { return main2(numArgs, args); }
807*f6dc9357SAndroid Build Coastguard Worker   catch (const char *s)
808*f6dc9357SAndroid Build Coastguard Worker   {
809*f6dc9357SAndroid Build Coastguard Worker     PrintError(s);
810*f6dc9357SAndroid Build Coastguard Worker     return 1;
811*f6dc9357SAndroid Build Coastguard Worker   }
812*f6dc9357SAndroid Build Coastguard Worker   catch(...)
813*f6dc9357SAndroid Build Coastguard Worker   {
814*f6dc9357SAndroid Build Coastguard Worker     PrintError("Unknown Error");
815*f6dc9357SAndroid Build Coastguard Worker     return 1;
816*f6dc9357SAndroid Build Coastguard Worker   }
817*f6dc9357SAndroid Build Coastguard Worker }
818