Tries to scan for an RLO/LRO/RLE/LRE/PDF and keeps track of script writing direction override depth. @returns ScannerError::NoError in case of successful parsing and directional encodings are paired and error code in case the input's lexical parser state is invalid and this error should be reported to the user.
| 273 | /// and error code in case the input's lexical parser state is invalid and this error should be reported |
| 274 | /// to the user. |
| 275 | static ScannerError validateBiDiMarkup(CharStream& _stream, size_t _startPosition) |
| 276 | { |
| 277 | static std::array<std::pair<std::string_view, int>, 5> constexpr directionalSequences{ |
| 278 | std::pair<std::string_view, int>{"\xE2\x80\xAD", 1}, // U+202D (LRO - Left-to-Right Override) |
| 279 | std::pair<std::string_view, int>{"\xE2\x80\xAE", 1}, // U+202E (RLO - Right-to-Left Override) |
| 280 | std::pair<std::string_view, int>{"\xE2\x80\xAA", 1}, // U+202A (LRE - Left-to-Right Embedding) |
| 281 | std::pair<std::string_view, int>{"\xE2\x80\xAB", 1}, // U+202B (RLE - Right-to-Left Embedding) |
| 282 | std::pair<std::string_view, int>{"\xE2\x80\xAC", -1} // U+202C (PDF - Pop Directional Formatting |
| 283 | }; |
| 284 | |
| 285 | size_t endPosition = _stream.position(); |
| 286 | _stream.setPosition(_startPosition); |
| 287 | |
| 288 | int directionOverrideDepth = 0; |
| 289 | |
| 290 | for (size_t currentPos = _startPosition; currentPos < endPosition; ++currentPos) |
| 291 | { |
| 292 | _stream.setPosition(currentPos); |
| 293 | |
| 294 | for (auto const& [sequence, depthChange]: directionalSequences) |
| 295 | if (_stream.prefixMatch(sequence)) |
| 296 | directionOverrideDepth += depthChange; |
| 297 | |
| 298 | if (directionOverrideDepth < 0) |
| 299 | return ScannerError::DirectionalOverrideUnderflow; |
| 300 | } |
| 301 | |
| 302 | _stream.setPosition(endPosition); |
| 303 | |
| 304 | return directionOverrideDepth > 0 ? ScannerError::DirectionalOverrideMismatch : ScannerError::NoError; |
| 305 | } |
| 306 | |
| 307 | } |
| 308 |
no test coverage detected