generic: test MADV_POPULATE_READ with IO errors
[xfstests-dev.git] / lib / pattern.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include <string.h>
7 #include "pattern.h"
8
9 /*
10  * The routines in this module are used to fill/check a data buffer
11  * with/against a known pattern.
12  */
13
14 int
15 pattern_check(buf, buflen, pat, patlen, patshift)
16 char    *buf;
17 int     buflen;
18 char    *pat;
19 int     patlen;
20 int     patshift;
21 {
22     int         nb, ncmp, nleft;
23     char        *cp;
24
25     if (patlen)
26         patshift = patshift % patlen;
27
28     cp = buf;
29     nleft = buflen;
30
31     /*
32      * The following 2 blocks of code are to compare the first patlen
33      * bytes of buf.  We need 2 checks if patshift is > 0 since we
34      * must check the last (patlen - patshift) bytes, and then the
35      * first (patshift) bytes.
36      */
37
38     nb = patlen - patshift;
39     if (nleft < nb) {
40         return (memcmp(cp, pat + patshift, nleft) ? -1 : 0);
41     } else {
42         if (memcmp(cp, pat + patshift, nb))
43             return -1;
44
45         nleft -= nb;
46         cp += nb;
47     }
48
49     if (patshift > 0) {
50         nb = patshift;
51         if (nleft < nb) {
52             return (memcmp(cp, pat, nleft) ? -1 : 0);
53         } else {
54             if (memcmp(cp, pat, nb))
55                 return -1;
56
57             nleft -= nb;
58             cp += nb;
59         }
60     }
61
62     /*
63      * Now, verify the rest of the buffer using the algorithm described
64      * in the function header.
65      */
66
67     ncmp = cp - buf;
68     while (ncmp < buflen) {
69         nb = (ncmp < nleft) ? ncmp : nleft;
70         if (memcmp(buf, cp, nb))
71             return -1;
72
73         cp += nb;
74         ncmp += nb;
75         nleft -= nb;
76     }
77
78     return 0;
79 }
80
81 int
82 pattern_fill(buf, buflen, pat, patlen, patshift)
83 char    *buf;
84 int     buflen;
85 char    *pat;
86 int     patlen;
87 int     patshift;
88 {
89     int         trans, ncopied, nleft;
90     char        *cp;
91
92     if (patlen)
93         patshift = patshift % patlen;
94
95     cp = buf;
96     nleft = buflen;
97
98     /*
99      * The following 2 blocks of code are to fill the first patlen
100      * bytes of buf.  We need 2 sections if patshift is > 0 since we
101      * must first copy the last (patlen - patshift) bytes into buf[0]...,
102      * and then the first (patshift) bytes of pattern following them.
103      */
104
105     trans = patlen - patshift;
106     if (nleft < trans) {
107         memcpy(cp, pat + patshift, nleft);
108         return 0;
109     } else {
110         memcpy(cp, pat + patshift, trans);
111         nleft -= trans;
112         cp += trans;
113     }
114
115     if (patshift > 0) {
116         trans = patshift;
117         if (nleft < trans) {
118             memcpy(cp, pat, nleft);
119             return 0;
120         } else {
121             memcpy(cp, pat, trans);
122             nleft -= trans;
123             cp += trans;
124         }
125     }
126
127     /*
128      * Now, fill the rest of the buffer using the algorithm described
129      * in the function header comment.
130      */
131
132     ncopied = cp - buf;
133     while (ncopied < buflen) {
134         trans = (ncopied < nleft) ? ncopied : nleft;
135         memcpy(cp, buf, trans);
136         cp += trans;
137         ncopied += trans;
138         nleft -= trans;
139     }
140
141     return(0);
142 }