1 using System;
2 using System.IO;
3 using System.IO.Compression;
4
5 void PrintHelp()
6 {
7 Console.Out() <<
8 "Usage: deflate [options] <input-file> <output-file>" << endl() <<
9 "options:" << endl() <<
10 "--help (-h)" << endl() <<
11 " Print this help." << endl() <<
12 "--verbose (-v)" << endl() <<
13 " Be verbose." << endl() <<
14 "--compress (-c)" << endl() <<
15 " Compress <input-file> to <output-file>." << endl() <<
16 " (default)" << endl() <<
17 "--extract (-x)" << endl() <<
18 " Extract <input-file> to <output-file>." << endl();
19 ;
20 }
21
22 public enum Mode
23 {
24 compress, extract
25 }
26
27 int main(int argc, const char** argv)
28 {
29 string inputFile;
30 string outputFile;
31 int argCount = 0;
32 Mode mode = Mode.compress;
33 bool verbose = false;
34 for (int i = 1; i < argc; ++i;)
35 {
36 string arg = argv[i];
37 if (arg.StartsWith("-"))
38 {
39 if (arg == "--help" || arg == "-h")
40 {
41 PrintHelp();
42 return 0;
43 }
44 else if (arg == "--verbose" || arg == "-v")
45 {
46 verbose = true;
47 }
48 else if (arg == "--compress" || arg == "-c")
49 {
50 mode = Mode.compress;
51 }
52 else if (arg == "--extract" || arg == "-x")
53 {
54 mode = Mode.extract;
55 }
56 else
57 {
58 int errorId = AllocateError("unknown argument \'" + arg + "\'");
59 Console.Error() << GetErrorMessage(errorId) << endl();
60 return 1;
61 }
62 }
63 else
64 {
65 switch (argCount)
66 {
67 case 0:
68 {
69 inputFile = arg;
70 ++argCount;
71 break;
72 }
73 case 1:
74 {
75 outputFile = arg;
76 ++argCount;
77 break;
78 }
79 default:
80 {
81 ++argCount;
82 break;
83 }
84 }
85 }
86 }
87 if (argCount < 2)
88 {
89 int errorId = AllocateError("missing arguments (try --help)");
90 Console.Error() << GetErrorMessage(errorId) << endl();
91 return 1;
92 }
93 else if (argCount > 2)
94 {
95 int errorId = AllocateError("extra arguments (try --help)");
96 Console.Error() << GetErrorMessage(errorId) << endl();
97 return 1;
98 }
99 if (verbose)
100 {
101 if (mode == Mode.compress)
102 {
103 Console.Out() << "compressing \'" << inputFile << "\' to \'" << outputFile << "\'..." << endl();
104 }
105 else if (mode == Mode.extract)
106 {
107 Console.Out() << "extracting \'" << inputFile << "\' to \'" << outputFile << "\'..." << endl();
108 }
109 }
110 if (mode == Mode.compress)
111 {
112 FileStream in(inputFile, cast<OpenMode>(OpenMode.read | OpenMode.binary));
113 FileStream out(outputFile, cast<OpenMode>(OpenMode.write | OpenMode.binary));
114 DeflateStream compressStream(&out, CompressionMode.compress);
115 auto result = in.CopyTo(compressStream);
116 if (result.Error())
117 {
118 Console.Error() << result.GetErrorMessage() << endl();
119 return 1;
120 }
121 }
122 else if (mode == Mode.extract)
123 {
124 FileStream in(inputFile, cast<OpenMode>(OpenMode.read | OpenMode.binary));
125 DeflateStream extractStream(&in, CompressionMode.decompress);
126 FileStream out(outputFile, cast<OpenMode>(OpenMode.write | OpenMode.binary));
127 auto result = extractStream.CopyTo(out);
128 if (result.Error())
129 {
130 Console.Error() << result.GetErrorMessage() << endl();
131 return 1;
132 }
133 }
134 if (verbose)
135 {
136 if (mode == Mode.compress)
137 {
138 Console.Out() << "compressed." << endl();
139 }
140 else if (mode == Mode.extract)
141 {
142 Console.Out() << "extracted." << endl();
143 }
144 }
145 return 0;
146 }