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)38cmpnullbytes(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