Home | History | Annotate | Download | only in lib
      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 
     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  */
     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 
    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