/** * @brief Matches literal OSC address pattern with target OSC address. * * The OSC address pattern is initially assumed to be literal and not to contain * any special characters: '?', ' *', '[]', or '{}'. If a special character is * found then the result of MatchExpression is returned. Matching literal OSC * address patterns is faster than matching OSC address patterns that contain * special characters. * * This is an internal function and cannot be called by the user application. * * @param oscAddressPattern Pointer to first character of OSC address pattern. * @param oscAddress Pointer to first character of target OSC address. * @param isPartial Flag indicating if a partial match is acceptable. * @return true if OSC address pattern and target OSC address match. */ static bool MatchLiteral(const char * oscAddressPattern, const char * oscAddress, const bool isPartial) { while (*oscAddressPattern != '\0') { if (*oscAddress == '\0') { if (isPartial == true) { return true; } else { return MatchExpression(&oscAddressPattern, &oscAddress, isPartial); // handle trailing 'zero character' expressions } return false; // fail: OSC address pattern too short } switch (*oscAddressPattern) { case '?': case '*': case '[': case '{': return MatchExpression(&oscAddressPattern, &oscAddress, isPartial); default: if (*oscAddressPattern != *oscAddress) { return false; // fail: character mismatch } break; } oscAddressPattern++; oscAddress++; } if (*oscAddress != '\0') { return false; // fail: OSC address pattern too long } return true; }
bool FeedFilter::Rule::Match(FeedItemInfo* pFeedItemInfo) { for (RefValues::iterator it = m_RefValues.begin(); it != m_RefValues.end(); it++) { delete *it; } m_RefValues.clear(); if (!MatchExpression(pFeedItemInfo)) { return false; } if (m_bPatCategory) { ExpandRefValues(pFeedItemInfo, &m_szCategory, m_szPatCategory); } if (m_bPatDupeKey) { ExpandRefValues(pFeedItemInfo, &m_szDupeKey, m_szPatDupeKey); } if (m_bPatAddDupeKey) { ExpandRefValues(pFeedItemInfo, &m_szAddDupeKey, m_szPatAddDupeKey); } return true; }
/** * @brief Matches an OSC address pattern expression starting with a star with * the next character(s) in the target OSC address. * * The OSC address pattern must start with a ' *' character. A ' *' character * will be matched to any sequence of zero or more characters in the OSC address * up to the next '/' character or to the end of the OSC address. For example, * the OSC address pattern "/colour/b *" would match the OSC addresses * "/colour/blue", "/colour/black" and "/colour/brown". * * The oscAddressPattern and oscAddress pointers are advanced to the character * proceeding the matched sequence. This function calls MatchCharacter and so * becomes recursive if the expression contains multiple stars. * * This is an internal function and cannot be called by the user application. * * @param oscAddressPattern Pointer to first character of OSC address pattern. * @param oscAddress Pointer to first character of target OSC address. * @param isPartial Flag indicating if a partial match is acceptable. * @return true if OSC address pattern and target OSC address match. */ static bool MatchStar(const char * * const oscAddressPattern, const char * * const oscAddress, const bool isPartial) { // Advance OSC address pattern pointer to character proceeding star(s) while (**oscAddressPattern == '*') { (*oscAddressPattern)++; } // Advance OSC address pattern pointer to end of part if star is last character if ((**oscAddressPattern == '/') || (**oscAddressPattern == '\0')) { while ((**oscAddress != '/') && (**oscAddress != '\0')) { (*oscAddress)++; } return true; } // Attempt to match remainder of expression for each possible star match do { const char * oscAddressPatternCache = *oscAddressPattern; // cache character oscAddress proceeding star // Advance OSC address pattern to next match of character proceeding star while (MatchCharacter(oscAddressPattern, oscAddress, isPartial) == false) { (*oscAddress)++; if ((**oscAddress == '/') || (**oscAddress == '\0')) { if ((isPartial == true) && (**oscAddress == '\0')) { return true; } return false; // fail: OSC address pattern part ended before match } } const char * oscAddressCache = (*oscAddress); // cache character oscAddress proceeding current star match // Attempt to match remainder of expression if (MatchExpression(oscAddressPattern, oscAddress, isPartial) == true) { // potentially recursive return true; } else { *oscAddressPattern = oscAddressPatternCache; *oscAddress = oscAddressCache; } } while (true); }