OLD | NEW |
| (Empty) |
1 using System; | |
2 using System.IO; | |
3 namespace SevenZip | |
4 { | |
5 using CommandLineParser; | |
6 | |
7 public class CDoubleStream: Stream | |
8 { | |
9 public System.IO.Stream s1; | |
10 public System.IO.Stream s2; | |
11 public int fileIndex; | |
12 public long skipSize; | |
13 | |
14 public override bool CanRead { get { return true; }} | |
15 public override bool CanWrite { get { return false; }} | |
16 public override bool CanSeek { get { return false; }} | |
17 public override long Length { get { return s1.Length + s2.Length
- skipSize; } } | |
18 public override long Position | |
19 { | |
20 get { return 0; } | |
21 set { } | |
22 } | |
23 public override void Flush() { } | |
24 public override int Read(byte[] buffer, int offset, int count) | |
25 { | |
26 int numTotal = 0; | |
27 while (count > 0) | |
28 { | |
29 if (fileIndex == 0) | |
30 { | |
31 int num = s1.Read(buffer, offset, count)
; | |
32 offset += num; | |
33 count -= num; | |
34 numTotal += num; | |
35 if (num == 0) | |
36 fileIndex++; | |
37 } | |
38 if (fileIndex == 1) | |
39 { | |
40 numTotal += s2.Read(buffer, offset, coun
t); | |
41 return numTotal; | |
42 } | |
43 } | |
44 return numTotal; | |
45 } | |
46 public override void Write(byte[] buffer, int offset, int count) | |
47 { | |
48 throw (new Exception("can't Write")); | |
49 } | |
50 public override long Seek(long offset, System.IO.SeekOrigin orig
in) | |
51 { | |
52 throw (new Exception("can't Seek")); | |
53 } | |
54 public override void SetLength(long value) | |
55 { | |
56 throw (new Exception("can't SetLength")); | |
57 } | |
58 } | |
59 | |
60 class LzmaAlone | |
61 { | |
62 enum Key | |
63 { | |
64 Help1 = 0, | |
65 Help2, | |
66 Mode, | |
67 Dictionary, | |
68 FastBytes, | |
69 LitContext, | |
70 LitPos, | |
71 PosBits, | |
72 MatchFinder, | |
73 EOS, | |
74 StdIn, | |
75 StdOut, | |
76 Train | |
77 }; | |
78 | |
79 static void PrintHelp() | |
80 { | |
81 System.Console.WriteLine("\nUsage: LZMA <e|d> [<switche
s>...] inputFile outputFile\n" + | |
82 " e: encode file\n" + | |
83 " d: decode file\n" + | |
84 " b: Benchmark\n" + | |
85 "<Switches>\n" + | |
86 // " -a{N}: set compression mode - [0, 1], def
ault: 1 (max)\n" + | |
87 " -d{N}: set dictionary - [0, 29], default: 23
(8MB)\n" + | |
88 " -fb{N}: set number of fast bytes - [5, 273],
default: 128\n" + | |
89 " -lc{N}: set number of literal context bits -
[0, 8], default: 3\n" + | |
90 " -lp{N}: set number of literal pos bits - [0,
4], default: 0\n" + | |
91 " -pb{N}: set number of pos bits - [0, 4], defa
ult: 2\n" + | |
92 " -mf{MF_ID}: set Match Finder: [bt2, bt4], def
ault: bt4\n" + | |
93 " -eos: write End Of Stream marker\n" | |
94 // + " -si: read data from stdin\n" | |
95 // + " -so: write data to stdout\n" | |
96 ); | |
97 } | |
98 | |
99 static bool GetNumber(string s, out Int32 v) | |
100 { | |
101 v = 0; | |
102 for (int i = 0; i < s.Length; i++) | |
103 { | |
104 char c = s[i]; | |
105 if (c < '0' || c > '9') | |
106 return false; | |
107 v *= 10; | |
108 v += (Int32)(c - '0'); | |
109 } | |
110 return true; | |
111 } | |
112 | |
113 static int IncorrectCommand() | |
114 { | |
115 throw (new Exception("Command line error")); | |
116 // System.Console.WriteLine("\nCommand line error\n"); | |
117 // return 1; | |
118 } | |
119 static int Main2(string[] args) | |
120 { | |
121 System.Console.WriteLine("\nLZMA# 4.61 2008-11-23\n"); | |
122 | |
123 if (args.Length == 0) | |
124 { | |
125 PrintHelp(); | |
126 return 0; | |
127 } | |
128 | |
129 SwitchForm[] kSwitchForms = new SwitchForm[13]; | |
130 int sw = 0; | |
131 kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simp
le, false); | |
132 kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simp
le, false); | |
133 kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLi
mitedPostString, false, 1); | |
134 kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLi
mitedPostString, false, 1); | |
135 kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnL
imitedPostString, false, 1); | |
136 kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnL
imitedPostString, false, 1); | |
137 kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnL
imitedPostString, false, 1); | |
138 kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnL
imitedPostString, false, 1); | |
139 kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnL
imitedPostString, false, 1); | |
140 kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Si
mple, false); | |
141 kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Sim
ple, false); | |
142 kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Sim
ple, false); | |
143 kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLi
mitedPostString, false, 1); | |
144 | |
145 | |
146 Parser parser = new Parser(sw); | |
147 try | |
148 { | |
149 parser.ParseStrings(kSwitchForms, args); | |
150 } | |
151 catch | |
152 { | |
153 return IncorrectCommand(); | |
154 } | |
155 | |
156 if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.He
lp2].ThereIs) | |
157 { | |
158 PrintHelp(); | |
159 return 0; | |
160 } | |
161 | |
162 System.Collections.ArrayList nonSwitchStrings = parser.N
onSwitchStrings; | |
163 | |
164 int paramIndex = 0; | |
165 if (paramIndex >= nonSwitchStrings.Count) | |
166 return IncorrectCommand(); | |
167 string command = (string)nonSwitchStrings[paramIndex++]; | |
168 command = command.ToLower(); | |
169 | |
170 bool dictionaryIsDefined = false; | |
171 Int32 dictionary = 1 << 21; | |
172 if (parser[(int)Key.Dictionary].ThereIs) | |
173 { | |
174 Int32 dicLog; | |
175 if (!GetNumber((string)parser[(int)Key.Dictionar
y].PostStrings[0], out dicLog)) | |
176 IncorrectCommand(); | |
177 dictionary = (Int32)1 << dicLog; | |
178 dictionaryIsDefined = true; | |
179 } | |
180 string mf = "bt4"; | |
181 if (parser[(int)Key.MatchFinder].ThereIs) | |
182 mf = (string)parser[(int)Key.MatchFinder].PostSt
rings[0]; | |
183 mf = mf.ToLower(); | |
184 | |
185 if (command == "b") | |
186 { | |
187 const Int32 kNumDefaultItereations = 10; | |
188 Int32 numIterations = kNumDefaultItereations; | |
189 if (paramIndex < nonSwitchStrings.Count) | |
190 if (!GetNumber((string)nonSwitchStrings[
paramIndex++], out numIterations)) | |
191 numIterations = kNumDefaultItere
ations; | |
192 return LzmaBench.LzmaBenchmark(numIterations, (U
Int32)dictionary); | |
193 } | |
194 | |
195 string train = ""; | |
196 if (parser[(int)Key.Train].ThereIs) | |
197 train = (string)parser[(int)Key.Train].PostStrin
gs[0]; | |
198 | |
199 bool encodeMode = false; | |
200 if (command == "e") | |
201 encodeMode = true; | |
202 else if (command == "d") | |
203 encodeMode = false; | |
204 else | |
205 IncorrectCommand(); | |
206 | |
207 bool stdInMode = parser[(int)Key.StdIn].ThereIs; | |
208 bool stdOutMode = parser[(int)Key.StdOut].ThereIs; | |
209 | |
210 Stream inStream = null; | |
211 if (stdInMode) | |
212 { | |
213 throw (new Exception("Not implemeted")); | |
214 } | |
215 else | |
216 { | |
217 if (paramIndex >= nonSwitchStrings.Count) | |
218 IncorrectCommand(); | |
219 string inputName = (string)nonSwitchStrings[para
mIndex++]; | |
220 inStream = new FileStream(inputName, FileMode.Op
en, FileAccess.Read); | |
221 } | |
222 | |
223 FileStream outStream = null; | |
224 if (stdOutMode) | |
225 { | |
226 throw (new Exception("Not implemeted")); | |
227 } | |
228 else | |
229 { | |
230 if (paramIndex >= nonSwitchStrings.Count) | |
231 IncorrectCommand(); | |
232 string outputName = (string)nonSwitchStrings[par
amIndex++]; | |
233 outStream = new FileStream(outputName, FileMode.
Create, FileAccess.Write); | |
234 } | |
235 | |
236 FileStream trainStream = null; | |
237 if (train.Length != 0) | |
238 trainStream = new FileStream(train, FileMode.Ope
n, FileAccess.Read); | |
239 | |
240 if (encodeMode) | |
241 { | |
242 if (!dictionaryIsDefined) | |
243 dictionary = 1 << 23; | |
244 | |
245 Int32 posStateBits = 2; | |
246 Int32 litContextBits = 3; // for normal files | |
247 // UInt32 litContextBits = 0; // for 32-bit data | |
248 Int32 litPosBits = 0; | |
249 // UInt32 litPosBits = 2; // for 32-bit data | |
250 Int32 algorithm = 2; | |
251 Int32 numFastBytes = 128; | |
252 | |
253 bool eos = parser[(int)Key.EOS].ThereIs || stdIn
Mode; | |
254 | |
255 if (parser[(int)Key.Mode].ThereIs) | |
256 if (!GetNumber((string)parser[(int)Key.M
ode].PostStrings[0], out algorithm)) | |
257 IncorrectCommand(); | |
258 | |
259 if (parser[(int)Key.FastBytes].ThereIs) | |
260 if (!GetNumber((string)parser[(int)Key.F
astBytes].PostStrings[0], out numFastBytes)) | |
261 IncorrectCommand(); | |
262 if (parser[(int)Key.LitContext].ThereIs) | |
263 if (!GetNumber((string)parser[(int)Key.L
itContext].PostStrings[0], out litContextBits)) | |
264 IncorrectCommand(); | |
265 if (parser[(int)Key.LitPos].ThereIs) | |
266 if (!GetNumber((string)parser[(int)Key.L
itPos].PostStrings[0], out litPosBits)) | |
267 IncorrectCommand(); | |
268 if (parser[(int)Key.PosBits].ThereIs) | |
269 if (!GetNumber((string)parser[(int)Key.P
osBits].PostStrings[0], out posStateBits)) | |
270 IncorrectCommand(); | |
271 | |
272 CoderPropID[] propIDs = | |
273 { | |
274 CoderPropID.DictionarySize, | |
275 CoderPropID.PosStateBits, | |
276 CoderPropID.LitContextBits, | |
277 CoderPropID.LitPosBits, | |
278 CoderPropID.Algorithm, | |
279 CoderPropID.NumFastBytes, | |
280 CoderPropID.MatchFinder, | |
281 CoderPropID.EndMarker | |
282 }; | |
283 object[] properties = | |
284 { | |
285 (Int32)(dictionary), | |
286 (Int32)(posStateBits), | |
287 (Int32)(litContextBits), | |
288 (Int32)(litPosBits), | |
289 (Int32)(algorithm), | |
290 (Int32)(numFastBytes), | |
291 mf, | |
292 eos | |
293 }; | |
294 | |
295 Compression.LZMA.Encoder encoder = new Compressi
on.LZMA.Encoder(); | |
296 encoder.SetCoderProperties(propIDs, properties); | |
297 encoder.WriteCoderProperties(outStream); | |
298 Int64 fileSize; | |
299 if (eos || stdInMode) | |
300 fileSize = -1; | |
301 else | |
302 fileSize = inStream.Length; | |
303 for (int i = 0; i < 8; i++) | |
304 outStream.WriteByte((Byte)(fileSize >> (
8 * i))); | |
305 if (trainStream != null) | |
306 { | |
307 CDoubleStream doubleStream = new CDouble
Stream(); | |
308 doubleStream.s1 = trainStream; | |
309 doubleStream.s2 = inStream; | |
310 doubleStream.fileIndex = 0; | |
311 inStream = doubleStream; | |
312 long trainFileSize = trainStream.Length; | |
313 doubleStream.skipSize = 0; | |
314 if (trainFileSize > dictionary) | |
315 doubleStream.skipSize = trainFil
eSize - dictionary; | |
316 trainStream.Seek(doubleStream.skipSize,
SeekOrigin.Begin); | |
317 encoder.SetTrainSize((uint)(trainFileSiz
e - doubleStream.skipSize)); | |
318 } | |
319 encoder.Code(inStream, outStream, -1, -1, null); | |
320 } | |
321 else if (command == "d") | |
322 { | |
323 byte[] properties = new byte[5]; | |
324 if (inStream.Read(properties, 0, 5) != 5) | |
325 throw (new Exception("input .lzma is too
short")); | |
326 Compression.LZMA.Decoder decoder = new Compressi
on.LZMA.Decoder(); | |
327 decoder.SetDecoderProperties(properties); | |
328 if (trainStream != null) | |
329 { | |
330 if (!decoder.Train(trainStream)) | |
331 throw (new Exception("can't trai
n")); | |
332 } | |
333 long outSize = 0; | |
334 for (int i = 0; i < 8; i++) | |
335 { | |
336 int v = inStream.ReadByte(); | |
337 if (v < 0) | |
338 throw (new Exception("Can't Read
1")); | |
339 outSize |= ((long)(byte)v) << (8 * i); | |
340 } | |
341 long compressedSize = inStream.Length - inStream
.Position; | |
342 decoder.Code(inStream, outStream, compressedSize
, outSize, null); | |
343 } | |
344 else | |
345 throw (new Exception("Command Error")); | |
346 return 0; | |
347 } | |
348 | |
349 [STAThread] | |
350 static int Main(string[] args) | |
351 { | |
352 try | |
353 { | |
354 return Main2(args); | |
355 } | |
356 catch (Exception e) | |
357 { | |
358 Console.WriteLine("{0} Caught exception #1.", e)
; | |
359 // throw e; | |
360 return 1; | |
361 } | |
362 } | |
363 } | |
364 } | |
OLD | NEW |