~ubuntu-branches/ubuntu/precise/p7zip/precise-updates

« back to all changes in this revision

Viewing changes to CPP/7zip/Compress/PPMD_Alone/PPMDAlone.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mohammed Adnène Trojette
  • Date: 2009-02-14 20:12:27 UTC
  • mfrom: (1.1.11 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090214201227-go63qxm9ozfdma60
Tags: 4.65~dfsg.1-1
* New upstream release.
* Remove wx2.8 Build-Depends added by mistakes (7zG is not yet
  intended to be built).
* Use dh_clean without -k.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// PPMDAlone.cpp
2
 
 
3
 
#include "StdAfx.h"
4
 
 
5
 
#include "../../../Common/MyWindows.h"
6
 
#include "../../../Common/MyInitGuid.h"
7
 
 
8
 
#include <stdio.h>
9
 
 
10
 
#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
11
 
#include <fcntl.h>
12
 
#include <io.h>
13
 
#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)
14
 
#else
15
 
#define MY_SET_BINARY_MODE(file)
16
 
#endif
17
 
 
18
 
#include "../../../Common/CommandLineParser.h"
19
 
#include "../../../Common/StringConvert.h"
20
 
#include "../../../Common/StringToInt.h"
21
 
 
22
 
#include "../../Common/FileStreams.h"
23
 
#include "../../Common/StreamUtils.h"
24
 
 
25
 
#include "../PPMD/PPMDDecoder.h"
26
 
#include "../PPMD/PPMDEncoder.h"
27
 
 
28
 
using namespace NCommandLineParser;
29
 
 
30
 
#ifdef _WIN32
31
 
bool g_IsNT = false;
32
 
static inline bool IsItWindowsNT()
33
 
{
34
 
  OSVERSIONINFO versionInfo;
35
 
  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
36
 
  if (!::GetVersionEx(&versionInfo)) 
37
 
    return false;
38
 
  return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
39
 
}
40
 
#endif
41
 
 
42
 
static const char *kCantAllocate = "Can not allocate memory";
43
 
static const char *kReadError = "Read error";
44
 
static const char *kWriteError = "Write error";
45
 
 
46
 
namespace NKey {
47
 
enum Enum
48
 
{
49
 
  kHelp1 = 0,
50
 
  kHelp2,
51
 
  kOrder,
52
 
  kUsedMemorySize,
53
 
  kStdIn,
54
 
  kStdOut
55
 
};
56
 
}
57
 
 
58
 
static const CSwitchForm kSwitchForms[] = 
59
 
{
60
 
  { L"?",  NSwitchType::kSimple, false },
61
 
  { L"H",  NSwitchType::kSimple, false },
62
 
  { L"O", NSwitchType::kUnLimitedPostString, false, 1 },
63
 
  { L"M", NSwitchType::kUnLimitedPostString, false, 1 },
64
 
  { L"SI",  NSwitchType::kSimple, false },
65
 
  { L"SO",  NSwitchType::kSimple, false }
66
 
};
67
 
 
68
 
static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
69
 
 
70
 
static void PrintHelp()
71
 
{
72
 
  fprintf(stderr, "\nUsage:  PPMD <e|d> inputFile outputFile [<switches>...]\n"
73
 
             "  e: encode file\n"
74
 
             "  d: decode file\n"
75
 
/*
76
 
             "  b: Benchmark\n"
77
 
*/
78
 
    "<Switches>\n"
79
 
    "  -o{N}:  set order - [4, 32], default: 4\n"
80
 
    "  -m{N}:  set memory size - [4,512], default: 4 (4 MB)\n"
81
 
    "  -si:    read data from stdin (only with d)\n"
82
 
    "  -so:    write data to stdout\n"
83
 
    );
84
 
}
85
 
 
86
 
static void PrintHelpAndExit(const char *s)
87
 
{
88
 
  fprintf(stderr, "\nError: %s\n\n", s);
89
 
  PrintHelp();
90
 
  throw -1;
91
 
}
92
 
 
93
 
static void IncorrectCommand()
94
 
{
95
 
  PrintHelpAndExit("Incorrect command");
96
 
}
97
 
 
98
 
static void WriteArgumentsToStringList(int numArguments, const char *arguments[], 
99
 
    UStringVector &strings)
100
 
{
101
 
  for(int i = 1; i < numArguments; i++)
102
 
    strings.Add(MultiByteToUnicodeString(arguments[i]));
103
 
}
104
 
 
105
 
static bool GetNumber(const wchar_t *s, UInt32 &value)
106
 
{
107
 
  value = 0;
108
 
  if (MyStringLen(s) == 0)
109
 
    return false;
110
 
  const wchar_t *end;
111
 
  UInt64 res = ConvertStringToUInt64(s, &end);
112
 
  if (*end != L'\0')
113
 
    return false;
114
 
  if (res > 0xFFFFFFFF)
115
 
    return false;
116
 
  value = UInt32(res);
117
 
  return true;
118
 
}
119
 
 
120
 
int main2(int n, const char *args[])
121
 
{
122
 
  #ifdef _WIN32
123
 
  g_IsNT = IsItWindowsNT();
124
 
  #endif
125
 
 
126
 
  fprintf(stderr, "\nPPMD 4.49 Copyright (c) 1999-2007 Igor Pavlov  2007-07-05\n");
127
 
 
128
 
  if (n == 1)
129
 
  {
130
 
    PrintHelp();
131
 
    return 0;
132
 
  }
133
 
 
134
 
  bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
135
 
  if (unsupportedTypes)
136
 
  {
137
 
    fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
138
 
    return 1;
139
 
  }   
140
 
 
141
 
  UStringVector commandStrings;
142
 
  WriteArgumentsToStringList(n, args, commandStrings);
143
 
  CParser parser(kNumSwitches);
144
 
  try
145
 
  {
146
 
    parser.ParseStrings(kSwitchForms, commandStrings);
147
 
  }
148
 
  catch(...) 
149
 
  {
150
 
    IncorrectCommand();
151
 
  }
152
 
 
153
 
  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
154
 
  {
155
 
    PrintHelp();
156
 
    return 0;
157
 
  }
158
 
  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
159
 
 
160
 
  int paramIndex = 0;
161
 
  if (paramIndex >= nonSwitchStrings.Size())
162
 
    IncorrectCommand();
163
 
  const UString &command = nonSwitchStrings[paramIndex++]; 
164
 
 
165
 
/* FIXME
166
 
  if (command.CompareNoCase(L"b") == 0)
167
 
  {
168
 
    const UInt32 kNumDefaultItereations = 1;
169
 
    UInt32 numIterations = kNumDefaultItereations;
170
 
    {
171
 
      if (paramIndex < nonSwitchStrings.Size())
172
 
        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
173
 
          numIterations = kNumDefaultItereations;
174
 
    }
175
 
    return LzmaBenchCon(stderr, numIterations, numThreads, dictionary);
176
 
  }
177
 
*/
178
 
 
179
 
  bool encodeMode = false;
180
 
  if (command.CompareNoCase(L"e") == 0)
181
 
    encodeMode = true;
182
 
  else if (command.CompareNoCase(L"d") == 0)
183
 
    encodeMode = false;
184
 
  else
185
 
    IncorrectCommand();
186
 
 
187
 
  bool stdInMode = parser[NKey::kStdIn].ThereIs;
188
 
  bool stdOutMode = parser[NKey::kStdOut].ThereIs;
189
 
 
190
 
  CMyComPtr<ISequentialInStream> inStream;
191
 
  CInFileStream *inStreamSpec = 0;
192
 
  if (stdInMode)
193
 
  {
194
 
    inStream = new CStdInFileStream;
195
 
    MY_SET_BINARY_MODE(stdin);
196
 
  }
197
 
  else
198
 
  {
199
 
    if (paramIndex >= nonSwitchStrings.Size())
200
 
      IncorrectCommand();
201
 
    const UString &inputName = nonSwitchStrings[paramIndex++]; 
202
 
    inStreamSpec = new CInFileStream;
203
 
    inStream = inStreamSpec;
204
 
    if (!inStreamSpec->Open(GetSystemString(inputName)))
205
 
    {
206
 
      fprintf(stderr, "\nError: can not open input file %s\n", 
207
 
          (const char *)GetOemString(inputName));
208
 
      return 1;
209
 
    }
210
 
  }
211
 
 
212
 
  CMyComPtr<ISequentialOutStream> outStream;
213
 
  if (stdOutMode)
214
 
  {
215
 
    outStream = new CStdOutFileStream;
216
 
    MY_SET_BINARY_MODE(stdout);
217
 
  }
218
 
  else
219
 
  {
220
 
    if (paramIndex >= nonSwitchStrings.Size())
221
 
      IncorrectCommand();
222
 
    const UString &outputName = nonSwitchStrings[paramIndex++]; 
223
 
    COutFileStream *outStreamSpec = new COutFileStream;
224
 
    outStream = outStreamSpec;
225
 
    if (!outStreamSpec->Create(GetSystemString(outputName), true))
226
 
    {
227
 
      fprintf(stderr, "\nError: can not open output file %s\n", 
228
 
        (const char *)GetOemString(outputName));
229
 
      return 1;
230
 
    }
231
 
  }
232
 
 
233
 
  UInt64 fileSize;
234
 
  if (encodeMode)
235
 
  {
236
 
    // NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
237
 
    NCompress::NPPMD::CEncoder *encoderSpec = new NCompress::NPPMD::CEncoder;
238
 
    CMyComPtr<ICompressCoder> encoder = encoderSpec;
239
 
 
240
 
    if (stdInMode)
241
 
      IncorrectCommand();
242
 
 
243
 
    UInt32 order = 4;
244
 
    if(parser[NKey::kOrder].ThereIs)
245
 
      if (!GetNumber(parser[NKey::kOrder].PostStrings[0], order))
246
 
        IncorrectCommand();
247
 
   if (order < 4) order = 4;
248
 
    
249
 
    UInt32 memSize = 4;
250
 
    if(parser[NKey::kUsedMemorySize].ThereIs)
251
 
      if (!GetNumber(parser[NKey::kUsedMemorySize].PostStrings[0], memSize))
252
 
        IncorrectCommand();
253
 
   if (memSize < 4 ) memSize = 4; 
254
 
    
255
 
 
256
 
    PROPID propIDs[] = 
257
 
 
258
 
    {
259
 
        NCoderPropID::kUsedMemorySize,
260
 
        NCoderPropID::kOrder
261
 
    };
262
 
    const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
263
 
 
264
 
    PROPVARIANT properties[kNumPropsMax];
265
 
    for (int p = 0; p < kNumPropsMax; p++)
266
 
      properties[p].vt = VT_UI4;
267
 
 
268
 
    properties[0].ulVal = memSize * 1024 * 1024; // memory
269
 
    properties[1].ulVal = order;
270
 
 
271
 
    int numProps = kNumPropsMax;
272
 
 
273
 
    if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
274
 
      IncorrectCommand();
275
 
    encoderSpec->WriteCoderProperties(outStream);
276
 
 
277
 
/* 
278
 
    if (eos || stdInMode)
279
 
      fileSize = (UInt64)(Int64)-1;
280
 
    else
281
 
*/
282
 
      inStreamSpec->File.GetLength(fileSize);
283
 
 
284
 
    for (int i = 0; i < 8; i++)
285
 
    {
286
 
      Byte b = Byte(fileSize >> (8 * i));
287
 
      if (outStream->Write(&b, 1, 0) != S_OK)
288
 
      {
289
 
        fprintf(stderr, kWriteError);
290
 
        return 1;
291
 
      }
292
 
    }
293
 
    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
294
 
    if (result == E_OUTOFMEMORY)
295
 
    {
296
 
      fprintf(stderr, "\nError: Can not allocate memory\n");
297
 
      return 1;
298
 
    }   
299
 
    else if (result != S_OK)
300
 
    {
301
 
      fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
302
 
      return 1;
303
 
    }   
304
 
  }
305
 
  else
306
 
  {
307
 
    // NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
308
 
    NCompress::NPPMD::CDecoder *decoderSpec = new NCompress::NPPMD::CDecoder;
309
 
    CMyComPtr<ICompressCoder> decoder = decoderSpec;
310
 
    const UInt32 kPropertiesSize = 5;
311
 
    Byte header[kPropertiesSize + 8];
312
 
    if (ReadStream_FALSE(inStream, header, kPropertiesSize + 8) != S_OK)
313
 
    {
314
 
      fprintf(stderr, kReadError);
315
 
      return 1;
316
 
    }
317
 
    if (decoderSpec->SetDecoderProperties2(header, kPropertiesSize) != S_OK)
318
 
    {
319
 
      fprintf(stderr, "SetDecoderProperties error");
320
 
      return 1;
321
 
    }
322
 
    fileSize = 0;
323
 
    for (int i = 0; i < 8; i++)
324
 
      fileSize |= ((UInt64)header[kPropertiesSize + i]) << (8 * i);
325
 
 
326
 
    if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
327
 
    {
328
 
      fprintf(stderr, "Decoder error");
329
 
      return 1;
330
 
    }   
331
 
  }
332
 
  return 0;
333
 
}
334
 
 
335
 
int main(int n, const char *args[])
336
 
{
337
 
  try { return main2(n, args); }
338
 
  catch(const char *s) 
339
 
  { 
340
 
    fprintf(stderr, "\nError: %s\n", s);
341
 
    return 1; 
342
 
  }
343
 
  catch(...) 
344
 
  { 
345
 
    fprintf(stderr, "\nError\n");
346
 
    return 1; 
347
 
  }
348
 
}