* Find text in document, supporting both forward and backward * searches (just pass minPos > maxPos to do a backward search) * Has not been tested with backwards DBCS searches yet. */
| 1485 | * Has not been tested with backwards DBCS searches yet. |
| 1486 | */ |
| 1487 | long Document::FindText(int minPos, int maxPos, const char *search, |
| 1488 | bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, |
| 1489 | int *length) { |
| 1490 | if (*length <= 0) |
| 1491 | return minPos; |
| 1492 | if (regExp) { |
| 1493 | if (!regex) |
| 1494 | regex = CreateRegexSearch(&charClass); |
| 1495 | return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length); |
| 1496 | } else { |
| 1497 | |
| 1498 | const bool forward = minPos <= maxPos; |
| 1499 | const int increment = forward ? 1 : -1; |
| 1500 | |
| 1501 | // Range endpoints should not be inside DBCS characters, but just in case, move them. |
| 1502 | const int startPos = MovePositionOutsideChar(minPos, increment, false); |
| 1503 | const int endPos = MovePositionOutsideChar(maxPos, increment, false); |
| 1504 | |
| 1505 | // Compute actual search ranges needed |
| 1506 | const int lengthFind = *length; |
| 1507 | |
| 1508 | //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind); |
| 1509 | const int limitPos = Platform::Maximum(startPos, endPos); |
| 1510 | int pos = startPos; |
| 1511 | if (!forward) { |
| 1512 | // Back all of a character |
| 1513 | pos = NextPosition(pos, increment); |
| 1514 | } |
| 1515 | if (caseSensitive) { |
| 1516 | const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; |
| 1517 | const char charStartSearch = search[0]; |
| 1518 | while (forward ? (pos < endSearch) : (pos >= endSearch)) { |
| 1519 | if (CharAt(pos) == charStartSearch) { |
| 1520 | bool found = (pos + lengthFind) <= limitPos; |
| 1521 | for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) { |
| 1522 | found = CharAt(pos + indexSearch) == search[indexSearch]; |
| 1523 | } |
| 1524 | if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { |
| 1525 | return pos; |
| 1526 | } |
| 1527 | } |
| 1528 | if (!NextCharacter(pos, increment)) |
| 1529 | break; |
| 1530 | } |
| 1531 | } else if (SC_CP_UTF8 == dbcsCodePage) { |
| 1532 | const size_t maxFoldingExpansion = 4; |
| 1533 | std::vector<char> searchThing(lengthFind * UTF8MaxBytes * maxFoldingExpansion + 1); |
| 1534 | const int lenSearch = static_cast<int>( |
| 1535 | pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind)); |
| 1536 | char bytes[UTF8MaxBytes + 1]; |
| 1537 | char folded[UTF8MaxBytes * maxFoldingExpansion + 1]; |
| 1538 | while (forward ? (pos < endPos) : (pos >= endPos)) { |
| 1539 | int widthFirstCharacter = 0; |
| 1540 | int posIndexDocument = pos; |
| 1541 | int indexSearch = 0; |
| 1542 | bool characterMatches = true; |
| 1543 | for (;;) { |
| 1544 | const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(posIndexDocument)); |
nothing calls this directly
no test coverage detected