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