wreadln: optimize character skipping in right_align_bytes()
authorMax Kellermann <max@musicpd.org>
Wed, 12 Sep 2018 17:24:45 +0000 (19:24 +0200)
committerMax Kellermann <max@musicpd.org>
Wed, 12 Sep 2018 17:26:33 +0000 (19:26 +0200)
meson.build
src/util/LocaleString.cxx [new file with mode: 0644]
src/util/LocaleString.hxx [new file with mode: 0644]
src/wreadln.cxx

index 1e01337..f1f1098 100644 (file)
@@ -364,6 +364,7 @@ ncmpc = executable('ncmpc',
   'src/Completion.cxx',
   'src/strfsong.cxx',
   'src/time_format.cxx',
+  'src/util/LocaleString.cxx',
   'src/util/StringStrip.cxx',
   'src/util/StringUTF8.cxx',
   sources,
diff --git a/src/util/LocaleString.cxx b/src/util/LocaleString.cxx
new file mode 100644 (file)
index 0000000..0b5ccdf
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 Max Kellermann <max.kellermann@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "LocaleString.hxx"
+
+#include <cwchar>
+
+#include <string.h>
+
+std::size_t
+CharSizeMB(const char *s, size_t n)
+{
+       auto mb = std::mbstate_t();
+       const std::size_t length = std::mbrlen(s, n, &mb);
+       if (length == std::size_t(-2))
+               return n;
+
+       if (length == std::size_t(-1))
+               return 1;
+
+       return length;
+}
diff --git a/src/util/LocaleString.hxx b/src/util/LocaleString.hxx
new file mode 100644 (file)
index 0000000..ba6ca53
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 Max Kellermann <max.kellermann@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LOCALE_STRING_HXX
+#define LOCALE_STRING_HXX
+
+#include "Compiler.h"
+
+#include <cstddef>
+
+/**
+ * Wrapper for std::mbrlen() which attempts to recover with a best
+ * effort from invalid or incomplete sequences.
+ */
+gcc_pure
+std::size_t
+CharSizeMB(const char *s, size_t n);
+
+#endif
index 399de00..0e32c18 100644 (file)
@@ -23,6 +23,7 @@
 #include "screen_utils.hxx"
 #include "Point.hxx"
 #include "config.h"
+#include "util/LocaleString.hxx"
 #include "util/StringUTF8.hxx"
 
 #include <string>
@@ -152,10 +153,7 @@ right_align_bytes(const char *data, size_t right, unsigned width)
                        break;
                }
 
-               gunichar c = g_utf8_get_char(p);
-               p[g_unichar_to_utf8(c, nullptr)] = 0;
-
-               start += strlen(Utf8ToLocale(p).c_str());
+               start += CharSizeMB(data + start, right - start);
                g_free(p);
        }