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 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 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