123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- using System;
- using System.IO;
- namespace SevenZip
- {
- using CommandLineParser;
-
- public class CDoubleStream: Stream
- {
- public System.IO.Stream s1;
- public System.IO.Stream s2;
- public int fileIndex;
- public long skipSize;
-
- public override bool CanRead { get { return true; }}
- public override bool CanWrite { get { return false; }}
- public override bool CanSeek { get { return false; }}
- public override long Length { get { return s1.Length + s2.Length - skipSize; } }
- public override long Position
- {
- get { return 0; }
- set { }
- }
- public override void Flush() { }
- public override int Read(byte[] buffer, int offset, int count)
- {
- int numTotal = 0;
- while (count > 0)
- {
- if (fileIndex == 0)
- {
- int num = s1.Read(buffer, offset, count);
- offset += num;
- count -= num;
- numTotal += num;
- if (num == 0)
- fileIndex++;
- }
- if (fileIndex == 1)
- {
- numTotal += s2.Read(buffer, offset, count);
- return numTotal;
- }
- }
- return numTotal;
- }
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw (new Exception("can't Write"));
- }
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- throw (new Exception("can't Seek"));
- }
- public override void SetLength(long value)
- {
- throw (new Exception("can't SetLength"));
- }
- }
-
- class LzmaAlone
- {
- enum Key
- {
- Help1 = 0,
- Help2,
- Mode,
- Dictionary,
- FastBytes,
- LitContext,
- LitPos,
- PosBits,
- MatchFinder,
- EOS,
- StdIn,
- StdOut,
- Train
- };
- static void PrintHelp()
- {
- System.Console.WriteLine("\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" +
- " e: encode file\n" +
- " d: decode file\n" +
- " b: Benchmark\n" +
- "<Switches>\n" +
- // " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" +
- " -d{N}: set dictionary - [0, 29], default: 23 (8MB)\n" +
- " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
- " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
- " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
- " -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
- " -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
- " -eos: write End Of Stream marker\n"
- // + " -si: read data from stdin\n"
- // + " -so: write data to stdout\n"
- );
- }
- static bool GetNumber(string s, out Int32 v)
- {
- v = 0;
- for (int i = 0; i < s.Length; i++)
- {
- char c = s[i];
- if (c < '0' || c > '9')
- return false;
- v *= 10;
- v += (Int32)(c - '0');
- }
- return true;
- }
- static int IncorrectCommand()
- {
- throw (new Exception("Command line error"));
- // System.Console.WriteLine("\nCommand line error\n");
- // return 1;
- }
- static int Main2(string[] args)
- {
- System.Console.WriteLine("\nLZMA# 4.49 Copyright (c) 1999-2007 Igor Pavlov 2006-07-05\n");
- if (args.Length == 0)
- {
- PrintHelp();
- return 0;
- }
- SwitchForm[] kSwitchForms = new SwitchForm[13];
- int sw = 0;
- kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false);
- kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false);
- kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1);
- kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false);
- kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false);
- kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false);
- kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1);
- Parser parser = new Parser(sw);
- try
- {
- parser.ParseStrings(kSwitchForms, args);
- }
- catch
- {
- return IncorrectCommand();
- }
- if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs)
- {
- PrintHelp();
- return 0;
- }
- System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings;
- int paramIndex = 0;
- if (paramIndex >= nonSwitchStrings.Count)
- return IncorrectCommand();
- string command = (string)nonSwitchStrings[paramIndex++];
- command = command.ToLower();
- bool dictionaryIsDefined = false;
- Int32 dictionary = 1 << 21;
- if (parser[(int)Key.Dictionary].ThereIs)
- {
- Int32 dicLog;
- if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog))
- IncorrectCommand();
- dictionary = (Int32)1 << dicLog;
- dictionaryIsDefined = true;
- }
- string mf = "bt4";
- if (parser[(int)Key.MatchFinder].ThereIs)
- mf = (string)parser[(int)Key.MatchFinder].PostStrings[0];
- mf = mf.ToLower();
- if (command == "b")
- {
- const Int32 kNumDefaultItereations = 10;
- Int32 numIterations = kNumDefaultItereations;
- if (paramIndex < nonSwitchStrings.Count)
- if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations))
- numIterations = kNumDefaultItereations;
- return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary);
- }
- string train = "";
- if (parser[(int)Key.Train].ThereIs)
- train = (string)parser[(int)Key.Train].PostStrings[0];
- bool encodeMode = false;
- if (command == "e")
- encodeMode = true;
- else if (command == "d")
- encodeMode = false;
- else
- IncorrectCommand();
- bool stdInMode = parser[(int)Key.StdIn].ThereIs;
- bool stdOutMode = parser[(int)Key.StdOut].ThereIs;
- Stream inStream = null;
- if (stdInMode)
- {
- throw (new Exception("Not implemeted"));
- }
- else
- {
- if (paramIndex >= nonSwitchStrings.Count)
- IncorrectCommand();
- string inputName = (string)nonSwitchStrings[paramIndex++];
- inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);
- }
- FileStream outStream = null;
- if (stdOutMode)
- {
- throw (new Exception("Not implemeted"));
- }
- else
- {
- if (paramIndex >= nonSwitchStrings.Count)
- IncorrectCommand();
- string outputName = (string)nonSwitchStrings[paramIndex++];
- outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);
- }
- FileStream trainStream = null;
- if (train.Length != 0)
- trainStream = new FileStream(train, FileMode.Open, FileAccess.Read);
- if (encodeMode)
- {
- if (!dictionaryIsDefined)
- dictionary = 1 << 23;
- Int32 posStateBits = 2;
- Int32 litContextBits = 3; // for normal files
- // UInt32 litContextBits = 0; // for 32-bit data
- Int32 litPosBits = 0;
- // UInt32 litPosBits = 2; // for 32-bit data
- Int32 algorithm = 2;
- Int32 numFastBytes = 128;
- bool eos = parser[(int)Key.EOS].ThereIs || stdInMode;
- if (parser[(int)Key.Mode].ThereIs)
- if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm))
- IncorrectCommand();
- if (parser[(int)Key.FastBytes].ThereIs)
- if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes))
- IncorrectCommand();
- if (parser[(int)Key.LitContext].ThereIs)
- if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits))
- IncorrectCommand();
- if (parser[(int)Key.LitPos].ThereIs)
- if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits))
- IncorrectCommand();
- if (parser[(int)Key.PosBits].ThereIs)
- if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits))
- IncorrectCommand();
- CoderPropID[] propIDs =
- {
- CoderPropID.DictionarySize,
- CoderPropID.PosStateBits,
- CoderPropID.LitContextBits,
- CoderPropID.LitPosBits,
- CoderPropID.Algorithm,
- CoderPropID.NumFastBytes,
- CoderPropID.MatchFinder,
- CoderPropID.EndMarker
- };
- object[] properties =
- {
- (Int32)(dictionary),
- (Int32)(posStateBits),
- (Int32)(litContextBits),
- (Int32)(litPosBits),
- (Int32)(algorithm),
- (Int32)(numFastBytes),
- mf,
- eos
- };
- Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
- encoder.SetCoderProperties(propIDs, properties);
- encoder.WriteCoderProperties(outStream);
- Int64 fileSize;
- if (eos || stdInMode)
- fileSize = -1;
- else
- fileSize = inStream.Length;
- for (int i = 0; i < 8; i++)
- outStream.WriteByte((Byte)(fileSize >> (8 * i)));
- if (trainStream != null)
- {
- CDoubleStream doubleStream = new CDoubleStream();
- doubleStream.s1 = trainStream;
- doubleStream.s2 = inStream;
- doubleStream.fileIndex = 0;
- inStream = doubleStream;
- long trainFileSize = trainStream.Length;
- doubleStream.skipSize = 0;
- if (trainFileSize > dictionary)
- doubleStream.skipSize = trainFileSize - dictionary;
- trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);
- encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));
- }
- encoder.Code(inStream, outStream, -1, -1, null);
- }
- else if (command == "d")
- {
- byte[] properties = new byte[5];
- if (inStream.Read(properties, 0, 5) != 5)
- throw (new Exception("input .lzma is too short"));
- Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
- decoder.SetDecoderProperties(properties);
- if (trainStream != null)
- {
- if (!decoder.Train(trainStream))
- throw (new Exception("can't train"));
- }
- long outSize = 0;
- for (int i = 0; i < 8; i++)
- {
- int v = inStream.ReadByte();
- if (v < 0)
- throw (new Exception("Can't Read 1"));
- outSize |= ((long)(byte)v) << (8 * i);
- }
- long compressedSize = inStream.Length - inStream.Position;
- decoder.Code(inStream, outStream, compressedSize, outSize, null);
- }
- else
- throw (new Exception("Command Error"));
- return 0;
- }
- [STAThread]
- static int Main(string[] args)
- {
- try
- {
- return Main2(args);
- }
- catch (Exception e)
- {
- Console.WriteLine("{0} Caught exception #1.", e);
- // throw e;
- return 1;
- }
- }
- }
- }
|