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 <string.h> 33 #include "pattern.h" 34 35 /* 36 * The routines in this module are used to fill/check a data buffer 37 * with/against a known pattern. 38 */ 39 40 int pattern_check(char *buf, int buflen, char *pat, int patlen, int patshift) 41 { 42 int nb, ncmp, nleft; 43 char *cp; 44 45 if (patlen) 46 patshift = patshift % patlen; 47 48 cp = buf; 49 nleft = buflen; 50 51 /* 52 * The following 2 blocks of code are to compare the first patlen 53 * bytes of buf. We need 2 checks if patshift is > 0 since we 54 * must check the last (patlen - patshift) bytes, and then the 55 * first (patshift) bytes. 56 */ 57 58 nb = patlen - patshift; 59 if (nleft < nb) { 60 return (memcmp(cp, pat + patshift, nleft) ? -1 : 0); 61 } else { 62 if (memcmp(cp, pat + patshift, nb)) 63 return -1; 64 65 nleft -= nb; 66 cp += nb; 67 } 68 69 if (patshift > 0) { 70 nb = patshift; 71 if (nleft < nb) { 72 return (memcmp(cp, pat, nleft) ? -1 : 0); 73 } else { 74 if (memcmp(cp, pat, nb)) 75 return -1; 76 77 nleft -= nb; 78 cp += nb; 79 } 80 } 81 82 /* 83 * Now, verify the rest of the buffer using the algorithm described 84 * in the function header. 85 */ 86 87 ncmp = cp - buf; 88 while (ncmp < buflen) { 89 nb = (ncmp < nleft) ? ncmp : nleft; 90 if (memcmp(buf, cp, nb)) 91 return -1; 92 93 cp += nb; 94 ncmp += nb; 95 nleft -= nb; 96 } 97 98 return 0; 99 } 100 101 int pattern_fill(char *buf, int buflen, char *pat, int patlen, int patshift) 102 { 103 int trans, ncopied, nleft; 104 char *cp; 105 106 if (patlen) 107 patshift = patshift % patlen; 108 109 cp = buf; 110 nleft = buflen; 111 112 /* 113 * The following 2 blocks of code are to fill the first patlen 114 * bytes of buf. We need 2 sections if patshift is > 0 since we 115 * must first copy the last (patlen - patshift) bytes into buf[0]..., 116 * and then the first (patshift) bytes of pattern following them. 117 */ 118 119 trans = patlen - patshift; 120 if (nleft < trans) { 121 memcpy(cp, pat + patshift, nleft); 122 return 0; 123 } else { 124 memcpy(cp, pat + patshift, trans); 125 nleft -= trans; 126 cp += trans; 127 } 128 129 if (patshift > 0) { 130 trans = patshift; 131 if (nleft < trans) { 132 memcpy(cp, pat, nleft); 133 return 0; 134 } else { 135 memcpy(cp, pat, trans); 136 nleft -= trans; 137 cp += trans; 138 } 139 } 140 141 /* 142 * Now, fill the rest of the buffer using the algorithm described 143 * in the function header comment. 144 */ 145 146 ncopied = cp - buf; 147 while (ncopied < buflen) { 148 trans = (ncopied < nleft) ? ncopied : nleft; 149 memcpy(cp, buf, trans); 150 cp += trans; 151 ncopied += trans; 152 nleft -= trans; 153 } 154 155 return (0); 156 } 157