You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.0KB

  1. #include <string.hpp>
  2. #include <locale> // for wstring_convert
  3. #include <codecvt> // for codecvt_utf8_utf16
  4. #include <cctype> // for tolower and toupper
  5. #include <algorithm> // for transform
  6. #include <libgen.h> // for dirname and basename
  7. namespace rack {
  8. namespace string {
  9. std::string fromWstring(const std::wstring &s) {
  10. std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
  11. return converter.to_bytes(s);
  12. }
  13. std::wstring toWstring(const std::string &s) {
  14. std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
  15. return converter.from_bytes(s);
  16. }
  17. std::string f(const char *format, ...) {
  18. va_list args;
  19. va_start(args, format);
  20. // Compute size of required buffer
  21. int size = vsnprintf(NULL, 0, format, args);
  22. va_end(args);
  23. if (size < 0)
  24. return "";
  25. // Create buffer
  26. std::string s;
  27. s.resize(size);
  28. va_start(args, format);
  29. vsnprintf(&s[0], size + 1, format, args);
  30. va_end(args);
  31. return s;
  32. }
  33. std::string lowercase(const std::string &s) {
  34. std::string r = s;
  35. std::transform(r.begin(), r.end(), r.begin(), [](unsigned char c) { return std::tolower(c); });
  36. return r;
  37. }
  38. std::string uppercase(const std::string &s) {
  39. std::string r = s;
  40. std::transform(r.begin(), r.end(), r.begin(), [](unsigned char c) { return std::toupper(c); });
  41. return r;
  42. }
  43. std::string trim(const std::string &s) {
  44. const std::string whitespace = " \n\r\t";
  45. size_t first = s.find_first_not_of(whitespace);
  46. if (first == std::string::npos)
  47. return "";
  48. size_t last = s.find_last_not_of(whitespace);
  49. if (last == std::string::npos)
  50. return "";
  51. return s.substr(first, last - first + 1);
  52. }
  53. std::string ellipsize(const std::string &s, size_t len) {
  54. if (s.size() <= len)
  55. return s;
  56. else
  57. return s.substr(0, len - 3) + "...";
  58. }
  59. std::string ellipsizePrefix(const std::string &s, size_t len) {
  60. if (s.size() <= len)
  61. return s;
  62. else
  63. return "..." + s.substr(s.size() - (len - 3));
  64. }
  65. bool startsWith(const std::string &str, const std::string &prefix) {
  66. return str.substr(0, prefix.size()) == prefix;
  67. }
  68. bool endsWith(const std::string &str, const std::string &suffix) {
  69. return str.substr(str.size() - suffix.size(), suffix.size()) == suffix;
  70. }
  71. std::string directory(const std::string &path) {
  72. char *pathDup = strdup(path.c_str());
  73. std::string directory = dirname(pathDup);
  74. free(pathDup);
  75. return directory;
  76. }
  77. std::string filename(const std::string &path) {
  78. char *pathDup = strdup(path.c_str());
  79. std::string filename = basename(pathDup);
  80. free(pathDup);
  81. return filename;
  82. }
  83. std::string filenameBase(const std::string &filename) {
  84. size_t pos = filename.rfind('.');
  85. if (pos == std::string::npos)
  86. return filename;
  87. return std::string(filename, 0, pos);
  88. }
  89. std::string filenameExtension(const std::string &filename) {
  90. size_t pos = filename.rfind('.');
  91. if (pos == std::string::npos)
  92. return "";
  93. return std::string(filename, pos + 1);
  94. }
  95. float fuzzyScore(const std::string &s, const std::string &query) {
  96. size_t pos = s.find(query);
  97. if (pos == std::string::npos)
  98. return 0.f;
  99. return (float) (query.size() + 1) / (s.size() + 1);
  100. }
  101. } // namespace string
  102. } // namespace rack