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