| 26 | namespace { |
| 27 | |
| 28 | SegmentsPtr SegmentText(const std::shared_ptr<PrefixMatch>& prefixMatch, |
| 29 | std::string_view text) { |
| 30 | SegmentsPtr segments(new Segments); |
| 31 | if (text.empty()) { |
| 32 | return segments; |
| 33 | } |
| 34 | |
| 35 | const char* segStart = text.data(); |
| 36 | size_t segLength = 0; |
| 37 | auto clearBuffer = [&segments, &segStart, &segLength]() { |
| 38 | if (segLength > 0) { |
| 39 | segments->AddSegment(std::string_view(segStart, segLength)); |
| 40 | segLength = 0; |
| 41 | } |
| 42 | }; |
| 43 | const char* textEnd = text.data() + text.length(); |
| 44 | for (const char* pstr = text.data(); pstr < textEnd;) { |
| 45 | size_t remainingLength = textEnd - pstr; |
| 46 | const PrefixMatchView matched = |
| 47 | prefixMatch->MatchPrefixView(pstr, remainingLength); |
| 48 | size_t matchedLength; |
| 49 | if (!matched.matched) { |
| 50 | matchedLength = |
| 51 | UTF8Util::NextIdeographicDescriptionSequenceLength(pstr, |
| 52 | remainingLength); |
| 53 | if (matchedLength == 0) { |
| 54 | matchedLength = UTF8Util::NextCharLength(pstr); |
| 55 | } |
| 56 | // Ensure we don't advance beyond the string boundary |
| 57 | if (matchedLength > remainingLength) { |
| 58 | matchedLength = remainingLength; |
| 59 | } |
| 60 | segLength += matchedLength; |
| 61 | } else { |
| 62 | clearBuffer(); |
| 63 | matchedLength = matched.keyLength; |
| 64 | segments->AddSegment(matched.key); |
| 65 | segStart = pstr + matchedLength; |
| 66 | } |
| 67 | pstr += matchedLength; |
| 68 | } |
| 69 | clearBuffer(); |
| 70 | return segments; |
| 71 | } |
| 72 | |
| 73 | } // namespace |
| 74 |
no test coverage detected