util/LocaleString: add IsIncompleteCharMB()
[ncmpc-debian.git] / src / util / LocaleString.cxx
index 0b5ccdf..438bc02 100644 (file)
 
 #include <string.h>
 
+bool
+IsIncompleteCharMB(const char *s, size_t n)
+{
+       auto mb = std::mbstate_t();
+       const std::size_t length = std::mbrlen(s, n, &mb);
+       return length == std::size_t(-2);
+}
+
 std::size_t
 CharSizeMB(const char *s, size_t n)
 {
@@ -46,3 +54,52 @@ CharSizeMB(const char *s, size_t n)
 
        return length;
 }
+
+const char *
+PrevCharMB(const char *start, const char *reference)
+{
+       const char *p = reference;
+
+       while (p > start) {
+               --p;
+
+               auto mb = std::mbstate_t();
+               const std::size_t length = std::mbrlen(p, reference - p, &mb);
+               if (length != std::size_t(-1))
+                       break;
+       }
+
+       return p;
+}
+
+size_t
+StringWidthMB(const char *s, size_t length)
+{
+       const char *const end = s + length;
+       auto state = std::mbstate_t();
+
+       size_t width = 0;
+       while (s < end) {
+               wchar_t w;
+               std::size_t n = std::mbrtowc(&w, s, end - s, &state);
+               if (n == std::size_t(-2))
+                       break;
+
+               if (n == std::size_t(-1) || n == 0) {
+                       ++s;
+               } else {
+                       s += n;
+                       int cw = wcwidth(w);
+                       if (cw > 0)
+                               width += cw;
+               }
+       }
+
+       return width;
+}
+
+size_t
+StringWidthMB(const char *s)
+{
+       return StringWidthMB(s, strlen(s));
+}