string.h 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #pragma once
  2. #if __has_include(<unicode/std_string.h>)
  3. #define JVALIDATE_HAS_ICU
  4. #include <unicode/brkiter.h>
  5. #include <unicode/unistr.h>
  6. #endif
  7. namespace jvalidate::detail {
  8. inline size_t length(std::string_view arg) {
  9. #ifdef JVALIDATE_HAS_ICU
  10. icu::UnicodeString ucs = icu::UnicodeString::fromUTF8(icu::StringPiece(arg));
  11. return ucs.countChar32();
  12. #else
  13. return arg.size();
  14. #endif
  15. }
  16. inline std::string regex_escape(std::string_view arg) {
  17. #ifdef JVALIDATE_HAS_ICU
  18. icu::UnicodeString const ucs = icu::UnicodeString::fromUTF8(icu::StringPiece(arg));
  19. if (ucs.countChar32() == arg.size()) {
  20. return std::string(arg);
  21. }
  22. UErrorCode status = U_ZERO_ERROR;
  23. std::unique_ptr<icu::BreakIterator> iter(
  24. icu::BreakIterator::createCharacterInstance(NULL, status));
  25. if (U_FAILURE(status)) {
  26. return std::string(arg);
  27. }
  28. icu::UnicodeString rval;
  29. iter->setText(ucs);
  30. int32_t start = iter->first();
  31. int32_t end = iter->next();
  32. while (end != icu::BreakIterator::DONE) {
  33. if (std::strchr("?*+", ucs.charAt(end))) {
  34. rval.append('(');
  35. rval.append(ucs, start, end - 1);
  36. rval.append(')');
  37. rval.append(ucs.char32At(end));
  38. end = iter->next();
  39. } else {
  40. rval.append(ucs, start, end - 1);
  41. }
  42. start = end;
  43. end = iter->next();
  44. }
  45. std::string out;
  46. return rval.toUTF8String(out);
  47. #else
  48. return std::string(arg);
  49. #endif
  50. }
  51. }