home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 October / CMCD1004.ISO / Software / Shareware / Utilitare / pec / pec2setup.exe / lzma / sdk / LzmaAlone.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-04-25  |  7.5 KB  |  277 lines

  1. // LzmaAlone.h
  2.  
  3. #include <stdafx.h>
  4.  
  5. #include <initguid.h>
  6. #include <limits.h>
  7.  
  8. #include "Common/CommandLineParser.h"
  9. #include "Common/StringConvert.h"
  10. #include "Common/StringToInt.h"
  11.  
  12. #include "Windows/PropVariant.h"
  13.  
  14. #include "../../Common/FileStreams.h"
  15.  
  16. #include "../LZMA/LZMADecoder.h"
  17. #include "../LZMA/LZMAEncoder.h"
  18.  
  19. using namespace NWindows;
  20. using namespace NCommandLineParser;
  21.  
  22. namespace NKey {
  23. enum Enum
  24. {
  25.   kHelp1 = 0,
  26.   kHelp2,
  27.   kDictionary,
  28.   kFastBytes,
  29.   kLitContext,
  30.   kLitPos,
  31.   kPosBits,
  32.   kEOS
  33. };
  34. }
  35.  
  36. static const CSwitchForm kSwitchForms[] = 
  37.   {
  38.     { L"?",  NSwitchType::kSimple, false },
  39.     { L"H",  NSwitchType::kSimple, false },
  40.     { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
  41.     { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
  42.     { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
  43.     { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
  44.     { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
  45.     { L"EOS", NSwitchType::kSimple, false }
  46.   };
  47.  
  48. static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
  49.  
  50. static void PrintHelp()
  51. {
  52.   printf("\nUsage:  LZMA <e|d> inputFile outputFile [<switches>...]\n"
  53.              "  e: encode file\n"
  54.              "  d: decode file\n"
  55.     "<Switches>\n"
  56.     "  -d{N}:  set dictionary - [0,28], default: 23 (8MB)\n"
  57.     "  -fb{N}: set number of fast bytes - [5, 255], default: 128\n"
  58.     "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
  59.     "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
  60.     "  -pb{N}: set number of pos bits - [0, 4], default: 2\n"
  61.     "  -eos:   write End Of Stream marker\n"
  62.     );
  63. }
  64.  
  65. static void PrintHelpAndExit(const char *s)
  66. {
  67.   printf("\nError: %s\n\n", s);
  68.   PrintHelp();
  69.   throw -1;
  70. }
  71.  
  72. static void IncorrectCommand()
  73. {
  74.   PrintHelpAndExit("Incorrect command");
  75. }
  76.  
  77. static void WriteArgumentsToStringList(int numArguments, const char *arguments[], 
  78.     UStringVector &strings)
  79. {
  80.   for(int i = 1; i < numArguments; i++)
  81.     strings.Add(MultiByteToUnicodeString(arguments[i]));
  82. }
  83.  
  84. static bool GetNumber(const wchar_t *s, UINT32 &value)
  85. {
  86.   value  =0;
  87.   if (wcslen(s) == 0)
  88.     return false;
  89.   const wchar_t *end;
  90.   UINT64 res = ConvertStringToUINT64(s, &end);
  91.   if (*end != L'\0')
  92.     return false;
  93.   if (res > 0xFFFFFFFF)
  94.     return false;
  95.   value = UINT32(res);
  96.   return true;
  97. }
  98.  
  99. int __cdecl main2(int n, const char *args[])
  100. {
  101.   printf("\nLZMA 4.00 Copyright (c) 2001-2004 Igor Pavlov  2004-02-13\n");
  102.  
  103.   if (n == 1)
  104.   {
  105.     PrintHelp();
  106.     return -1;
  107.   }
  108.  
  109.   UStringVector commandStrings;
  110.   WriteArgumentsToStringList(n, args, commandStrings);
  111.   CParser parser(kNumSwitches);
  112.   try
  113.   {
  114.     parser.ParseStrings(kSwitchForms, commandStrings);
  115.   }
  116.   catch(...) 
  117.   {
  118.     IncorrectCommand();
  119.   }
  120.  
  121.   if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
  122.   {
  123.     PrintHelp();
  124.     return 0;
  125.   }
  126.   const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
  127.  
  128.   if(nonSwitchStrings.Size() != 3)  
  129.     IncorrectCommand();
  130.  
  131.   bool encodeMode = false;
  132.   const UString &command = nonSwitchStrings[0]; 
  133.   const UString &inputName = nonSwitchStrings[1]; 
  134.   const UString &outputName = nonSwitchStrings[2]; 
  135.  
  136.   if (command.CompareNoCase(L"e") == 0)
  137.     encodeMode = true;
  138.   else if (command.CompareNoCase(L"d") == 0)
  139.     encodeMode = false;
  140.   else
  141.     IncorrectCommand();
  142.  
  143.   CInFileStream *inStreamSpec = new CInFileStream;
  144.   CMyComPtr<IInStream> inStream = inStreamSpec;
  145.   if (!inStreamSpec->Open(GetSystemString(inputName)))
  146.   {
  147.     printf("can not open input file %s", GetSystemString(inputName, CP_OEMCP));
  148.     return 1;
  149.   }
  150.  
  151.   COutFileStream *outStreamSpec = new COutFileStream;
  152.   CMyComPtr<IOutStream> outStream = outStreamSpec;
  153.   // boutStreamSpec->m_File.SetOpenCreationDispositionCreateAlways();
  154.   if (!outStreamSpec->Open(GetSystemString(outputName)))
  155.   {
  156.     printf("can not open output file %s", GetSystemString(outputName, CP_OEMCP));
  157.     return 1;
  158.   }
  159.  
  160.   UINT64 fileSize;
  161.   if (encodeMode)
  162.   {
  163.     NCompress::NLZMA::CEncoder *encoderSpec = 
  164.       new NCompress::NLZMA::CEncoder;
  165.     CMyComPtr<ICompressCoder> encoder = encoderSpec;
  166.  
  167.     UINT32 dictionary = 1 << 23;
  168.     UINT32 posStateBits = 2;
  169.     UINT32 litContextBits = 3; // for normal files
  170.     // UINT32 litContextBits = 0; // for 32-bit data
  171.     UINT32 litPosBits = 0;
  172.     // UINT32 litPosBits = UINT32(2); // for 32-bit data
  173.     UINT32 algorithm = 2;
  174.     UINT32 numFastBytes = 128;
  175.  
  176.     bool eos = parser[NKey::kEOS].ThereIs;
  177.     if(eos)
  178.       encoderSpec->SetWriteEndMarkerMode(true);
  179.  
  180.     if(parser[NKey::kDictionary].ThereIs)
  181.     {
  182.       UINT32 dicLog;
  183.       if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
  184.         IncorrectCommand();
  185.       dictionary = 1 << dicLog;
  186.     }
  187.     if(parser[NKey::kFastBytes].ThereIs)
  188.       if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
  189.         IncorrectCommand();
  190.  
  191.     if(parser[NKey::kLitContext].ThereIs)
  192.       if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
  193.         IncorrectCommand();
  194.     if(parser[NKey::kLitPos].ThereIs)
  195.       if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
  196.         IncorrectCommand();
  197.     if(parser[NKey::kPosBits].ThereIs)
  198.       if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
  199.         IncorrectCommand();
  200.  
  201.  
  202.     PROPID propIDs[] = 
  203.     {
  204.       NCoderPropID::kDictionarySize,
  205.       NCoderPropID::kPosStateBits,
  206.       NCoderPropID::kLitContextBits,
  207.       NCoderPropID::kLitPosBits,
  208.       NCoderPropID::kAlgorithm,
  209.       NCoderPropID::kNumFastBytes
  210.     };
  211.     const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
  212.     NWindows::NCOM::CPropVariant properties[kNumProps];
  213.     properties[0] = UINT32(dictionary);
  214.     properties[1] = UINT32(posStateBits);
  215.     properties[2] = UINT32(litContextBits);
  216.    
  217.     properties[3] = UINT32(litPosBits);
  218.     properties[4] = UINT32(algorithm);
  219.     properties[5] = UINT32(numFastBytes);
  220.  
  221.     if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
  222.       IncorrectCommand();
  223.     encoderSpec->WriteCoderProperties(outStream);
  224.  
  225.     if (eos)
  226.       fileSize = (UINT64)(INT64)-1;
  227.     else
  228.       inStreamSpec->File.GetLength(fileSize);
  229.     outStream->Write(&fileSize, sizeof(fileSize), 0);
  230.  
  231.     if (encoder->Code(inStream, outStream, 0, 0, 0) != S_OK)
  232.     {
  233.       printf("Decoder error");
  234.       return 1;
  235.     }   
  236.  
  237.   }
  238.   else
  239.   {
  240.     NCompress::NLZMA::CDecoder *decoderSpec = 
  241.         new NCompress::NLZMA::CDecoder;
  242.     CMyComPtr<ICompressCoder> decoder = decoderSpec;
  243.     if (decoderSpec->SetDecoderProperties(inStream) != S_OK)
  244.     {
  245.       printf("SetDecoderProperties error");
  246.       return 1;
  247.     }
  248.     UINT32 processedSize;
  249.     if (inStream->Read(&fileSize, sizeof(fileSize), &processedSize) != S_OK)
  250.     {
  251.       printf("SetDecoderProperties error");
  252.       return 1;
  253.     }   
  254.     
  255.     // CComObjectNoLock<CDummyOutStream> *outStreamSpec = new CComObjectNoLock<CDummyOutStream>;
  256.     // CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
  257.  
  258.     for (int n = 0 ; n < 1; n++)
  259.     {
  260.       inStream->Seek(13, STREAM_SEEK_SET, 0);
  261.       if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
  262.       {
  263.         printf("Decoder error");
  264.         return 1;
  265.       }   
  266.     }
  267.   }
  268.   return 0;
  269. }
  270.  
  271.  
  272. int __cdecl main(int n, const char *args[])
  273. {
  274.   try { return main2(n, args); }
  275.   catch(...) { return -1; }
  276. }
  277.