bool RegularExpression::matchRange(Context* const context, const Op* const op, int& offset, const short direction, const bool ignoreCase) { int tmpOffset = direction > 0 ? offset : offset - 1; if (tmpOffset >= context->fLimit || tmpOffset < 0) return false; XMLInt32 strCh = 0; if (!context->nextCh(strCh, tmpOffset, direction)) return false; RangeToken* tok = (RangeToken *) op->getToken(); bool match = false; if (ignoreCase) { tok = tok->getCaseInsensitiveToken(fTokenFactory); } match = tok->match(strCh); if (!match) return false; offset = (direction > 0) ? ++tmpOffset : tmpOffset; return true; }
bool RegularExpression::matchRange(Context* const context, const Op* const op, int& offset, const short direction, const bool ignoreCase) { int tmpOffset = direction > 0 ? offset : offset - 1; if (tmpOffset >= context->fLimit || tmpOffset < 0) return false; XMLInt32 strCh = 0; if (!context->nextCh(strCh, tmpOffset, direction)) return false; RangeToken* tok = (RangeToken *) op->getToken(); bool match = false; if (ignoreCase) { //REVISIT we should match ignoring case, but for now //we will do a normal match //tok = tok->getCaseInsensitiveToken(); //if (!token->match(strCh)) { // if (strCh > 0x10000) // return -1; // Do case insensitive matching - uppercase match // or lowercase match //} match = tok->match(strCh); } else match = tok->match(strCh); if (!match) return false; offset = (direction > 0) ? ++tmpOffset : tmpOffset; return true; }
bool RegularExpression::matches(const XMLCh* const expression, const int start, const int end, Match* const pMatch , MemoryManager* const manager) { if (fOperations == 0) prepare(); Context context(manager); int strLength = XMLString::stringLen(expression); context.reset(expression, strLength, start, end, fNoClosures); bool adoptMatch = false; Match* lMatch = pMatch; if (lMatch != 0) { lMatch->setNoGroups(fNoGroups); } else if (fHasBackReferences) { lMatch = new (fMemoryManager) Match(fMemoryManager); lMatch->setNoGroups(fNoGroups); adoptMatch = true; } if (context.fAdoptMatch) delete context.fMatch; context.fMatch = lMatch; context.fAdoptMatch = adoptMatch; if (isSet(fOptions, XMLSCHEMA_MODE)) { int matchEnd = match(&context, fOperations, context.fStart, 1); if (matchEnd == context.fLimit) { if (context.fMatch != 0) { context.fMatch->setStartPos(0, context.fStart); context.fMatch->setEndPos(0, matchEnd); } return true; } return false; } /* * If the pattern has only fixed string, use Boyer-Moore */ if (fFixedStringOnly) { int ret = fBMPattern->matches(expression, context.fStart, context.fLimit); if (ret >= 0) { if (context.fMatch != 0) { context.fMatch->setStartPos(0, ret); context.fMatch->setEndPos(0, ret + strLength); } return true; } return false; } /* * If the pattern contains a fixed string, we check with Boyer-Moore * whether the text contains the fixed string or not. If not found * return false */ if (fFixedString != 0) { int ret = fBMPattern->matches(expression, context.fStart, context.fLimit); if (ret < 0) { // No match return false; } } int limit = context.fLimit - fMinLength; int matchStart; int matchEnd = -1; /* * Check whether the expression start with ".*" */ if (fOperations != 0 && fOperations->getOpType() == Op::O_CLOSURE && fOperations->getChild()->getOpType() == Op::O_DOT) { if (isSet(fOptions, SINGLE_LINE)) { matchStart = context.fStart; matchEnd = match(&context, fOperations, matchStart, 1); } else { bool previousIsEOL = true; for (matchStart=context.fStart; matchStart<=limit; matchStart++) { XMLCh ch = expression[matchStart]; if (RegxUtil::isEOLChar(ch)) { previousIsEOL = true; } else { if (previousIsEOL) { if (0 <= (matchEnd = match(&context, fOperations, matchStart, 1))) break; } previousIsEOL = false; } } } } else { /* * Optimization against the first char */ if (fFirstChar != 0) { bool ignoreCase = isSet(fOptions, IGNORE_CASE); RangeToken* range = fFirstChar; if (ignoreCase) range = fFirstChar->getCaseInsensitiveToken(fTokenFactory); for (matchStart=context.fStart; matchStart<=limit; matchStart++) { XMLInt32 ch; if (!context.nextCh(ch, matchStart, 1)) break; if (!range->match(ch)) { if (!ignoreCase) continue; // Perform case insensitive match // REVISIT continue; } if (0 <= (matchEnd = match(&context,fOperations,matchStart,1))) break; } } else { /* * Straightforward matching */ for (matchStart=context.fStart; matchStart<=limit; matchStart++) { if (0 <= (matchEnd = match(&context,fOperations,matchStart,1))) break; } } } if (matchEnd >= 0) { if (context.fMatch != 0) { context.fMatch->setStartPos(0, matchStart); context.fMatch->setEndPos(0, matchEnd); } return true; } return false; }