Fixed merge problems
[xfstests-dev.git] / lib / databin.c
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., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, 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 <malloc.h>
40 #endif
41
42 static char Errmsg[80];
43
44 void
45 databingen (mode, buffer, bsize, offset)
46 int mode;       /* either a, c, r, o, z or C */
47 unsigned char *buffer;  /* buffer pointer */
48 int bsize;      /* size of buffer */
49 int offset;     /* offset into the file where buffer starts */
50 {
51 int ind;
52
53         switch (mode)
54         {
55         default:
56         case 'a':       /* alternating bit pattern */
57                 memset(buffer,0x55,bsize);
58                 break;
59
60         case 'c':       /* checkerboard pattern */
61                 memset(buffer,0xf0,bsize);
62                 break;
63
64         case 'C':       /* */
65                 for (ind=0;ind< bsize;ind++) {
66                     buffer[ind] = ((offset+ind)%8 & 0177);
67                 }
68                 break;
69
70         case 'o':
71                 memset(buffer,0xff,bsize);
72                 break;
73
74         case 'z':
75                 memset(buffer,0x0,bsize);
76                 break;
77
78         case 'r':       /* random */
79                 for (ind=0;ind< bsize;ind++) {
80                     buffer[ind] = (rand () & 0177) | 0100;
81                 }
82         }
83 }
84
85 /***********************************************************************
86  *
87  * return values:
88  *      >= 0 : error at byte offset into the file, offset+buffer[0-(bsize-1)]
89  *      < 0  : no error
90  ***********************************************************************/
91 int
92 databinchk(mode, buffer, bsize, offset, errmsg)
93 int mode;       /* either a, c, r, z, o, or C */
94 unsigned char *buffer;  /* buffer pointer */
95 int bsize;      /* size of buffer */
96 int offset;     /* offset into the file where buffer starts */
97 char **errmsg;
98 {
99         int cnt;
100         unsigned char *chr;
101         long expbits;
102         long actbits;
103
104         chr=buffer;
105
106         if ( errmsg != NULL ) {
107             *errmsg = Errmsg;
108         }
109         
110         switch (mode)
111         {
112         default:
113         case 'a':       /* alternating bit pattern */
114                 expbits=0x55;
115                 break;
116
117         case 'c':       /* checkerboard pattern */
118                 expbits=0xf0;
119                 break;
120
121         case 'C':       /* counting pattern */
122                 for (cnt=0;cnt< bsize;cnt++) {
123                     expbits = ((offset+cnt)%8 & 0177);
124
125                     if ( buffer[cnt] != expbits ) {
126                         sprintf(Errmsg,
127                             "data mismatch at offset %d, exp:%#lo, act:%#o",
128                             offset+cnt, expbits, buffer[cnt]);
129                         return offset+cnt;
130                     }
131                 }
132                 sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
133                 return -1;
134
135         case 'o':
136                 expbits=0xff;
137                 break;
138
139         case 'z':
140                 expbits=0;
141                 break;
142
143         case 'r':
144                 return -1;      /* no check can be done for random */
145         }
146
147         for (cnt=0; cnt<bsize; chr++, cnt++) {
148             actbits = (long)*chr;
149
150             if ( actbits != expbits ) {
151                 sprintf(Errmsg, "data mismatch at offset %d, exp:%#lo, act:%#lo",
152                     offset+cnt, expbits, actbits);
153                 return offset+cnt;
154             }
155         }
156
157         sprintf(Errmsg, "all %d bytes match desired pattern", bsize);
158         return -1; /* all ok */
159 }
160
161 #if UNIT_TEST
162
163 /***********************************************************************
164  * main for doing unit testing
165  ***********************************************************************/
166 int
167 main(ac, ag)
168 int ac;
169 char **ag;
170 {
171
172     int size=1023;
173     int offset;
174     int number;
175     unsigned char *buffer;
176     int ret;
177     char *errmsg;
178
179     if ((buffer=(unsigned char *)malloc(size)) == NULL ) {
180         perror("malloc");
181         exit(2);
182     }
183
184
185 printf("***** for a ****************************\n");
186     databingen('a', buffer, size, 0);
187     printf("databingen('a', buffer, %d, 0)\n", size);
188
189     ret=databinchk('a', buffer, size, 0, &errmsg);
190     printf("databinchk('a', buffer, %d, 0, &errmsg) returned %d: %s\n",
191         size, ret, errmsg);
192     if ( ret == -1 )
193         printf("\tPASS return value of -1 as expected\n");
194     else
195         printf("\tFAIL return value %d, expected -1\n", ret);
196
197     offset=232400;
198     ret=databinchk('a', &buffer[1], size-1, offset, &errmsg);
199     printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
200         size, offset, ret, errmsg);
201     if ( ret == -1 )
202         printf("\tPASS return value of -1 as expected\n");
203     else
204         printf("\tFAIL return value %d, expected -1\n", ret);
205
206     buffer[15]= 0x0;
207     printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
208     number=offset+15;
209
210     ret=databinchk('a', &buffer[1], size-1, offset+1, &errmsg);
211     printf("databinchk('a', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
212         size-1, offset+1, ret, errmsg);
213     if ( ret == number )
214         printf("\tPASS return value of %d as expected\n", number);
215     else
216         printf("\tFAIL return value %d, expected %d\n", ret, number);
217
218
219
220 printf("***** for c ****************************\n");
221     databingen('c', buffer, size, 0);
222     printf("databingen('c', buffer, %d, 0)\n", size);
223
224     ret=databinchk('c', buffer, size, 0, &errmsg);
225     printf("databinchk('c', buffer, %d, 0, &errmsg) returned %d: %s\n",
226         size, ret, errmsg);
227     if ( ret == -1 )
228         printf("\tPASS return value of -1 as expected\n");
229     else
230         printf("\tFAIL return value %d, expected -1\n", ret);
231
232     offset=232400;
233     ret=databinchk('c', &buffer[1], size-1, offset, &errmsg);
234     printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
235         size, offset, ret, errmsg);
236     if ( ret == -1 )
237         printf("\tPASS return value of -1 as expected\n");
238     else
239         printf("\tFAIL return value %d, expected -1\n", ret);
240
241     buffer[15]= 0x0;
242     printf("changing char 15 (offset (%d+15) = %d) to 0x0\n", offset, offset+15);
243     number=offset+15;
244
245     ret=databinchk('c', &buffer[1], size-1, offset+1, &errmsg);
246     printf("databinchk('c', &buffer[1], %d, %d, &errmsg) returned %d: %s\n",
247         size-1, offset+1, ret, errmsg);
248     if ( ret == number )
249         printf("\tPASS return value of %d as expected\n", number);
250     else
251         printf("\tFAIL return value %d, expected %d\n", ret, number);
252
253 printf("***** for C ****************************\n");
254
255     databingen('C', buffer, size, 0);
256     printf("databingen('C', buffer, %d, 0)\n", size);
257
258     ret=databinchk('C', buffer, size, 0, &errmsg);
259     printf("databinchk('C', buffer, %d, 0, &errmsg) returned %d: %s\n",
260         size, ret, errmsg);
261     if ( ret == -1 )
262         printf("\tPASS return value of -1 as expected\n");
263     else
264         printf("\tFAIL return value %d, expected -1\n", ret);
265
266     offset=18;
267     ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
268     printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
269         size-18, ret, errmsg);
270     if ( ret == -1 )
271         printf("\tPASS return value of -1 as expected\n");
272     else
273         printf("\tFAIL return value %d, expected -1\n", ret);
274
275     buffer[20]= 0x0;
276     buffer[21]= 0x0;
277     printf("changing char 20 and 21 to 0x0 (offset %d and %d)\n", 20,
278         21);
279
280     ret=databinchk('C', &buffer[18], size-18, 18, &errmsg);
281     printf("databinchk('C', &buffer[18], %d, 18, &errmsg) returned %d: %s\n",
282         size-18, ret, errmsg);
283
284     if ( ret == 20 || ret == 21 )
285         printf("\tPASS return value of %d or %d as expected\n",
286             20, 21);
287     else
288         printf("\tFAIL return value %d, expected %d or %d\n", ret,
289             20, 21 );
290
291     exit(0);
292
293 }
294
295 #endif
296