include/o3tl/string_view.hxx            |   61 +++++++++++++++++++++++++
 starmath/inc/mathml/mathmlattr.hxx      |    6 ++
 starmath/source/mathml/mathmlattr.cxx   |   76 +++++++++++++++-----------------
 starmath/source/mathml/mathmlimport.cxx |    2 
 4 files changed, 103 insertions(+), 42 deletions(-)

New commits:
commit e6fe048ded34a322007547d4d31e32c598aa4993
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Sun Sep 19 15:11:43 2021 +0200
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Sun Sep 19 18:14:15 2021 +0200

    Some more string_view use, add o3tl::starts/ends_with
    
    ...until those C++20 string_view member functions are generally available 
(the
    fallback implementations are taken directly from the C++20 spec).
    
    (In ParseMathMLAttributeLengthValue in 
starmath/source/mathml/mathmlattr.cxx,
    returning nIdx + 2 instead of nIdx + 1 for the single-character u'%' case 
was
    presumably a typo, but which was harmless as the return value was only 
checked
    for <= 0, and has now been turned into a bool.)
    
    Change-Id: Ib441e474c515f016a4d81bb39f7821dfe0356499
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122322
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>

diff --git a/include/o3tl/string_view.hxx b/include/o3tl/string_view.hxx
index 5ebbb0b9f044..b66ba1175a57 100644
--- a/include/o3tl/string_view.hxx
+++ b/include/o3tl/string_view.hxx
@@ -13,6 +13,7 @@
 
 #include <cassert>
 #include <cstddef>
+#include <string>
 #include <string_view>
 
 #include <rtl/ustring.h>
@@ -46,6 +47,66 @@ inline std::string_view getToken(std::string_view sv, char 
delimiter, std::size_
     }
     return t;
 }
+
+// Implementations of C++20 std::basic_string_view::starts_with and
+// std::basic_string_view::ends_with, until we can use those directly on all 
platforms:
+template <typename charT, typename traits = std::char_traits<charT>>
+constexpr bool starts_with(std::basic_string_view<charT, traits> sv,
+                           std::basic_string_view<charT, traits> x) noexcept
+{
+#if defined __cpp_lib_starts_ends_with
+    return sv.starts_with(x);
+#else
+    return sv.substr(0, x.size()) == x;
+#endif
+}
+template <typename charT, typename traits = std::char_traits<charT>>
+constexpr bool starts_with(std::basic_string_view<charT, traits> sv, charT x) 
noexcept
+{
+#if defined __cpp_lib_starts_ends_with
+    return sv.starts_with(x);
+#else
+    return !sv.empty() && traits::eq(sv.front(), x);
+#endif
+}
+template <typename charT, typename traits = std::char_traits<charT>>
+constexpr bool starts_with(std::basic_string_view<charT, traits> sv, charT 
const* x)
+{
+#if defined __cpp_lib_starts_ends_with
+    return sv.starts_with(x);
+#else
+    return starts_with(sv, std::basic_string_view<charT, traits>(x));
+#endif
+}
+template <typename charT, typename traits = std::char_traits<charT>>
+constexpr bool ends_with(std::basic_string_view<charT, traits> sv,
+                         std::basic_string_view<charT, traits> x) noexcept
+{
+#if defined __cpp_lib_ends_ends_with
+    return sv.ends_with(x);
+#else
+    return sv.size() >= x.size()
+           && sv.compare(sv.size() - x.size(), std::basic_string_view<charT, 
traits>::npos, x) == 0;
+#endif
+}
+template <typename charT, typename traits = std::char_traits<charT>>
+constexpr bool ends_with(std::basic_string_view<charT, traits> sv, charT x) 
noexcept
+{
+#if defined __cpp_lib_ends_ends_with
+    return sv.ends_with(x);
+#else
+    return !sv.empty() && traits::eq(sv.back(), x);
+#endif
+}
+template <typename charT, typename traits = std::char_traits<charT>>
+constexpr bool ends_with(std::basic_string_view<charT, traits> sv, charT 
const* x)
+{
+#if defined __cpp_lib_ends_ends_with
+    return sv.ends_with(x);
+#else
+    return ends_with(sv, std::basic_string_view<charT, traits>(x));
+#endif
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/starmath/inc/mathml/mathmlattr.hxx 
b/starmath/inc/mathml/mathmlattr.hxx
index f999f28d680a..16161fb4b8fb 100644
--- a/starmath/inc/mathml/mathmlattr.hxx
+++ b/starmath/inc/mathml/mathmlattr.hxx
@@ -9,6 +9,10 @@
 
 #pragma once
 
+#include <sal/config.h>
+
+#include <string_view>
+
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 #include <tools/fract.hxx>
@@ -44,7 +48,7 @@ struct MathMLAttributeLengthValue
     }
 };
 
