1370b324cSopenharmony_ciusing System; 2370b324cSopenharmony_ciusing System.IO; 3370b324cSopenharmony_cinamespace SevenZip 4370b324cSopenharmony_ci{ 5370b324cSopenharmony_ci using CommandLineParser; 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci public class CDoubleStream: Stream 8370b324cSopenharmony_ci { 9370b324cSopenharmony_ci public System.IO.Stream s1; 10370b324cSopenharmony_ci public System.IO.Stream s2; 11370b324cSopenharmony_ci public int fileIndex; 12370b324cSopenharmony_ci public long skipSize; 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci public override bool CanRead { get { return true; }} 15370b324cSopenharmony_ci public override bool CanWrite { get { return false; }} 16370b324cSopenharmony_ci public override bool CanSeek { get { return false; }} 17370b324cSopenharmony_ci public override long Length { get { return s1.Length + s2.Length - skipSize; } } 18370b324cSopenharmony_ci public override long Position 19370b324cSopenharmony_ci { 20370b324cSopenharmony_ci get { return 0; } 21370b324cSopenharmony_ci set { } 22370b324cSopenharmony_ci } 23370b324cSopenharmony_ci public override void Flush() { } 24370b324cSopenharmony_ci public override int Read(byte[] buffer, int offset, int count) 25370b324cSopenharmony_ci { 26370b324cSopenharmony_ci int numTotal = 0; 27370b324cSopenharmony_ci while (count > 0) 28370b324cSopenharmony_ci { 29370b324cSopenharmony_ci if (fileIndex == 0) 30370b324cSopenharmony_ci { 31370b324cSopenharmony_ci int num = s1.Read(buffer, offset, count); 32370b324cSopenharmony_ci offset += num; 33370b324cSopenharmony_ci count -= num; 34370b324cSopenharmony_ci numTotal += num; 35370b324cSopenharmony_ci if (num == 0) 36370b324cSopenharmony_ci fileIndex++; 37370b324cSopenharmony_ci } 38370b324cSopenharmony_ci if (fileIndex == 1) 39370b324cSopenharmony_ci { 40370b324cSopenharmony_ci numTotal += s2.Read(buffer, offset, count); 41370b324cSopenharmony_ci return numTotal; 42370b324cSopenharmony_ci } 43370b324cSopenharmony_ci } 44370b324cSopenharmony_ci return numTotal; 45370b324cSopenharmony_ci } 46370b324cSopenharmony_ci public override void Write(byte[] buffer, int offset, int count) 47370b324cSopenharmony_ci { 48370b324cSopenharmony_ci throw (new Exception("can't Write")); 49370b324cSopenharmony_ci } 50370b324cSopenharmony_ci public override long Seek(long offset, System.IO.SeekOrigin origin) 51370b324cSopenharmony_ci { 52370b324cSopenharmony_ci throw (new Exception("can't Seek")); 53370b324cSopenharmony_ci } 54370b324cSopenharmony_ci public override void SetLength(long value) 55370b324cSopenharmony_ci { 56370b324cSopenharmony_ci throw (new Exception("can't SetLength")); 57370b324cSopenharmony_ci } 58370b324cSopenharmony_ci } 59370b324cSopenharmony_ci 60370b324cSopenharmony_ci class LzmaAlone 61370b324cSopenharmony_ci { 62370b324cSopenharmony_ci enum Key 63370b324cSopenharmony_ci { 64370b324cSopenharmony_ci Help1 = 0, 65370b324cSopenharmony_ci Help2, 66370b324cSopenharmony_ci Mode, 67370b324cSopenharmony_ci Dictionary, 68370b324cSopenharmony_ci FastBytes, 69370b324cSopenharmony_ci LitContext, 70370b324cSopenharmony_ci LitPos, 71370b324cSopenharmony_ci PosBits, 72370b324cSopenharmony_ci MatchFinder, 73370b324cSopenharmony_ci EOS, 74370b324cSopenharmony_ci StdIn, 75370b324cSopenharmony_ci StdOut, 76370b324cSopenharmony_ci Train 77370b324cSopenharmony_ci }; 78370b324cSopenharmony_ci 79370b324cSopenharmony_ci static void PrintHelp() 80370b324cSopenharmony_ci { 81370b324cSopenharmony_ci System.Console.WriteLine("\nUsage: LZMA <e|d> [<switches>...] inputFile outputFile\n" + 82370b324cSopenharmony_ci " e: encode file\n" + 83370b324cSopenharmony_ci " d: decode file\n" + 84370b324cSopenharmony_ci " b: Benchmark\n" + 85370b324cSopenharmony_ci "<Switches>\n" + 86370b324cSopenharmony_ci // " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" + 87370b324cSopenharmony_ci " -d{N}: set dictionary - [0, 29], default: 23 (8MB)\n" + 88370b324cSopenharmony_ci " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" + 89370b324cSopenharmony_ci " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + 90370b324cSopenharmony_ci " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + 91370b324cSopenharmony_ci " -pb{N}: set number of pos bits - [0, 4], default: 2\n" + 92370b324cSopenharmony_ci " -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" + 93370b324cSopenharmony_ci " -eos: write End Of Stream marker\n" 94370b324cSopenharmony_ci // + " -si: read data from stdin\n" 95370b324cSopenharmony_ci // + " -so: write data to stdout\n" 96370b324cSopenharmony_ci ); 97370b324cSopenharmony_ci } 98370b324cSopenharmony_ci 99370b324cSopenharmony_ci static bool GetNumber(string s, out Int32 v) 100370b324cSopenharmony_ci { 101370b324cSopenharmony_ci v = 0; 102370b324cSopenharmony_ci for (int i = 0; i < s.Length; i++) 103370b324cSopenharmony_ci { 104370b324cSopenharmony_ci char c = s[i]; 105370b324cSopenharmony_ci if (c < '0' || c > '9') 106370b324cSopenharmony_ci return false; 107370b324cSopenharmony_ci v *= 10; 108370b324cSopenharmony_ci v += (Int32)(c - '0'); 109370b324cSopenharmony_ci } 110370b324cSopenharmony_ci return true; 111370b324cSopenharmony_ci } 112370b324cSopenharmony_ci 113370b324cSopenharmony_ci static int IncorrectCommand() 114370b324cSopenharmony_ci { 115370b324cSopenharmony_ci throw (new Exception("Command line error")); 116370b324cSopenharmony_ci // System.Console.WriteLine("\nCommand line error\n"); 117370b324cSopenharmony_ci // return 1; 118370b324cSopenharmony_ci } 119370b324cSopenharmony_ci static int Main2(string[] args) 120370b324cSopenharmony_ci { 121370b324cSopenharmony_ci System.Console.WriteLine("\nLZMA# 4.61 2008-11-23\n"); 122370b324cSopenharmony_ci 123370b324cSopenharmony_ci if (args.Length == 0) 124370b324cSopenharmony_ci { 125370b324cSopenharmony_ci PrintHelp(); 126370b324cSopenharmony_ci return 0; 127370b324cSopenharmony_ci } 128370b324cSopenharmony_ci 129370b324cSopenharmony_ci SwitchForm[] kSwitchForms = new SwitchForm[13]; 130370b324cSopenharmony_ci int sw = 0; 131370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false); 132370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false); 133370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1); 134370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1); 135370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1); 136370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1); 137370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1); 138370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1); 139370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1); 140370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false); 141370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false); 142370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false); 143370b324cSopenharmony_ci kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1); 144370b324cSopenharmony_ci 145370b324cSopenharmony_ci 146370b324cSopenharmony_ci Parser parser = new Parser(sw); 147370b324cSopenharmony_ci try 148370b324cSopenharmony_ci { 149370b324cSopenharmony_ci parser.ParseStrings(kSwitchForms, args); 150370b324cSopenharmony_ci } 151370b324cSopenharmony_ci catch 152370b324cSopenharmony_ci { 153370b324cSopenharmony_ci return IncorrectCommand(); 154370b324cSopenharmony_ci } 155370b324cSopenharmony_ci 156370b324cSopenharmony_ci if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs) 157370b324cSopenharmony_ci { 158370b324cSopenharmony_ci PrintHelp(); 159370b324cSopenharmony_ci return 0; 160370b324cSopenharmony_ci } 161370b324cSopenharmony_ci 162370b324cSopenharmony_ci System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings; 163370b324cSopenharmony_ci 164370b324cSopenharmony_ci int paramIndex = 0; 165370b324cSopenharmony_ci if (paramIndex >= nonSwitchStrings.Count) 166370b324cSopenharmony_ci return IncorrectCommand(); 167370b324cSopenharmony_ci string command = (string)nonSwitchStrings[paramIndex++]; 168370b324cSopenharmony_ci command = command.ToLower(); 169370b324cSopenharmony_ci 170370b324cSopenharmony_ci bool dictionaryIsDefined = false; 171370b324cSopenharmony_ci Int32 dictionary = 1 << 21; 172370b324cSopenharmony_ci if (parser[(int)Key.Dictionary].ThereIs) 173370b324cSopenharmony_ci { 174370b324cSopenharmony_ci Int32 dicLog; 175370b324cSopenharmony_ci if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog)) 176370b324cSopenharmony_ci IncorrectCommand(); 177370b324cSopenharmony_ci dictionary = (Int32)1 << dicLog; 178370b324cSopenharmony_ci dictionaryIsDefined = true; 179370b324cSopenharmony_ci } 180370b324cSopenharmony_ci string mf = "bt4"; 181370b324cSopenharmony_ci if (parser[(int)Key.MatchFinder].ThereIs) 182370b324cSopenharmony_ci mf = (string)parser[(int)Key.MatchFinder].PostStrings[0]; 183370b324cSopenharmony_ci mf = mf.ToLower(); 184370b324cSopenharmony_ci 185370b324cSopenharmony_ci if (command == "b") 186370b324cSopenharmony_ci { 187370b324cSopenharmony_ci const Int32 kNumDefaultItereations = 10; 188370b324cSopenharmony_ci Int32 numIterations = kNumDefaultItereations; 189370b324cSopenharmony_ci if (paramIndex < nonSwitchStrings.Count) 190370b324cSopenharmony_ci if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations)) 191370b324cSopenharmony_ci numIterations = kNumDefaultItereations; 192370b324cSopenharmony_ci return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary); 193370b324cSopenharmony_ci } 194370b324cSopenharmony_ci 195370b324cSopenharmony_ci string train = ""; 196370b324cSopenharmony_ci if (parser[(int)Key.Train].ThereIs) 197370b324cSopenharmony_ci train = (string)parser[(int)Key.Train].PostStrings[0]; 198370b324cSopenharmony_ci 199370b324cSopenharmony_ci bool encodeMode = false; 200370b324cSopenharmony_ci if (command == "e") 201370b324cSopenharmony_ci encodeMode = true; 202370b324cSopenharmony_ci else if (command == "d") 203370b324cSopenharmony_ci encodeMode = false; 204370b324cSopenharmony_ci else 205370b324cSopenharmony_ci IncorrectCommand(); 206370b324cSopenharmony_ci 207370b324cSopenharmony_ci bool stdInMode = parser[(int)Key.StdIn].ThereIs; 208370b324cSopenharmony_ci bool stdOutMode = parser[(int)Key.StdOut].ThereIs; 209370b324cSopenharmony_ci 210370b324cSopenharmony_ci Stream inStream = null; 211370b324cSopenharmony_ci if (stdInMode) 212370b324cSopenharmony_ci { 213370b324cSopenharmony_ci throw (new Exception("Not implemeted")); 214370b324cSopenharmony_ci } 215370b324cSopenharmony_ci else 216370b324cSopenharmony_ci { 217370b324cSopenharmony_ci if (paramIndex >= nonSwitchStrings.Count) 218370b324cSopenharmony_ci IncorrectCommand(); 219370b324cSopenharmony_ci string inputName = (string)nonSwitchStrings[paramIndex++]; 220370b324cSopenharmony_ci inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read); 221370b324cSopenharmony_ci } 222370b324cSopenharmony_ci 223370b324cSopenharmony_ci FileStream outStream = null; 224370b324cSopenharmony_ci if (stdOutMode) 225370b324cSopenharmony_ci { 226370b324cSopenharmony_ci throw (new Exception("Not implemeted")); 227370b324cSopenharmony_ci } 228370b324cSopenharmony_ci else 229370b324cSopenharmony_ci { 230370b324cSopenharmony_ci if (paramIndex >= nonSwitchStrings.Count) 231370b324cSopenharmony_ci IncorrectCommand(); 232370b324cSopenharmony_ci string outputName = (string)nonSwitchStrings[paramIndex++]; 233370b324cSopenharmony_ci outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write); 234370b324cSopenharmony_ci } 235370b324cSopenharmony_ci 236370b324cSopenharmony_ci FileStream trainStream = null; 237370b324cSopenharmony_ci if (train.Length != 0) 238370b324cSopenharmony_ci trainStream = new FileStream(train, FileMode.Open, FileAccess.Read); 239370b324cSopenharmony_ci 240370b324cSopenharmony_ci if (encodeMode) 241370b324cSopenharmony_ci { 242370b324cSopenharmony_ci if (!dictionaryIsDefined) 243370b324cSopenharmony_ci dictionary = 1 << 23; 244370b324cSopenharmony_ci 245370b324cSopenharmony_ci Int32 posStateBits = 2; 246370b324cSopenharmony_ci Int32 litContextBits = 3; // for normal files 247370b324cSopenharmony_ci // UInt32 litContextBits = 0; // for 32-bit data 248370b324cSopenharmony_ci Int32 litPosBits = 0; 249370b324cSopenharmony_ci // UInt32 litPosBits = 2; // for 32-bit data 250370b324cSopenharmony_ci Int32 algorithm = 2; 251370b324cSopenharmony_ci Int32 numFastBytes = 128; 252370b324cSopenharmony_ci 253370b324cSopenharmony_ci bool eos = parser[(int)Key.EOS].ThereIs || stdInMode; 254370b324cSopenharmony_ci 255370b324cSopenharmony_ci if (parser[(int)Key.Mode].ThereIs) 256370b324cSopenharmony_ci if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm)) 257370b324cSopenharmony_ci IncorrectCommand(); 258370b324cSopenharmony_ci 259370b324cSopenharmony_ci if (parser[(int)Key.FastBytes].ThereIs) 260370b324cSopenharmony_ci if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes)) 261370b324cSopenharmony_ci IncorrectCommand(); 262370b324cSopenharmony_ci if (parser[(int)Key.LitContext].ThereIs) 263370b324cSopenharmony_ci if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits)) 264370b324cSopenharmony_ci IncorrectCommand(); 265370b324cSopenharmony_ci if (parser[(int)Key.LitPos].ThereIs) 266370b324cSopenharmony_ci if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits)) 267370b324cSopenharmony_ci IncorrectCommand(); 268370b324cSopenharmony_ci if (parser[(int)Key.PosBits].ThereIs) 269370b324cSopenharmony_ci if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits)) 270370b324cSopenharmony_ci IncorrectCommand(); 271370b324cSopenharmony_ci 272370b324cSopenharmony_ci CoderPropID[] propIDs = 273370b324cSopenharmony_ci { 274370b324cSopenharmony_ci CoderPropID.DictionarySize, 275370b324cSopenharmony_ci CoderPropID.PosStateBits, 276370b324cSopenharmony_ci CoderPropID.LitContextBits, 277370b324cSopenharmony_ci CoderPropID.LitPosBits, 278370b324cSopenharmony_ci CoderPropID.Algorithm, 279370b324cSopenharmony_ci CoderPropID.NumFastBytes, 280370b324cSopenharmony_ci CoderPropID.MatchFinder, 281370b324cSopenharmony_ci CoderPropID.EndMarker 282370b324cSopenharmony_ci }; 283370b324cSopenharmony_ci object[] properties = 284370b324cSopenharmony_ci { 285370b324cSopenharmony_ci (Int32)(dictionary), 286370b324cSopenharmony_ci (Int32)(posStateBits), 287370b324cSopenharmony_ci (Int32)(litContextBits), 288370b324cSopenharmony_ci (Int32)(litPosBits), 289370b324cSopenharmony_ci (Int32)(algorithm), 290370b324cSopenharmony_ci (Int32)(numFastBytes), 291370b324cSopenharmony_ci mf, 292370b324cSopenharmony_ci eos 293370b324cSopenharmony_ci }; 294370b324cSopenharmony_ci 295370b324cSopenharmony_ci Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder(); 296370b324cSopenharmony_ci encoder.SetCoderProperties(propIDs, properties); 297370b324cSopenharmony_ci encoder.WriteCoderProperties(outStream); 298370b324cSopenharmony_ci Int64 fileSize; 299370b324cSopenharmony_ci if (eos || stdInMode) 300370b324cSopenharmony_ci fileSize = -1; 301370b324cSopenharmony_ci else 302370b324cSopenharmony_ci fileSize = inStream.Length; 303370b324cSopenharmony_ci for (int i = 0; i < 8; i++) 304370b324cSopenharmony_ci outStream.WriteByte((Byte)(fileSize >> (8 * i))); 305370b324cSopenharmony_ci if (trainStream != null) 306370b324cSopenharmony_ci { 307370b324cSopenharmony_ci CDoubleStream doubleStream = new CDoubleStream(); 308370b324cSopenharmony_ci doubleStream.s1 = trainStream; 309370b324cSopenharmony_ci doubleStream.s2 = inStream; 310370b324cSopenharmony_ci doubleStream.fileIndex = 0; 311370b324cSopenharmony_ci inStream = doubleStream; 312370b324cSopenharmony_ci long trainFileSize = trainStream.Length; 313370b324cSopenharmony_ci doubleStream.skipSize = 0; 314370b324cSopenharmony_ci if (trainFileSize > dictionary) 315370b324cSopenharmony_ci doubleStream.skipSize = trainFileSize - dictionary; 316370b324cSopenharmony_ci trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin); 317370b324cSopenharmony_ci encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize)); 318370b324cSopenharmony_ci } 319370b324cSopenharmony_ci encoder.Code(inStream, outStream, -1, -1, null); 320370b324cSopenharmony_ci } 321370b324cSopenharmony_ci else if (command == "d") 322370b324cSopenharmony_ci { 323370b324cSopenharmony_ci byte[] properties = new byte[5]; 324370b324cSopenharmony_ci if (inStream.Read(properties, 0, 5) != 5) 325370b324cSopenharmony_ci throw (new Exception("input .lzma is too short")); 326370b324cSopenharmony_ci Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder(); 327370b324cSopenharmony_ci decoder.SetDecoderProperties(properties); 328370b324cSopenharmony_ci if (trainStream != null) 329370b324cSopenharmony_ci { 330370b324cSopenharmony_ci if (!decoder.Train(trainStream)) 331370b324cSopenharmony_ci throw (new Exception("can't train")); 332370b324cSopenharmony_ci } 333370b324cSopenharmony_ci long outSize = 0; 334370b324cSopenharmony_ci for (int i = 0; i < 8; i++) 335370b324cSopenharmony_ci { 336370b324cSopenharmony_ci int v = inStream.ReadByte(); 337370b324cSopenharmony_ci if (v < 0) 338370b324cSopenharmony_ci throw (new Exception("Can't Read 1")); 339370b324cSopenharmony_ci outSize |= ((long)(byte)v) << (8 * i); 340370b324cSopenharmony_ci } 341370b324cSopenharmony_ci long compressedSize = inStream.Length - inStream.Position; 342370b324cSopenharmony_ci decoder.Code(inStream, outStream, compressedSize, outSize, null); 343370b324cSopenharmony_ci } 344370b324cSopenharmony_ci else 345370b324cSopenharmony_ci throw (new Exception("Command Error")); 346370b324cSopenharmony_ci return 0; 347370b324cSopenharmony_ci } 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci [STAThread] 350370b324cSopenharmony_ci static int Main(string[] args) 351370b324cSopenharmony_ci { 352370b324cSopenharmony_ci try 353370b324cSopenharmony_ci { 354370b324cSopenharmony_ci return Main2(args); 355370b324cSopenharmony_ci } 356370b324cSopenharmony_ci catch (Exception e) 357370b324cSopenharmony_ci { 358370b324cSopenharmony_ci Console.WriteLine("{0} Caught exception #1.", e); 359370b324cSopenharmony_ci // throw e; 360370b324cSopenharmony_ci return 1; 361370b324cSopenharmony_ci } 362370b324cSopenharmony_ci } 363370b324cSopenharmony_ci } 364370b324cSopenharmony_ci} 365