| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (c) 2000 Silicon Graphics, Inc. |
| * All Rights Reserved. |
| */ |
| #include <string.h> |
| #include "pattern.h" |
| |
| /* |
| * The routines in this module are used to fill/check a data buffer |
| * with/against a known pattern. |
| */ |
| |
| int |
| pattern_check(buf, buflen, pat, patlen, patshift) |
| char *buf; |
| int buflen; |
| char *pat; |
| int patlen; |
| int patshift; |
| { |
| int nb, ncmp, nleft; |
| char *cp; |
| |
| if (patlen) |
| patshift = patshift % patlen; |
| |
| cp = buf; |
| nleft = buflen; |
| |
| /* |
| * The following 2 blocks of code are to compare the first patlen |
| * bytes of buf. We need 2 checks if patshift is > 0 since we |
| * must check the last (patlen - patshift) bytes, and then the |
| * first (patshift) bytes. |
| */ |
| |
| nb = patlen - patshift; |
| if (nleft < nb) { |
| return (memcmp(cp, pat + patshift, nleft) ? -1 : 0); |
| } else { |
| if (memcmp(cp, pat + patshift, nb)) |
| return -1; |
| |
| nleft -= nb; |
| cp += nb; |
| } |
| |
| if (patshift > 0) { |
| nb = patshift; |
| if (nleft < nb) { |
| return (memcmp(cp, pat, nleft) ? -1 : 0); |
| } else { |
| if (memcmp(cp, pat, nb)) |
| return -1; |
| |
| nleft -= nb; |
| cp += nb; |
| } |
| } |
| |
| /* |
| * Now, verify the rest of the buffer using the algorithm described |
| * in the function header. |
| */ |
| |
| ncmp = cp - buf; |
| while (ncmp < buflen) { |
| nb = (ncmp < nleft) ? ncmp : nleft; |
| if (memcmp(buf, cp, nb)) |
| return -1; |
| |
| cp += nb; |
| ncmp += nb; |
| nleft -= nb; |
| } |
| |
| return 0; |
| } |
| |
| int |
| pattern_fill(buf, buflen, pat, patlen, patshift) |
| char *buf; |
| int buflen; |
| char *pat; |
| int patlen; |
| int patshift; |
| { |
| int trans, ncopied, nleft; |
| char *cp; |
| |
| if (patlen) |
| patshift = patshift % patlen; |
| |
| cp = buf; |
| nleft = buflen; |
| |
| /* |
| * The following 2 blocks of code are to fill the first patlen |
| * bytes of buf. We need 2 sections if patshift is > 0 since we |
| * must first copy the last (patlen - patshift) bytes into buf[0]..., |
| * and then the first (patshift) bytes of pattern following them. |
| */ |
| |
| trans = patlen - patshift; |
| if (nleft < trans) { |
| memcpy(cp, pat + patshift, nleft); |
| return 0; |
| } else { |
| memcpy(cp, pat + patshift, trans); |
| nleft -= trans; |
| cp += trans; |
| } |
| |
| if (patshift > 0) { |
| trans = patshift; |
| if (nleft < trans) { |
| memcpy(cp, pat, nleft); |
| return 0; |
| } else { |
| memcpy(cp, pat, trans); |
| nleft -= trans; |
| cp += trans; |
| } |
| } |
| |
| /* |
| * Now, fill the rest of the buffer using the algorithm described |
| * in the function header comment. |
| */ |
| |
| ncopied = cp - buf; |
| while (ncopied < buflen) { |
| trans = (ncopied < nleft) ? ncopied : nleft; |
| memcpy(cp, buf, trans); |
| cp += trans; |
| ncopied += trans; |
| nleft -= trans; |
| } |
| |
| return(0); |
| } |