-sal_Int32 ParseMathMLAttributeLengthValue(const OUString& rStr, 
MathMLAttributeLengthValue& rV);
+bool ParseMathMLAttributeLengthValue(std::u16string_view rStr, 
MathMLAttributeLengthValue& rV);
 
 // MathML 3: 3.2.2 Mathematics style attributes common to token elements
 // <https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt>
diff --git a/starmath/source/mathml/mathmlattr.cxx 
b/starmath/source/mathml/mathmlattr.cxx
index 7da7f947a8c6..ce28ec7836e9 100644
--- a/starmath/source/mathml/mathmlattr.cxx
+++ b/starmath/source/mathml/mathmlattr.cxx
@@ -10,14 +10,18 @@
 #include <mathmlattr.hxx>
 
 #include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <rtl/math.h>
 
+#include <cstddef>
+#include <string_view>
 #include <unordered_map>
 
-static sal_Int32 ParseMathMLUnsignedNumber(const OUString& rStr, Fraction& rUN)
+static std::size_t ParseMathMLUnsignedNumber(std::u16string_view rStr, 
Fraction& rUN)
 {
-    auto nLen = rStr.getLength();
-    sal_Int32 nDecimalPoint = -1;
-    sal_Int32 nIdx;
+    auto nLen = rStr.length();
+    std::size_t nDecimalPoint = std::u16string_view::npos;
+    std::size_t nIdx;
     sal_Int64 nom = 0;
     sal_Int64 den = 1;
     bool validNomDen = true;
@@ -26,8 +30,8 @@ static sal_Int32 ParseMathMLUnsignedNumber(const OUString& 
rStr, Fraction& rUN)
         auto cD = rStr[nIdx];
         if (cD == u'.')
         {
-            if (nDecimalPoint >= 0)
-                return -1;
+            if (nDecimalPoint != std::u16string_view::npos)
+                return std::u16string_view::npos;
             nDecimalPoint = nIdx;
             continue;
         }
@@ -36,13 +40,14 @@ static sal_Int32 ParseMathMLUnsignedNumber(const OUString& 
rStr, Fraction& rUN)
         if (validNomDen
             && (o3tl::checked_multiply(nom, sal_Int64(10), nom)
                 || o3tl::checked_add(nom, sal_Int64(cD - u'0'), nom)
-                || (nDecimalPoint >= 0 && o3tl::checked_multiply(den, 
sal_Int64(10), den))))
+                || (nDecimalPoint != std::u16string_view::npos
+                    && o3tl::checked_multiply(den, sal_Int64(10), den))))
         {
             validNomDen = false;
         }
     }
     if (nIdx == 0 || (nIdx == 1 && nDecimalPoint == 0))
-        return -1;
+        return std::u16string_view::npos;
 
     // If the input "xx.yyy" can be represented with nom = xx*10^n + yyy and 
den = 10^n in sal_Int64
     // (where n is the length of "yyy"), then use that to create an accurate 
Fraction (and TODO: we
@@ -54,83 +59,74 @@ static sal_Int32 ParseMathMLUnsignedNumber(const OUString& 
rStr, Fraction& rUN)
     }
     else
     {
-        rUN = Fraction(rStr.copy(0, nIdx).toDouble());
+        rUN = Fraction(
+            rtl_math_uStringToDouble(rStr.data(), rStr.data() + nIdx, '.', 0, 
nullptr, nullptr));
     }
 
     return nIdx;
 }
 
