1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// LzmaAlone.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <stdio.h>
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#if (defined(_WIN32) || defined(OS2) || defined(MSDOS)) && !defined(UNDER_CE)
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <fcntl.h>
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <io.h>
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define MY_SET_BINARY_MODE(file)
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// #include "../../../Common/MyWindows.h"
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/MyInitGuid.h"
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/7zVersion.h"
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/Alloc.h"
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/Lzma86.h"
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Windows/NtCheck.h"
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _7ZIP_ST
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Windows/System.h"
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/CommandLineParser.h"
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/StringConvert.h"
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../Common/StringToInt.h"
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/FileStreams.h"
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamUtils.h"
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Compress/LzmaDecoder.h"
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Compress/LzmaEncoder.h"
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../UI/Console/BenchCon.h"
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
41baa3858d3f5d128a5c8466b700098109edcad5f2repo syncusing namespace NCommandLineParser;
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kCantAllocate = "Can not allocate memory";
44baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kReadError = "Read error";
45baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kWriteError = "Write error";
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NKey {
48baa3858d3f5d128a5c8466b700098109edcad5f2repo syncenum Enum
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kHelp1 = 0,
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kHelp2,
52cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  kMethod,
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  kLevel,
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kAlgo,
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kDict,
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kFb,
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kMc,
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kLc,
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kLp,
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kPb,
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kMatchFinder,
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kMultiThread,
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kEOS,
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kStdIn,
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kStdOut,
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  kFilter86
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
70baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const CSwitchForm kSwitchForms[] =
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "?",  NSwitchType::kSimple, false },
73cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "H",  NSwitchType::kSimple, false },
74cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "MM", NSwitchType::kString, false, 1 },
75cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "X", NSwitchType::kString, false, 1 },
76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "A", NSwitchType::kString, false, 1 },
77cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "D", NSwitchType::kString, false, 1 },
78cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "FB", NSwitchType::kString, false, 1 },
79cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "MC", NSwitchType::kString, false, 1 },
80cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "LC", NSwitchType::kString, false, 1 },
81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "LP", NSwitchType::kString, false, 1 },
82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "PB", NSwitchType::kString, false, 1 },
83cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "MF", NSwitchType::kString, false, 1 },
84cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "MT", NSwitchType::kString, false, 0 },
85cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "EOS", NSwitchType::kSimple, false },
86cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "SI",  NSwitchType::kSimple, false },
87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "SO",  NSwitchType::kSimple, false },
88cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { "F86",  NSwitchType::kChar, false, 0, "+" }
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync};
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
91baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void PrintMessage(const char *s)
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fputs(s, stderr);
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
96baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void PrintHelp()
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintMessage("\nUsage:  LZMA <e|d> inputFile outputFile [<switches>...]\n"
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync             "  e: encode file\n"
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync             "  d: decode file\n"
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync             "  b: Benchmark\n"
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "<Switches>\n"
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n"
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -d{N}:  set dictionary size - [12, 30], default: 23 (8MB)\n"
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -mc{N}: set number of cycles for match finder\n"
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -pb{N}: set number of pos bits - [0, 4], default: 2\n"
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n"
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -mt{N}: set number of CPU threads\n"
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -eos:   write End Of Stream marker\n"
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -si:    read data from stdin\n"
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    "  -so:    write data to stdout\n"
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    );
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
118baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void PrintHelpAndExit(const char *s)
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fprintf(stderr, "\nError: %s\n\n", s);
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintHelp();
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  throw -1;
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
125baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void IncorrectCommand()
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintHelpAndExit("Incorrect command");
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
130baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void WriteArgumentsToStringList(int numArgs, const char *args[], UStringVector &strings)
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 1; i < numArgs; i++)
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    strings.Add(MultiByteToUnicodeString(args[i]));
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
136baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool GetNumber(const wchar_t *s, UInt32 &value)
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  value = 0;
139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (*s == 0)
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const wchar_t *end;
142cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  value = ConvertStringToUInt32(s, &end);
143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return *end == 0;
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void ParseUInt32(const CParser &parser, unsigned index, UInt32 &res)
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (parser[index].ThereIs)
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!GetNumber(parser[index].PostStrings[0], res))
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IncorrectCommand();
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NT_CHECK_FAIL_ACTION PrintMessage("Unsupported Windows version"); return 1;
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
155baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint main2(int numArgs, const char *args[])
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NT_CHECK
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PrintMessage("\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (numArgs == 1)
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintHelp();
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 0;
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (unsupportedTypes)
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintMessage("Unsupported base types. Edit Common/Types.h and recompile");
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 1;
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UStringVector commandStrings;
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  WriteArgumentsToStringList(numArgs, args, commandStrings);
176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CParser parser(ARRAY_SIZE(kSwitchForms));
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  try
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    parser.ParseStrings(kSwitchForms, commandStrings);
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  catch(...)
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IncorrectCommand();
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintHelp();
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 0;
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  unsigned paramIndex = 0;
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (paramIndex >= nonSwitchStrings.Size())
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IncorrectCommand();
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  const UString &command = nonSwitchStrings[paramIndex++];
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  CObjectVector<CProperty> props;
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool dictDefined = false;
201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 dict = (UInt32)(Int32)-1;
202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (parser[NKey::kDict].ThereIs)
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 dicLog;
205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const UString &s = parser[NKey::kDict].PostStrings[0];
206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!GetNumber(s, dicLog))
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IncorrectCommand();
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dict = 1 << dicLog;
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dictDefined = true;
210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CProperty prop;
211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Name = L"d";
212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Value = s;
213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    props.Add(prop);
214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (parser[NKey::kLevel].ThereIs)
216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 level = 5;
218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const UString &s = parser[NKey::kLevel].PostStrings[0];
219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!GetNumber(s, level))
220cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      IncorrectCommand();
221cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CProperty prop;
222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Name = L"x";
223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Value = s;
224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    props.Add(prop);
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString mf = L"BT4";
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (parser[NKey::kMatchFinder].ThereIs)
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mf = parser[NKey::kMatchFinder].PostStrings[0];
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
230cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 numThreads = (UInt32)(Int32)-1;
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (parser[NKey::kMultiThread].ThereIs)
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UString &s = parser[NKey::kMultiThread].PostStrings[0];
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (s.IsEmpty())
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numThreads = numCPUs;
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!GetNumber(s, numThreads))
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        IncorrectCommand();
242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CProperty prop;
243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Name = L"mt";
244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Value = s;
245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    props.Add(prop);
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (parser[NKey::kMethod].ThereIs)
250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UString s = parser[NKey::kMethod].PostStrings[0];
252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (s.IsEmpty() || s[0] != '=')
253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      IncorrectCommand();
254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    CProperty prop;
255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Name = L"m";
256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    prop.Value = s.Ptr(1);
257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    props.Add(prop);
258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (MyStringCompareNoCase(command, L"b") == 0)
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt32 kNumDefaultItereations = 1;
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 numIterations = kNumDefaultItereations;
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (paramIndex < nonSwitchStrings.Size())
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          numIterations = kNumDefaultItereations;
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT res = BenchCon(props, numIterations, stderr);
270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (res != S_OK)
271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (res != E_ABORT)
273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        PrintMessage("Benchmark Error");
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return 1;
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return 0;
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (numThreads == (UInt32)(Int32)-1)
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    numThreads = 1;
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool encodeMode = false;
285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (MyStringCompareNoCase(command, L"e") == 0)
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encodeMode = true;
287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else if (MyStringCompareNoCase(command, L"d") == 0)
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encodeMode = false;
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    IncorrectCommand();
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool stdInMode = parser[NKey::kStdIn].ThereIs;
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool stdOutMode = parser[NKey::kStdOut].ThereIs;
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialInStream> inStream;
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CInFileStream *inStreamSpec = 0;
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (stdInMode)
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    inStream = new CStdInFileStream;
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MY_SET_BINARY_MODE(stdin);
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (paramIndex >= nonSwitchStrings.Size())
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IncorrectCommand();
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UString &inputName = nonSwitchStrings[paramIndex++];
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    inStreamSpec = new CInFileStream;
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    inStream = inStreamSpec;
309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!inStreamSpec->Open(us2fs(inputName)))
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fprintf(stderr, "\nError: can not open input file %s\n",
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          (const char *)GetOemString(inputName));
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMyComPtr<ISequentialOutStream> outStream;
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  COutFileStream *outStreamSpec = NULL;
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (stdOutMode)
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outStream = new CStdOutFileStream;
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MY_SET_BINARY_MODE(stdout);
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (paramIndex >= nonSwitchStrings.Size())
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IncorrectCommand();
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UString &outputName = nonSwitchStrings[paramIndex++];
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outStreamSpec = new COutFileStream;
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outStream = outStreamSpec;
331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!outStreamSpec->Create(us2fs(outputName), true))
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fprintf(stderr, "\nError: can not open output file %s\n",
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        (const char *)GetOemString(outputName));
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (parser[NKey::kFilter86].ThereIs)
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // -f86 switch is for x86 filtered mode: BCJ + LZMA.
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (parser[NKey::kEOS].ThereIs || stdInMode)
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw "Can not use stdin in this mode";
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 fileSize;
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    inStreamSpec->File.GetLength(fileSize);
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (fileSize > 0xF0000000)
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw "File is too big";
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t inSize = (size_t)fileSize;
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte *inBuffer = 0;
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (inSize != 0)
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      inBuffer = (Byte *)MyAlloc((size_t)inSize);
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (inBuffer == 0)
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw kCantAllocate;
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ReadStream_FAIL(inStream, inBuffer, inSize) != S_OK)
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw "Can not read";
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte *outBuffer = 0;
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t outSize;
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (encodeMode)
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // we allocate 105% of original size for output buffer
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (outSize != 0)
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        outBuffer = (Byte *)MyAlloc((size_t)outSize);
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (outBuffer == 0)
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          throw kCantAllocate;
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!dictDefined)
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        dict = 1 << 23;
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      int res = Lzma86_Encode(outBuffer, &outSize, inBuffer, inSize,
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          5, dict, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res != 0)
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        fprintf(stderr, "\nEncoder error = %d\n", (int)res);
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return 1;
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt64 outSize64;
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0)
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw "data error";
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outSize = (size_t)outSize64;
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (outSize != outSize64)
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw "too big";
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (outSize != 0)
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        outBuffer = (Byte *)MyAlloc(outSize);
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (outBuffer == 0)
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          throw kCantAllocate;
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      int res = Lzma86_Decode(outBuffer, &outSize, inBuffer, &inSize);
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (inSize != (size_t)fileSize)
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw "incorrect processed size";
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res != 0)
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        throw "LzmaDecoder error";
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (WriteStream(outStream, outBuffer, outSize) != S_OK)
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw kWriteError;
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MyFree(outBuffer);
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MyFree(inBuffer);
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 0;
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 fileSize;
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (encodeMode)
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCompress::NLzma::CEncoder *encoderSpec = new NCompress::NLzma::CEncoder;
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICompressCoder> encoder = encoderSpec;
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!dictDefined)
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      dict = 1 << 23;
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 pb = 2;
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 lc = 3; // = 0; for 32-bit data
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 lp = 0; // = 2; for 32-bit data
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 algo = 1;
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 fb = 128;
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 mc = 16 + fb / 2;
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool mcDefined = false;
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ParseUInt32(parser, NKey::kAlgo, algo);
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ParseUInt32(parser, NKey::kFb, fb);
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ParseUInt32(parser, NKey::kLc, lc);
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ParseUInt32(parser, NKey::kLp, lp);
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ParseUInt32(parser, NKey::kPb, pb);
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mcDefined = parser[NKey::kMc].ThereIs;
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (mcDefined)
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc))
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        IncorrectCommand();
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const PROPID propIDs[] =
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kDictionarySize,
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kPosStateBits,
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kLitContextBits,
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kLitPosBits,
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kAlgorithm,
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kNumFastBytes,
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kMatchFinder,
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kEndMarker,
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kNumThreads,
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NCoderPropID::kMatchFinderCycles,
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    };
453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    const unsigned kNumPropsMax = ARRAY_SIZE(propIDs);
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PROPVARIANT props[kNumPropsMax];
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int p = 0; p < 6; p++)
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      props[p].vt = VT_UI4;
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[0].ulVal = (UInt32)dict;
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[1].ulVal = (UInt32)pb;
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[2].ulVal = (UInt32)lc;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[3].ulVal = (UInt32)lp;
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[4].ulVal = (UInt32)algo;
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[5].ulVal = (UInt32)fb;
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[6].vt = VT_BSTR;
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[6].bstrVal = const_cast<BSTR>((const wchar_t *)mf);
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[7].vt = VT_BOOL;
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[8].vt = VT_UI4;
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[8].ulVal = (UInt32)numThreads;
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // it must be last in property list
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[9].vt = VT_UI4;
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    props[9].ulVal = (UInt32)mc;
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    unsigned numProps = kNumPropsMax;
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!mcDefined)
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      numProps--;
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (encoderSpec->SetCoderProperties(propIDs, props, numProps) != S_OK)
484baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      IncorrectCommand();
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    encoderSpec->WriteCoderProperties(outStream);
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (eos || stdInMode)
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileSize = (UInt64)(Int64)-1;
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      inStreamSpec->File.GetLength(fileSize);
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int i = 0; i < 8; i++)
493baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      Byte b = Byte(fileSize >> (8 * i));
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (outStream->Write(&b, 1, 0) != S_OK)
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        PrintMessage(kWriteError);
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return 1;
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (result == E_OUTOFMEMORY)
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintMessage("\nError: Can not allocate memory\n");
505baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else if (result != S_OK)
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      fprintf(stderr, "\nEncoder error = %X\n", (unsigned)result);
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NCompress::NLzma::CDecoder *decoderSpec = new NCompress::NLzma::CDecoder;
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMyComPtr<ICompressCoder> decoder = decoderSpec;
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    decoderSpec->FinishStream = true;
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt32 kPropertiesSize = 5;
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte header[kPropertiesSize + 8];
520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK)
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintMessage(kReadError);
523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK)
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintMessage("SetDecoderProperties error");
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fileSize = 0;
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (int i = 0; i < 8; i++)
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i);
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    bool isSizeDefined = (fileSize != (UInt64)(Int64)-1);
535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    HRESULT res = decoder->Code(inStream, outStream, 0, isSizeDefined ? &fileSize : NULL, 0) != S_OK;
536cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (res != S_OK)
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintMessage("Decoder error");
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
541cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (isSizeDefined && decoderSpec->GetOutputProcessedSize() != fileSize)
542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      PrintMessage("Error: incorrect uncompressed size in header");
544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return 1;
545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (outStreamSpec != NULL)
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (outStreamSpec->Close() != S_OK)
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      PrintMessage("File closing error");
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 1;
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return 0;
556baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
558baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint MY_CDECL main(int numArgs, const char *args[])
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  try { return main2(numArgs, args); }
561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  catch (const char *s)
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fprintf(stderr, "\nError: %s\n", s);
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 1;
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  catch(...)
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PrintMessage("\nError\n");
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return 1;
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
572