replay-log: add support for replaying ops in target device sector range
[xfstests-dev.git] / lib / pattern.c
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include <string.h>
19 #include "pattern.h"
20
21 /*
22  * The routines in this module are used to fill/check a data buffer
23  * with/against a known pattern.
24  */
25
26 int
27 pattern_check(buf, buflen, pat, patlen, patshift)
28 char    *buf;
29 int     buflen;
30 char    *pat;
31 int     patlen;
32 int     patshift;
33 {
34     int         nb, ncmp, nleft;
35     char        *cp;
36
37     if (patlen)
38         patshift = patshift % patlen;
39
40     cp = buf;
41     nleft = buflen;
42
43     /*
44      * The following 2 blocks of code are to compare the first patlen
45      * bytes of buf.  We need 2 checks if patshift is > 0 since we
46      * must check the last (patlen - patshift) bytes, and then the
47      * first (patshift) bytes.
48      */
49
50     nb = patlen - patshift;
51     if (nleft < nb) {
52         return (memcmp(cp, pat + patshift, nleft) ? -1 : 0);
53     } else {
54         if (memcmp(cp, pat + patshift, nb))
55             return -1;
56
57         nleft -= nb;
58         cp += nb;
59     }
60
61     if (patshift > 0) {
62         nb = patshift;
63         if (nleft < nb) {
64             return (memcmp(cp, pat, nleft) ? -1 : 0);
65         } else {
66             if (memcmp(cp, pat, nb))
67                 return -1;
68
69             nleft -= nb;
70             cp += nb;
71         }
72     }
73
74     /*
75      * Now, verify the rest of the buffer using the algorithm described
76      * in the function header.
77      */
78
79     ncmp = cp - buf;
80     while (ncmp < buflen) {
81         nb = (ncmp < nleft) ? ncmp : nleft;
82         if (memcmp(buf, cp, nb))
83             return -1;
84
85         cp += nb;
86         ncmp += nb;
87         nleft -= nb;
88     }
89
90     return 0;
91 }
92
93 int
94 pattern_fill(buf, buflen, pat, patlen, patshift)
95 char    *buf;
96 int     buflen;
97 char    *pat;
98 int     patlen;
99 int     patshift;
100 {
101     int         trans, ncopied, nleft;
102     char        *cp;
103
104     if (patlen)
105         patshift = patshift % patlen;
106
107     cp = buf;
108     nleft = buflen;
109
110     /*
111      * The following 2 blocks of code are to fill the first patlen
112      * bytes of buf.  We need 2 sections if patshift is > 0 since we
113      * must first copy the last (patlen - patshift) bytes into buf[0]...,
114      * and then the first (patshift) bytes of pattern following them.
115      */
116
117     trans = patlen - patshift;
118     if (nleft < trans) {
119         memcpy(cp, pat + patshift, nleft);
120         return 0;
121     } else {
122         memcpy(cp, pat + patshift, trans);
123         nleft -= trans;
124         cp += trans;
125     }
126
127     if (patshift > 0) {
128         trans = patshift;
129         if (nleft < trans) {
130             memcpy(cp, pat, nleft);
131             return 0;
132         } else {
133             memcpy(cp, pat, trans);
134             nleft -= trans;
135             cp += trans;
136         }
137     }
138
139     /*
140      * Now, fill the rest of the buffer using the algorithm described
141      * in the function header comment.
142      */
143
144     ncopied = cp - buf;
145     while (ncopied < buflen) {
146         trans = (ncopied < nleft) ? ncopied : nleft;
147         memcpy(cp, buf, trans);
148         cp += trans;
149         ncopied += trans;
150         nleft -= trans;
151     }
152
153     return(0);
154 }