| 437 | } |
| 438 | |
| 439 | void RegExPredicate::calculateRange() { |
| 440 | max_limit = ""; |
| 441 | min_limit = ""; |
| 442 | // we do not support calculating ranges if 'm' and 'x' are specified |
| 443 | if (options.multiline() || options.extended()) |
| 444 | return; |
| 445 | |
| 446 | // remove the special "^" if exist in regexPattern |
| 447 | const auto pattern = re->pattern(); |
| 448 | // we don't want to calculate any limits if we don't have ^ or \A at the beginning of the pattern |
| 449 | const bool startChevron = (!pattern.empty() && pattern.at(0) == '^'); |
| 450 | const bool startString = (pattern.size() > 1 && (pattern.at(0) == '\\' && pattern.at(1) == 'A')); |
| 451 | if (startChevron || startString) { |
| 452 | auto sValue = pattern.substr(startChevron ? 1 : (startString ? 2 : 0)); |
| 453 | const static std::string sSpecial = ".\\[]()*?+|,${}!="; // define an array with the special chars |
| 454 | for (int ii = 0; ii < sValue.length(); ++ii) { |
| 455 | if (sSpecial.find(sValue[ii]) != std::string::npos) { |
| 456 | // We need to take special care for ? and * cases |
| 457 | const int oneLess = (sValue[ii] == '?' || sValue[ii] == '*') ? 1 : 0; |
| 458 | sValue = sValue.substr(0, ii - oneLess); |
| 459 | break; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | if (sValue.length() > 0) { |
| 464 | max_limit = sValue; |
| 465 | min_limit = sValue; |
| 466 | |
| 467 | if (options.caseless()) { |
| 468 | std::transform(max_limit.begin(), max_limit.end(), max_limit.begin(), ::tolower); |
| 469 | std::transform(min_limit.begin(), min_limit.end(), min_limit.begin(), ::toupper); |
| 470 | } |
| 471 | } |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | void RegExPredicate::setOptions(const std::string& _options) { |
| 476 | // According to http://docs.mongodb.org/manual/reference/operator/query/regex/ |