/* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include namespace android { // static int AStringUtils::Compare(const char *a, const char *b, size_t len, bool ignoreCase) { // this method relies on a trailing '\0' if a or b are shorter than len return ignoreCase ? strncasecmp(a, b, len) : strncmp(a, b, len); } // static bool AStringUtils::MatchesGlob( const char *glob, size_t globLen, const char *str, size_t strLen, bool ignoreCase) { // this method does not assume a trailing '\0' size_t ix = 0, globIx = 0; // pattern must match until first '*' while (globIx < globLen && glob[globIx] != '*') { ++globIx; } if (strLen < globIx || Compare(str, glob, globIx /* len */, ignoreCase)) { return false; } ix = globIx; // process by * separated sections while (globIx < globLen) { ++globIx; size_t start = globIx; while (globIx < globLen && glob[globIx] != '*') { ++globIx; } size_t len = globIx - start; const char *pattern = glob + start; if (globIx == globLen) { // last pattern must match tail if (ix + len > strLen) { return false; } const char *tail = str + strLen - len; return !Compare(tail, pattern, len, ignoreCase); } // progress after first occurrence of pattern while (ix + len <= strLen && Compare(str + ix, pattern, len, ignoreCase)) { ++ix; } if (ix + len > strLen) { return false; } ix += len; // we will loop around as globIx < globLen } // we only get here if there were no * in the pattern return ix == strLen; } } // namespace android