1 /*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31 */
32 #include <stdio.h>
33 #include <sys/param.h>
34 #include <string.h> /* memset */
35 #include <stdlib.h> /* rand */
36 #include "databin.h"
37
38 #if UNIT_TEST
39 #include <stdlib.h>
40 #endif
41
42 static char Errmsg[80];
43
databingen(int mode,char * buffer,int bsize,int offset)44 void databingen(int mode, char *buffer, int bsize, int offset)
45 {
46 int ind;
47
48 switch (mode) {
49 default:
50 case 'a': /* alternating bit pattern */
51 memset(buffer, 0x55, bsize);
52 break;
53
54 case 'c': /* checkerboard pattern */
55 memset(buffer, 0xf0, bsize);
56 break;
57
58 case 'C': /* */
59 for (ind = 0; ind < bsize; ind++)
60 buffer[ind] = ((offset + ind) % 8 & 0177);
61
62 break;
63
64 case 'o':
65 memset(buffer, 0xff, bsize);
66 break;
67
68 case 'z':
69 memset(buffer, 0x0, bsize);
70 break;
71
72 case 'r': /* random */
73 for (ind = 0; ind < bsize; ind++)
74 buffer[ind] = (rand() & 0177) | 0100;
75 }
76 }
77
78 /*
79 * return values:
80 * >= 0 : error at byte offset into the file, offset+buffer[0-(bsize-1)]
81 * < 0 : no error
82 */
databinchk(int mode,char * buffer,int bsize,int offset,char ** errmsg)83 int databinchk(int mode, char *buffer, int bsize, int offset, char **errmsg)
84 {
85 int cnt;
86 unsigned char *chr;
87 long expbits;
88 long actbits;
89
90 chr = (unsigned char *)buffer;
91
92 if (errmsg != NULL)
93 *errmsg = Errmsg;
94
95 switch (mode) {
96 default:
97 case 'a': /* alternating bit pattern */
98 expbits = 0x55;
99 break;
100
101 case 'c': /* checkerboard pattern */
102 expbits = 0xf0;
103 break;
104
105 case 'C': /* counting pattern */
106 for (cnt = 0; cnt < bsize; cnt++) {
107 expbits = ((offset + cnt) % 8 & 0177);
108
109 if (buffer[cnt] != expbits) {
110 sprintf(Errmsg,
111 "data mismatch at offset %d, exp:%#lo, act:%#o",
112 offset + cnt, expbits, buffer[cnt]);
113 return offset + cnt;
114 }
115 }
116 sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
117 return -1;
118
119 case 'o':
120 expbits = 0xff;
121 break;
122
123 case 'z':
124 expbits = 0;
125 break;
126
127 case 'r':
128 return -1; /* no check can be done for random */
129 }
130
131 for (cnt = 0; cnt < bsize; chr++, cnt++) {
132 actbits = (long)*chr;
133
134 if (actbits != expbits) {
135 sprintf(Errmsg,
136 "data mismatch at offset %d, exp:%#lo, act:%#lo",
137 offset + cnt, expbits, actbits);
138 return offset + cnt;
139 }
140 }
141
142 sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
143 return -1;
144 }
145
146 #if UNIT_TEST
147
main(int ac,char ** ag)148 int main(int ac, char **ag)
149 {
150 int size = 1023;
151 int offset;
152 int number;
153 unsigned char *buffer;
154 int ret;
155 char *errmsg;
156
157 buffer = malloc(size);
158 if (buffer == NULL) {
159 perror("malloc");
160 exit(2);
161 }
162
163 printf("***** for a ****************************\n");
164 databingen('a', buffer, size, 0);
165 printf("databingen('a', buffer, %d, 0)\n", size);
166
167 ret = databinchk('a', buffer, size, 0, &errmsg);
168 printf("databinchk('a', buffer, %d, 0, &errmsg) returned %d: %s\n",
169 size, ret, errmsg);
170 if (ret == -1)
171 printf("\tPASS return value of -1 as expected\n");
172 else
173 printf("\tFAIL return value %d, expected -1\n", ret);
174
175 offset = 232400;
176 ret = databinchk('a', &buffer[1], size - 1, offset, &errmsg);
177 printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
178 size, offset, ret, errmsg);
179 if (ret == -1)
180 printf("\tPASS return value of -1 as expected\n");
181 else
182 printf("\tFAIL return value %d, expected -1\n", ret);
183
184 buffer[15] = 0x0;
185 printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset,
186 offset + 15);
187 number = offset + 15;
188
189 ret = databinchk('a', &buffer[1], size - 1, offset + 1, &errmsg);
190 printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
191 size - 1, offset + 1, ret, errmsg);
192 if (ret == number)
193 printf("\tPASS return value of %d as expected\n", number);
194 else
195 printf("\tFAIL return value %d, expected %d\n", ret, number);
196
197 printf("***** for c ****************************\n");
198 databingen('c', buffer, size, 0);
199 printf("databingen('c', buffer, %d, 0)\n", size);
200
201 ret = databinchk('c', buffer, size, 0, &errmsg);
202 printf("databinchk('c', buffer, %d, 0, &errmsg) returned %d: %s\n",
203 size, ret, errmsg);
204 if (ret == -1)
205 printf("\tPASS return value of -1 as expected\n");
206 else
207 printf("\tFAIL return value %d, expected -1\n", ret);
208
209 offset = 232400;
210 ret = databinchk('c', &buffer[1], size - 1, offset, &errmsg);
211 printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
212 size, offset, ret, errmsg);
213 if (ret == -1)
214 printf("\tPASS return value of -1 as expected\n");
215 else
216 printf("\tFAIL return value %d, expected -1\n", ret);
217
218 buffer[15] = 0x0;
219 printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset,
220 offset + 15);
221 number = offset + 15;
222
223 ret = databinchk('c', &buffer[1], size - 1, offset + 1, &errmsg);
224 printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
225 size - 1, offset + 1, ret, errmsg);
226 if (ret == number)
227 printf("\tPASS return value of %d as expected\n", number);
228 else
229 printf("\tFAIL return value %d, expected %d\n", ret, number);
230
231 printf("***** for C ****************************\n");
232
233 databingen('C', buffer, size, 0);
234 printf("databingen('C', buffer, %d, 0)\n", size);
235
236 ret = databinchk('C', buffer, size, 0, &errmsg);
237 printf("databinchk('C', buffer, %d, 0, &errmsg) returned %d: %s\n",
238 size, ret, errmsg);
239 if (ret == -1)
240 printf("\tPASS return value of -1 as expected\n");
241 else
242 printf("\tFAIL return value %d, expected -1\n", ret);
243
244 offset = 18;
245 ret = databinchk('C', &buffer[18], size - 18, 18, &errmsg);
246 printf
247 ("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
248 size - 18, ret, errmsg);
249 if (ret == -1)
250 printf("\tPASS return value of -1 as expected\n");
251 else
252 printf("\tFAIL return value %d, expected -1\n", ret);
253
254 buffer[20] = 0x0;
255 buffer[21] = 0x0;
256 printf("changing char 20 and 21 to 0x0 (offset %d and %d)\n", 20, 21);
257
258 ret = databinchk('C', &buffer[18], size - 18, 18, &errmsg);
259 printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
260 size - 18, ret, errmsg);
261
262 if (ret == 20 || ret == 21)
263 printf("\tPASS return value of %d or %d as expected\n", 20, 21);
264 else
265 printf("\tFAIL return value %d, expected %d or %d\n", ret,
266 20, 21);
267
268 exit(0);
269
270 }
271
272 #endif
273