AStringUtils.cpp revision f296e2b262d2a8f7c570eaed454a28cca99eb976
1d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma/*
2d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * Copyright 2014 The Android Open Source Project
3d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma *
4d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * Licensed under the Apache License, Version 2.0 (the "License");
5d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * you may not use this file except in compliance with the License.
6d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * You may obtain a copy of the License at
7d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma *
8d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma *      http://www.apache.org/licenses/LICENSE-2.0
9d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma *
10d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * Unless required by applicable law or agreed to in writing, software
11d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * distributed under the License is distributed on an "AS IS" BASIS,
12d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * See the License for the specific language governing permissions and
14d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma * limitations under the License.
15d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma */
16d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
17d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma#include <string.h>
18d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma#include <AStringUtils.h>
19d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
20d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Vermanamespace android {
21d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
22d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma// static
23d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Vermaint AStringUtils::Compare(const char *a, const char *b, size_t len, bool ignoreCase) {
24d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    // this method relies on a trailing '\0' if a or b are shorter than len
25d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    return ignoreCase ? strncasecmp(a, b, len) : strncmp(a, b, len);
26d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma}
27d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
28d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma// static
29d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Vermabool AStringUtils::MatchesGlob(
30d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase) {
31d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    // this method does not assume a trailing '\0'
32d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    size_t ix = 0, globIx = 0;
33d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
34d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    // pattern must match until first '*'
35d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    while (globIx < globLen && glob[globIx] != '*') {
36d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        ++globIx;
37d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    }
38d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    if (strLen < globIx || Compare(str, glob, globIx /* len */, ignoreCase)) {
39d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        return false;
40d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    }
41d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    ix = globIx;
42d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
43d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    // process by * separated sections
44d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    while (globIx < globLen) {
45d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        ++globIx;
46d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        size_t start = globIx;
47d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        while (globIx < globLen && glob[globIx] != '*') {
48d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            ++globIx;
49d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        }
50d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        size_t len = globIx - start;
51d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        const char *pattern = glob + start;
52d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
53d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        if (globIx == globLen) {
54d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            // last pattern must match tail
55d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            if (ix + len > strLen) {
56d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma                return false;
57d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            }
58d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            const char *tail = str + strLen - len;
59d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            return !Compare(tail, pattern, len, ignoreCase);
60d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        }
61d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        // progress after first occurrence of pattern
62d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        while (ix + len <= strLen && Compare(str + ix, pattern, len, ignoreCase)) {
63d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            ++ix;
64d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        }
65d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        if (ix + len > strLen) {
66d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma            return false;
67d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        }
68d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        ix += len;
69d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma        // we will loop around as globIx < globLen
70d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    }
71d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
72d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    // we only get here if there were no * in the pattern
73d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma    return ix == strLen;
74d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma}
75d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
76d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma}  // namespace android
77d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma
78d6c98ae63824854ea2175b362a10985cac7cfb32Jyotsna Verma