Source code

Revision control

Copy as Markdown

Other Tools

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.61 2008-11-23\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;↩
}↩
}↩
}↩
}↩