| 1739 | */ |
| 1740 | |
| 1741 | std::size_t String::FindWord(const char* string, std::intmax_t start, UInt32 flags) const |
| 1742 | { |
| 1743 | if (!string || !string[0] || m_sharedString->size == 0) |
| 1744 | return npos; |
| 1745 | |
| 1746 | if (start < 0) |
| 1747 | start = std::max<std::size_t>(m_sharedString->size + start, 0); |
| 1748 | |
| 1749 | std::size_t pos = static_cast<std::size_t>(start); |
| 1750 | if (pos >= m_sharedString->size) |
| 1751 | return npos; |
| 1752 | |
| 1753 | ///Algo 3.FindWord#3 (Size of the pattern unknown) |
| 1754 | const char* ptr = m_sharedString->string.get(); |
| 1755 | if (flags & HandleUtf8) |
| 1756 | { |
| 1757 | if (utf8::internal::is_trail(*ptr)) |
| 1758 | utf8::unchecked::prior(ptr); // We ensure to have one pointer pointing to the begin of the character |
| 1759 | |
| 1760 | utf8::unchecked::iterator<const char*> it(ptr); |
| 1761 | |
| 1762 | if (flags & CaseInsensitive) |
| 1763 | { |
| 1764 | const char* t = string; // utf8(::unchecked)::next affects the iterator on argument |
| 1765 | UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); |
| 1766 | |
| 1767 | do |
| 1768 | { |
| 1769 | if (*it == c) |
| 1770 | { |
| 1771 | if (it.base() != m_sharedString->string.get()) |
| 1772 | { |
| 1773 | --it; |
| 1774 | if (!Detail::IsSpace(*it++)) |
| 1775 | continue; |
| 1776 | } |
| 1777 | |
| 1778 | utf8::unchecked::iterator<const char*> p(t); |
| 1779 | utf8::unchecked::iterator<const char*> tIt = it; |
| 1780 | ++tIt; |
| 1781 | |
| 1782 | for (;;) |
| 1783 | { |
| 1784 | if (*p == '\0') |
| 1785 | { |
| 1786 | if (*tIt == '\0' || Detail::IsSpace(*it++)) |
| 1787 | return it.base() - m_sharedString->string.get(); |
| 1788 | else |
| 1789 | break; |
| 1790 | } |
| 1791 | |
| 1792 | if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*p)) |
| 1793 | break; |
| 1794 | |
| 1795 | ++p; |
| 1796 | ++tIt; |
| 1797 | } |
| 1798 | } |
no test coverage detected