-static sal_Int32 ParseMathMLNumber(const OUString& rStr, Fraction& rN)
+static std::size_t ParseMathMLNumber(std::u16string_view rStr, Fraction& rN)
 {
-    if (rStr.isEmpty())
-        return -1;
+    if (rStr.empty())
+        return std::u16string_view::npos;
     bool bNegative = (rStr[0] == '-');
-    sal_Int32 nOffset = bNegative ? 1 : 0;
-    auto nIdx = ParseMathMLUnsignedNumber(rStr.copy(nOffset), rN);
-    if (nIdx <= 0 || !rN.IsValid())
-        return -1;
+    std::size_t nOffset = bNegative ? 1 : 0;
+    auto nIdx = ParseMathMLUnsignedNumber(rStr.substr(nOffset), rN);
+    if (nIdx == std::u16string_view::npos || !rN.IsValid())
+        return std::u16string_view::npos;
     if (bNegative)
         rN *= -1;
     return nOffset + nIdx;
 }
 
-sal_Int32 ParseMathMLAttributeLengthValue(const OUString& rStr, 
MathMLAttributeLengthValue& rV)
+bool ParseMathMLAttributeLengthValue(std::u16string_view rStr, 
MathMLAttributeLengthValue& rV)
 {
     auto nIdx = ParseMathMLNumber(rStr, rV.aNumber);
-    if (nIdx <= 0)
-        return -1;
-    OUString sRest = rStr.copy(nIdx);
-    if (sRest.isEmpty())
+    if (nIdx == std::u16string_view::npos)
+        return false;
+    std::u16string_view sRest = rStr.substr(nIdx);
+    if (sRest.empty())
     {
         rV.eUnit = MathMLLengthUnit::None;
-        return nIdx;
     }
-    if (sRest.startsWith("em"))
+    if (o3tl::starts_with(sRest, u"em"))
     {
         rV.eUnit = MathMLLengthUnit::Em;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("ex"))
+    if (o3tl::starts_with(sRest, u"ex"))
     {
         rV.eUnit = MathMLLengthUnit::Ex;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("px"))
+    if (o3tl::starts_with(sRest, u"px"))
     {
         rV.eUnit = MathMLLengthUnit::Px;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("in"))
+    if (o3tl::starts_with(sRest, u"in"))
     {
         rV.eUnit = MathMLLengthUnit::In;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("cm"))
+    if (o3tl::starts_with(sRest, u"cm"))
     {
         rV.eUnit = MathMLLengthUnit::Cm;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("mm"))
+    if (o3tl::starts_with(sRest, u"mm"))
     {
         rV.eUnit = MathMLLengthUnit::Mm;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("pt"))
+    if (o3tl::starts_with(sRest, u"pt"))
     {
         rV.eUnit = MathMLLengthUnit::Pt;
-        return nIdx + 2;
     }
-    if (sRest.startsWith("pc"))
+    if (o3tl::starts_with(sRest, u"pc"))
     {
         rV.eUnit = MathMLLengthUnit::Pc;
-        return nIdx + 2;
     }
     if (sRest[0] == u'%')
     {
         rV.eUnit = MathMLLengthUnit::Percent;
-        return nIdx + 2;
     }
-    return nIdx;
+    return true;
 }
 
 bool GetMathMLMathvariantValue(const OUString& rStr, MathMLMathvariantValue& 
rV)
diff --git a/starmath/source/mathml/mathmlimport.cxx 
b/starmath/source/mathml/mathmlimport.cxx
index e2db20a6d376..7315c96808ba 100644
--- a/starmath/source/mathml/mathmlimport.cxx
+++ b/starmath/source/mathml/mathmlimport.cxx
@@ -1522,7 +1522,7 @@ void SmXMLSpaceContext_Impl::startFastElement(
         switch (aIter.getToken())
         {
             case XML_WIDTH:
-                if (ParseMathMLAttributeLengthValue(sValue.trim(), aLV) <= 0
+                if (!ParseMathMLAttributeLengthValue(sValue.trim(), aLV)
                     || !lcl_CountBlanks(aLV, &nWide, &nNarrow))
                     SAL_WARN("starmath", "ignore mspace's width: " << sValue);
                 break;

Reply via email to