1 /*
2 * test_encoding.cc: Part of GNU CSSC.
3 *
4 * Copyright (C) 1997, 1998, 2007, 2010, 2011, 2013, 2019 Free Software
5 * Foundation, Inc.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 #include <cstdio>
21 #include <cstddef>
22 #include <cstring>
23 #include <cstdlib>
24
25 #include "bodyio.h"
26
27 using encoding_impl::decode;
28 using encoding_impl::encode;
29
30 int
test_encode(void)31 test_encode(void)
32 {
33 return encode_stream(stdin, stdout);
34 }
35
36 int
test_decode(void)37 test_decode(void)
38 {
39 char inbuf[80], outbuf[80];
40 while ( 0 != fgets(inbuf, sizeof(inbuf)-1, stdin) )
41 {
42 int len = decode_line(inbuf, outbuf);
43 if (0 == len)
44 return 0;
45 fwrite(outbuf, 1, len, stdout);
46 }
47 return 1;
48 }
49
50
51 // Test all possible inputs for encode(); decode its
52 // outputs and check that they decode back to the correct value.
test_all(void)53 int test_all(void)
54 {
55 union lunch { long l; char ch[4]; } in, out;
56 long i;
57
58 // i only has to hlod a 24-bit value.
59 const long maxval = 0xff | (0xff<<8) | (0xff<<16);
60 const double dmaxval = maxval;
61 for (i=0; i<=maxval; i++)
62 {
63 if ( 0x7FFFF == (i & 0x7FFFF) )
64 {
65 double completed = (100.0 * i) / dmaxval;
66 printf("%06lx %3.0f%%...\n", i, completed);
67 }
68
69
70 in.ch[0] = (i & 0x0000ff) >> 0;
71 in.ch[1] = (i & 0x00ff00) >> 8;
72 in.ch[2] = (i & 0xff0000) >> 16;
73 in.ch[3] = '\0';
74
75 encode(in.ch, out.ch);
76 decode(out.ch, in.ch);
77 const long l0 = ((unsigned char) in.ch[0]) & 0xff;
78 const long l1 = ((unsigned char) in.ch[1]) & 0xff;
79 const long l2 = ((unsigned char) in.ch[2]) & 0xff;
80 const long lo = l0 | l1<<8 | l2<<16;
81
82 if (lo != i)
83 {
84 fprintf(stderr,
85 "Asymmetry!\n"
86 "Input was %06lx, output was %05lx\n",
87 i, lo);
88 return 1;
89 }
90 }
91 printf("Success!\n");
92 return 0;
93 }
94
95 const char *options[] = { "--encode", "--decode", "--all" };
96 int (* const actions[])(void) = { test_encode, test_decode, test_all };
97
98 #define NELEM(array) (sizeof(array)/sizeof(array[0]))
99
100
101 static void
usage(const char * prog)102 usage(const char *prog)
103 {
104 fprintf(stderr, "Usage: %s [", prog);
105 for (size_t i=0; i<NELEM(options); ++i)
106 {
107 fprintf(stderr, "%s %s", (i>0) ? " |" : "", options[i]);
108 }
109 fprintf(stderr, " ]\n");
110 }
111
112 int
main(int argc,char * argv[])113 main(int argc, char *argv[])
114 {
115 if (2 == argc)
116 {
117 for (size_t i=0; i<NELEM(options); ++i)
118 if (0 == strcmp(options[i], argv[1]))
119 return (actions[i])();
120 }
121 else if (1 == argc)
122 {
123 // No options specified; the default is to perform the sanity test.
124 return test_all();
125 }
126 else
127 {
128 usage(argv[0] ? argv[0] : "encoding-test");
129 }
130 return 1;
131 }
132