1 /* @(#)cmpnullbytes.c	1.10 10/08/21 Copyright 1988,2002-2010 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)cmpnullbytes.c	1.10 10/08/21 Copyright 1988,2002-2010 J. Schilling";
6 #endif  /* lint */
7 /*
8  *	compare data against null
9  *	Return the index of the first non-null character
10  *
11  *	Copyright (c) 1988,2002-2010 J. Schilling
12  */
13 /*
14  * The contents of this file are subject to the terms of the
15  * Common Development and Distribution License, Version 1.0 only
16  * (the "License").  You may not use this file except in compliance
17  * with the License.
18  *
19  * See the file CDDL.Schily.txt in this distribution for details.
20  * A copy of the CDDL is also available via the Internet at
21  * http://www.opensource.org/licenses/cddl1.txt
22  *
23  * When distributing Covered Code, include this CDDL HEADER in each
24  * file and include the License file CDDL.Schily.txt from this distribution.
25  */
26 
27 #include <schily/standard.h>
28 #include <schily/align.h>
29 #include <schily/types.h>
30 #include <schily/schily.h>
31 
32 #define	DO8(a)	a; a; a; a; a; a; a; a;
33 
34 /*
35  * Return the index of the first non-null character
36  */
37 EXPORT ssize_t
cmpnullbytes(fromp,cnt)38 cmpnullbytes(fromp, cnt)
39 	const void	*fromp;
40 	ssize_t		cnt;
41 {
42 	register const char	*from	= (char *)fromp;
43 	register ssize_t	n;
44 
45 	/*
46 	 * If we change cnt to be unsigned, check for == instead of <=
47 	 */
48 	if ((n = cnt) <= 0)
49 		return (cnt);
50 
51 	/*
52 	 * Compare byte-wise until properly aligned for a long pointer.
53 	 */
54 	while (--n >= 0 && !laligned(from)) {
55 		if (*from++ != 0)
56 			goto cdiff;
57 	}
58 	n++;
59 
60 	if (n >= (ssize_t)(8 * sizeof (long))) {
61 		if (laligned(from)) {
62 			register const long *froml = (const long *)from;
63 			register ssize_t rem = n % (8 * sizeof (long));
64 
65 			n /= (8 * sizeof (long));
66 			do {
67 				/* BEGIN CSTYLED */
68 				DO8(
69 					if (*froml++ != 0)
70 						break;
71 				);
72 				/* END CSTYLED */
73 			} while (--n > 0);
74 
75 			if (n > 0) {
76 				--froml;
77 				from = (const char *)froml;
78 				goto ldiff;
79 			}
80 			from = (const char *)froml;
81 			n = rem;
82 		}
83 
84 		if (n >= 8) {
85 			n -= 8;
86 			do {
87 				/* BEGIN CSTYLED */
88 				DO8(
89 					if (*from++ != 0)
90 						goto cdiff;
91 				);
92 				/* END CSTYLED */
93 			} while ((n -= 8) >= 0);
94 			n += 8;
95 		}
96 		if (n > 0) do {
97 			if (*from++ != 0)
98 				goto cdiff;
99 		} while (--n > 0);
100 		return (cnt);
101 	}
102 	if (n > 0) do {
103 		if (*from++ != 0)
104 			goto cdiff;
105 	} while (--n > 0);
106 	return (cnt);
107 ldiff:
108 	n = sizeof (long);
109 	do {
110 		if (*from++ != 0)
111 			goto cdiff;
112 	} while (--n > 0);
113 cdiff:
114 	return ((ssize_t)(--from - (char *)fromp));
115 }
116