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