Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/LZMA_Alone/LzmaAlone.cpp, revision 1.1

1.1     ! misho       1: // LzmaAlone.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 "Windows/PropVariant.h"
        !            23: 
        !            24: #include "../../Common/FileStreams.h"
        !            25: 
        !            26: #include "../LZMA/LZMADecoder.h"
        !            27: #include "../LZMA/LZMAEncoder.h"
        !            28: 
        !            29: #include "LzmaBench.h"
        !            30: #include "LzmaRam.h"
        !            31: 
        !            32: extern "C"
        !            33: {
        !            34: #include "LzmaRamDecode.h"
        !            35: }
        !            36: 
        !            37: using namespace NCommandLineParser;
        !            38: 
        !            39: namespace NKey {
        !            40: enum Enum
        !            41: {
        !            42:   kHelp1 = 0,
        !            43:   kHelp2,
        !            44:   kMode,
        !            45:   kDictionary,
        !            46:   kFastBytes,
        !            47:   kLitContext,
        !            48:   kLitPos,
        !            49:   kPosBits,
        !            50:   kMatchFinder,
        !            51:   kEOS,
        !            52:   kStdIn,
        !            53:   kStdOut,
        !            54:   kFilter86
        !            55: };
        !            56: }
        !            57: 
        !            58: static const CSwitchForm kSwitchForms[] = 
        !            59: {
        !            60:   { L"?",  NSwitchType::kSimple, false },
        !            61:   { L"H",  NSwitchType::kSimple, false },
        !            62:   { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
        !            63:   { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
        !            64:   { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
        !            65:   { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
        !            66:   { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
        !            67:   { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
        !            68:   { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
        !            69:   { L"EOS", NSwitchType::kSimple, false },
        !            70:   { L"SI",  NSwitchType::kSimple, false },
        !            71:   { L"SO",  NSwitchType::kSimple, false },
        !            72:   { L"F86",  NSwitchType::kSimple, false }
        !            73: };
        !            74: 
        !            75: static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
        !            76: 
        !            77: static void PrintHelp()
        !            78: {
        !            79:   fprintf(stderr, "\nUsage:  LZMA <e|d> inputFile outputFile [<switches>...]\n"
        !            80:              "  e: encode file\n"
        !            81:              "  d: decode file\n"
        !            82:              "  b: Benchmark\n"
        !            83:     "<Switches>\n"
        !            84:     "  -a{N}:  set compression mode - [0, 2], default: 2 (max)\n"
        !            85:     "  -d{N}:  set dictionary - [0,28], default: 23 (8MB)\n"
        !            86:     "  -fb{N}: set number of fast bytes - [5, 255], default: 128\n"
        !            87:     "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
        !            88:     "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
        !            89:     "  -pb{N}: set number of pos bits - [0, 4], default: 2\n"
        !            90:     "  -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, bt4b, pat2r, pat2,\n"
        !            91:     "              pat2h, pat3h, pat4h, hc3, hc4], default: bt4\n"
        !            92:     "  -eos:   write End Of Stream marker\n"
        !            93:     "  -si:    Read data from stdin\n"
        !            94:     "  -so:    Write data to stdout\n"
        !            95:     );
        !            96: }
        !            97: 
        !            98: static void PrintHelpAndExit(const char *s)
        !            99: {
        !           100:   fprintf(stderr, "\nError: %s\n\n", s);
        !           101:   PrintHelp();
        !           102:   throw -1;
        !           103: }
        !           104: 
        !           105: static void IncorrectCommand()
        !           106: {
        !           107:   PrintHelpAndExit("Incorrect command");
        !           108: }
        !           109: 
        !           110: static void WriteArgumentsToStringList(int numArguments, const char *arguments[], 
        !           111:     UStringVector &strings)
        !           112: {
        !           113:   for(int i = 1; i < numArguments; i++)
        !           114:     strings.Add(MultiByteToUnicodeString(arguments[i]));
        !           115: }
        !           116: 
        !           117: static bool GetNumber(const wchar_t *s, UInt32 &value)
        !           118: {
        !           119:   value = 0;
        !           120:   if (MyStringLen(s) == 0)
        !           121:     return false;
        !           122:   const wchar_t *end;
        !           123:   UInt64 res = ConvertStringToUInt64(s, &end);
        !           124:   if (*end != L'\0')
        !           125:     return false;
        !           126:   if (res > 0xFFFFFFFF)
        !           127:     return false;
        !           128:   value = UInt32(res);
        !           129:   return true;
        !           130: }
        !           131: 
        !           132: int main2(int n, const char *args[])
        !           133: {
        !           134:   fprintf(stderr, "\nLZMA 4.17 Copyright (c) 1999-2004 Igor Pavlov  2005-04-18\n");
        !           135: 
        !           136:   if (n == 1)
        !           137:   {
        !           138:     PrintHelp();
        !           139:     return 0;
        !           140:   }
        !           141: 
        !           142:   if (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4)
        !           143:   {
        !           144:     fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
        !           145:     return 1;
        !           146:   }   
        !           147: 
        !           148:   UStringVector commandStrings;
        !           149:   WriteArgumentsToStringList(n, args, commandStrings);
        !           150:   CParser parser(kNumSwitches);
        !           151:   try
        !           152:   {
        !           153:     parser.ParseStrings(kSwitchForms, commandStrings);
        !           154:   }
        !           155:   catch(...) 
        !           156:   {
        !           157:     IncorrectCommand();
        !           158:   }
        !           159: 
        !           160:   if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
        !           161:   {
        !           162:     PrintHelp();
        !           163:     return 0;
        !           164:   }
        !           165:   const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
        !           166: 
        !           167:   int paramIndex = 0;
        !           168:   if (paramIndex >= nonSwitchStrings.Size())
        !           169:     IncorrectCommand();
        !           170:   const UString &command = nonSwitchStrings[paramIndex++]; 
        !           171: 
        !           172:   bool dictionaryIsDefined = false;
        !           173:   UInt32 dictionary = 1 << 21;
        !           174:   if(parser[NKey::kDictionary].ThereIs)
        !           175:   {
        !           176:     UInt32 dicLog;
        !           177:     if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
        !           178:       IncorrectCommand();
        !           179:     dictionary = 1 << dicLog;
        !           180:     dictionaryIsDefined = true;
        !           181:   }
        !           182:   UString mf = L"BT4";
        !           183:   if (parser[NKey::kMatchFinder].ThereIs)
        !           184:     mf = parser[NKey::kMatchFinder].PostStrings[0];
        !           185: 
        !           186:   if (command.CompareNoCase(L"b") == 0)
        !           187:   {
        !           188:     const UInt32 kNumDefaultItereations = 10;
        !           189:     UInt32 numIterations = kNumDefaultItereations;
        !           190:     {
        !           191:       if (paramIndex < nonSwitchStrings.Size())
        !           192:         if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
        !           193:           numIterations = kNumDefaultItereations;
        !           194:     }
        !           195:     return LzmaBenchmark(stderr, numIterations, dictionary, 
        !           196:         mf.CompareNoCase(L"BT4") == 0);
        !           197:   }
        !           198: 
        !           199:   bool encodeMode = false;
        !           200:   if (command.CompareNoCase(L"e") == 0)
        !           201:     encodeMode = true;
        !           202:   else if (command.CompareNoCase(L"d") == 0)
        !           203:     encodeMode = false;
        !           204:   else
        !           205:     IncorrectCommand();
        !           206: 
        !           207:   bool stdInMode = parser[NKey::kStdIn].ThereIs;
        !           208:   bool stdOutMode = parser[NKey::kStdOut].ThereIs;
        !           209: 
        !           210:   CMyComPtr<ISequentialInStream> inStream;
        !           211:   CInFileStream *inStreamSpec = 0;
        !           212:   if (stdInMode)
        !           213:   {
        !           214:     inStream = new CStdInFileStream;
        !           215:     MY_SET_BINARY_MODE(stdin);
        !           216:   }
        !           217:   else
        !           218:   {
        !           219:     if (paramIndex >= nonSwitchStrings.Size())
        !           220:       IncorrectCommand();
        !           221:     const UString &inputName = nonSwitchStrings[paramIndex++]; 
        !           222:     inStreamSpec = new CInFileStream;
        !           223:     inStream = inStreamSpec;
        !           224:     if (!inStreamSpec->Open(GetSystemString(inputName)))
        !           225:     {
        !           226:       fprintf(stderr, "\nError: can not open input file %s\n", 
        !           227:           (const char *)GetOemString(inputName));
        !           228:       return 1;
        !           229:     }
        !           230:   }
        !           231: 
        !           232:   CMyComPtr<ISequentialOutStream> outStream;
        !           233:   if (stdOutMode)
        !           234:   {
        !           235:     outStream = new CStdOutFileStream;
        !           236:     MY_SET_BINARY_MODE(stdout);
        !           237:   }
        !           238:   else
        !           239:   {
        !           240:     if (paramIndex >= nonSwitchStrings.Size())
        !           241:       IncorrectCommand();
        !           242:     const UString &outputName = nonSwitchStrings[paramIndex++]; 
        !           243:     COutFileStream *outStreamSpec = new COutFileStream;
        !           244:     outStream = outStreamSpec;
        !           245:     if (!outStreamSpec->Create(GetSystemString(outputName), true))
        !           246:     {
        !           247:       fprintf(stderr, "\nError: can not open output file %s\n", 
        !           248:         (const char *)GetOemString(outputName));
        !           249:       return 1;
        !           250:     }
        !           251:   }
        !           252: 
        !           253:   if (parser[NKey::kFilter86].ThereIs)
        !           254:   {
        !           255:     // -f86 switch is for x86 filtered mode: BCJ + LZMA.
        !           256:     if (parser[NKey::kEOS].ThereIs || stdInMode)
        !           257:       throw "Can not use stdin in this mode";
        !           258:     UInt64 fileSize;
        !           259:     inStreamSpec->File.GetLength(fileSize);
        !           260:     if (fileSize > 0xF0000000)
        !           261:       throw "File is too big";
        !           262:     UInt32 inSize = (UInt32)fileSize;
        !           263:     Byte *inBuffer = (Byte *)MyAlloc((size_t)inSize); 
        !           264:     if (inBuffer == 0)
        !           265:       throw "Can not allocate memory";
        !           266:     
        !           267:     UInt32 processedSize;
        !           268:     if (inStream->Read(inBuffer, (UInt32)inSize, &processedSize) != S_OK)
        !           269:       throw "Can not read";
        !           270:     if ((UInt32)inSize != processedSize)
        !           271:       throw "Read size error";
        !           272: 
        !           273:     Byte *outBuffer;
        !           274:     size_t outSizeProcessed;
        !           275:     if (encodeMode)
        !           276:     {
        !           277:       // we allocate 105% of original size for output buffer
        !           278:       size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
        !           279:       outBuffer = (Byte *)MyAlloc((size_t)outSize); 
        !           280:       if (outBuffer == 0)
        !           281:         throw "Can not allocate memory";
        !           282:       if (!dictionaryIsDefined)
        !           283:         dictionary = 1 << 23;
        !           284:       int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, 
        !           285:           dictionary, SZ_FILTER_AUTO);
        !           286:       if (res != 0)
        !           287:       {
        !           288:         fprintf(stderr, "\nEncoder error = %d\n", (int)res);
        !           289:         return 1;
        !           290:       }
        !           291:     }
        !           292:     else
        !           293:     {
        !           294:       size_t outSize;
        !           295:       if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
        !           296:         throw "data error";
        !           297:       outBuffer = (Byte *)MyAlloc(outSize); 
        !           298:       if (outBuffer == 0)
        !           299:         throw "Can not allocate memory";
        !           300:       
        !           301:       int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
        !           302:       if (res != 0)
        !           303:         throw "LzmaDecoder error";
        !           304:     }
        !           305:     if (outStream->Write(outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
        !           306:       throw "Can not write";
        !           307:     MyFree(outBuffer);
        !           308:     MyFree(inBuffer);
        !           309:     return 0;
        !           310:   }
        !           311: 
        !           312: 
        !           313:   UInt64 fileSize;
        !           314:   if (encodeMode)
        !           315:   {
        !           316:     NCompress::NLZMA::CEncoder *encoderSpec = 
        !           317:       new NCompress::NLZMA::CEncoder;
        !           318:     CMyComPtr<ICompressCoder> encoder = encoderSpec;
        !           319: 
        !           320:     if (!dictionaryIsDefined)
        !           321:       dictionary = 1 << 23;
        !           322: 
        !           323:     UInt32 posStateBits = 2;
        !           324:     UInt32 litContextBits = 3; // for normal files
        !           325:     // UInt32 litContextBits = 0; // for 32-bit data
        !           326:     UInt32 litPosBits = 0;
        !           327:     // UInt32 litPosBits = 2; // for 32-bit data
        !           328:     UInt32 algorithm = 2;
        !           329:     UInt32 numFastBytes = 128;
        !           330: 
        !           331:     bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
        !           332:  
        !           333:     if(parser[NKey::kMode].ThereIs)
        !           334:       if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
        !           335:         IncorrectCommand();
        !           336: 
        !           337:     if(parser[NKey::kFastBytes].ThereIs)
        !           338:       if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
        !           339:         IncorrectCommand();
        !           340:     if(parser[NKey::kLitContext].ThereIs)
        !           341:       if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
        !           342:         IncorrectCommand();
        !           343:     if(parser[NKey::kLitPos].ThereIs)
        !           344:       if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
        !           345:         IncorrectCommand();
        !           346:     if(parser[NKey::kPosBits].ThereIs)
        !           347:       if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
        !           348:         IncorrectCommand();
        !           349: 
        !           350:     PROPID propIDs[] = 
        !           351:     {
        !           352:       NCoderPropID::kDictionarySize,
        !           353:       NCoderPropID::kPosStateBits,
        !           354:       NCoderPropID::kLitContextBits,
        !           355:       NCoderPropID::kLitPosBits,
        !           356:       NCoderPropID::kAlgorithm,
        !           357:       NCoderPropID::kNumFastBytes,
        !           358:       NCoderPropID::kMatchFinder,
        !           359:       NCoderPropID::kEndMarker
        !           360:     };
        !           361:     const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
        !           362:     /*
        !           363:     NWindows::NCOM::CPropVariant properties[kNumProps];
        !           364:     properties[0] = UInt32(dictionary);
        !           365:     properties[1] = UInt32(posStateBits);
        !           366:     properties[2] = UInt32(litContextBits);
        !           367:    
        !           368:     properties[3] = UInt32(litPosBits);
        !           369:     properties[4] = UInt32(algorithm);
        !           370:     properties[5] = UInt32(numFastBytes);
        !           371:     properties[6] = mf;
        !           372:     properties[7] = eos;
        !           373:     */
        !           374:     PROPVARIANT properties[kNumProps];
        !           375:     for (int p = 0; p < 6; p++)
        !           376:       properties[p].vt = VT_UI4;
        !           377:     properties[0].ulVal = UInt32(dictionary);
        !           378:     properties[1].ulVal = UInt32(posStateBits);
        !           379:     properties[2].ulVal = UInt32(litContextBits);
        !           380:     properties[3].ulVal = UInt32(litPosBits);
        !           381:     properties[4].ulVal = UInt32(algorithm);
        !           382:     properties[5].ulVal = UInt32(numFastBytes);
        !           383:     
        !           384:     properties[6].vt = VT_BSTR;
        !           385:     properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
        !           386: 
        !           387:     properties[7].vt = VT_BOOL;
        !           388:     properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
        !           389: 
        !           390:     if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
        !           391:       IncorrectCommand();
        !           392:     encoderSpec->WriteCoderProperties(outStream);
        !           393: 
        !           394:     if (eos || stdInMode)
        !           395:       fileSize = (UInt64)(Int64)-1;
        !           396:     else
        !           397:       inStreamSpec->File.GetLength(fileSize);
        !           398: 
        !           399:     for (int i = 0; i < 8; i++)
        !           400:     {
        !           401:       Byte b = Byte(fileSize >> (8 * i));
        !           402:       if (outStream->Write(&b, sizeof(b), 0) != S_OK)
        !           403:       {
        !           404:         fprintf(stderr, "Write error");
        !           405:         return 1;
        !           406:       }
        !           407:     }
        !           408:     HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
        !           409:     if (result == E_OUTOFMEMORY)
        !           410:     {
        !           411:       fprintf(stderr, "\nError: Can not allocate memory\n");
        !           412:       return 1;
        !           413:     }   
        !           414:     else if (result != S_OK)
        !           415:     {
        !           416:       fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
        !           417:       return 1;
        !           418:     }   
        !           419:   }
        !           420:   else
        !           421:   {
        !           422:     NCompress::NLZMA::CDecoder *decoderSpec = 
        !           423:         new NCompress::NLZMA::CDecoder;
        !           424:     CMyComPtr<ICompressCoder> decoder = decoderSpec;
        !           425:     const UInt32 kPropertiesSize = 5;
        !           426:     Byte properties[kPropertiesSize];
        !           427:     UInt32 processedSize;
        !           428:     if (inStream->Read(properties, kPropertiesSize, &processedSize) != S_OK)
        !           429:     {
        !           430:       fprintf(stderr, "Read error");
        !           431:       return 1;
        !           432:     }
        !           433:     if (processedSize != kPropertiesSize)
        !           434:     {
        !           435:       fprintf(stderr, "Read error");
        !           436:       return 1;
        !           437:     }
        !           438:     if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
        !           439:     {
        !           440:       fprintf(stderr, "SetDecoderProperties error");
        !           441:       return 1;
        !           442:     }
        !           443:     fileSize = 0;
        !           444:     for (int i = 0; i < 8; i++)
        !           445:     {
        !           446:       Byte b;
        !           447:       if (inStream->Read(&b, sizeof(b), &processedSize) != S_OK)
        !           448:       {
        !           449:         fprintf(stderr, "Read error");
        !           450:         return 1;
        !           451:       }
        !           452:       if (processedSize != 1)
        !           453:       {
        !           454:         fprintf(stderr, "Read error");
        !           455:         return 1;
        !           456:       }
        !           457:       fileSize |= ((UInt64)b) << (8 * i);
        !           458:     }
        !           459:     if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
        !           460:     {
        !           461:       fprintf(stderr, "Decoder error");
        !           462:       return 1;
        !           463:     }   
        !           464:   }
        !           465:   return 0;
        !           466: }
        !           467: 
        !           468: int main(int n, const char *args[])
        !           469: {
        !           470:   try { return main2(n, args); }
        !           471:   catch(const char *s) 
        !           472:   { 
        !           473:     fprintf(stderr, "\nError: %s\n", s);
        !           474:     return 1; 
        !           475:   }
        !           476:   catch(...) 
        !           477:   { 
        !           478:     fprintf(stderr, "\nError\n");
        !           479:     return 1; 
        !           480:   }
        !           481: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>