2 * basE91 command line front-end
4 * Copyright (c) 2000-2006 Joachim Henke
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 * - Neither the name of Joachim Henke nor the names of his contributors may
16 * be used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
46 static char status[32];
47 static const char *progname;
48 static char *ibuf, *obuf;
49 static size_t ibuf_size, llen;
50 static struct basE91 b91;
52 static void stream_b91enc_p(void)
58 while ((s = fread(ibuf, 1, ibuf_size, stdin)) > 0) {
60 s = basE91_encode(&b91, ibuf, s, obuf);
62 fwrite(obuf, 1, s, stdout);
64 s = basE91_encode_end(&b91, obuf); /* empty bit queue */
66 fwrite(obuf, 1, s, stdout);
68 sprintf(status, "\t%.2f%%\n", itotal ? (float) ototal / itotal * 100.0 : 1.0);
71 static void stream_b91enc_w(void)
78 while ((s = fread(ibuf, 1, ibuf_size, stdin)) > 0) {
79 s = basE91_encode(&b91, ibuf, s, obuf);
80 for (i = 0; l <= s; l += llen) {
88 fwrite(obuf + i, 1, s - i, stdout);
91 s = basE91_encode_end(&b91, obuf);
105 sprintf(status, "\t%lu lines\n", (unsigned long) ltotal);
108 static void stream_b91dec(void)
112 while ((s = fread(ibuf, 1, ibuf_size, stdin)) > 0) {
113 s = basE91_decode(&b91, ibuf, s, obuf);
114 fwrite(obuf, 1, s, stdout);
116 s = basE91_decode_end(&b91, obuf); /* empty bit queue */
117 fwrite(obuf, 1, s, stdout);
119 sprintf(status, "done\n");
122 static int init_flags(const char *p)
124 size_t l = strlen(p);
127 progname = p + l - 6;
128 if (!strcmp(progname, "b91enc"))
130 if (!strcmp(progname, "b91dec"))
139 int main(int argc, char **argv)
141 size_t buf_size = 65536; /* buffer memory defaults to 64 KiB */
142 int flags = init_flags(*argv);
143 const char *ifile = "from standard input";
144 const char *ofile = NULL;
146 struct option longopts[8] = {
147 {"decode", no_argument, NULL, 'd'},
148 {"output", required_argument, NULL, 'o'},
149 {"verbose", no_argument, NULL, 'v'},
150 {"wrap", required_argument, NULL, 'w'},
151 {"help", no_argument, NULL, 'h'},
152 {"version", no_argument, NULL, 'V'},
156 while ((opt = getopt_long(argc, argv, "dem:o:vw:hV", longopts, NULL)) != -1)
167 long l = strtol(optarg, &t, 0);
169 if (t == optarg || strlen(t) > 1 || l < 0) {
170 fprintf(stderr, "invalid SIZE argument: `%s'\n", optarg);
185 fprintf(stderr, "invalid SIZE suffix: `%s'\n", t);
191 if (strcmp(optarg, "-"))
195 flags |= (flags & FLG_V) ? FLG_VV : FLG_V;
200 long l = strtol(optarg, &t, 0);
203 fprintf(stderr, "invalid number of columns: `%s'\n", optarg);
210 printf("Usage: %s [OPTION]... [FILE]\n"
211 "basE91 encode or decode FILE, or standard input, to standard output.\n", progname);
212 puts("\n -d, --decode\t\tdecode data\n"
213 " -m SIZE\t\tuse SIZE bytes of memory for buffers (suffixes b, K, M)\n"
214 " -o, --output=FILE\twrite to FILE instead of standard output\n"
215 " -v, --verbose\t\tverbose mode\n"
216 " -w, --wrap=COLS\twrap encoded lines after COLS characters (default 76)\n"
217 " --help\t\tdisplay this help and exit\n"
218 " --version\t\toutput version information and exit\n\n"
219 "With no FILE, or when FILE is -, read standard input.");
222 printf("%s 0.6.0\nCopyright (c) 2000-2006 Joachim Henke\n", progname);
225 fprintf(stderr, "Try `%s --help' for more information.\n", *argv);
230 ibuf_size = (buf_size - 1) << 3;
231 if (ibuf_size < 15) {
232 fputs("SIZE must be >= 3 for decoding\n", stderr);
237 ibuf_size = (buf_size - 2) << 4;
238 if (ibuf_size < 29) {
239 fputs("SIZE must be >= 4 for encoding\n", stderr);
245 if (optind < argc && strcmp(argv[optind], "-")) {
246 ifile = argv[optind];
247 if (freopen(ifile, "r", stdin) != stdin) {
253 if (freopen(ofile, "w", stdout) != stdout) {
259 fprintf(stderr, "using %lu bytes for buffers; input buffer: %lu bytes\n", (unsigned long) buf_size, (unsigned long) ibuf_size);
260 obuf = malloc(buf_size);
262 fputs("failed to allocate buffer memory\n", stderr);
268 _setmode(_fileno(stdin), _O_BINARY);
273 _setmode(_fileno(stdout), _O_BINARY);
275 ibuf = obuf + 1; /* create overlapping buffers to use memory efficiently */
277 fprintf(stderr, "decoding %s ...", ifile);
280 ibuf = obuf + buf_size - ibuf_size; /* partial overlap */
282 fprintf(stderr, "encoding %s ...", ifile);
291 fputs(status, stderr);