summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--codemaker/source/cppumaker/cppumaker.cxx13
-rw-r--r--codemaker/source/cppumaker/dumputils.cxx5
-rw-r--r--codemaker/source/cppumaker/dumputils.hxx2
-rw-r--r--codemaker/source/javamaker/javamaker.cxx13
-rw-r--r--include/o3tl/string_view.hxx44
-rw-r--r--o3tl/qa/test-string_view.cxx107
-rw-r--r--sal/osl/all/debugbase.cxx3
7 files changed, 171 insertions, 16 deletions
diff --git a/codemaker/source/cppumaker/cppumaker.cxx b/codemaker/source/cppumaker/cppumaker.cxx
index 384e2b5aa079..b2556655b361 100644
--- a/codemaker/source/cppumaker/cppumaker.cxx
+++ b/codemaker/source/cppumaker/cppumaker.cxx
@@ -32,6 +32,7 @@
#include <sal/main.h>
#include <sal/types.h>
#include <unoidl/unoidl.hxx>
+#include <o3tl/string_view.hxx>
#include "cppuoptions.hxx"
#include "cpputype.hxx"
@@ -57,13 +58,13 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
if (options.isValid("-T")) {
OUString names(b2u(options.getOption("-T")));
for (sal_Int32 i = 0; i != -1;) {
- OUString name(names.getToken(0, ';', i));
- if (!name.isEmpty()) {
+ std::u16string_view name(o3tl::getToken(names, 0, ';', i));
+ if (!name.empty()) {
produce(
- (name == "*"
- ? ""
- : name.endsWith(".*")
- ? name.copy(0, name.getLength() - std::strlen(".*"))
+ OUString(name == u"*"
+ ? u""
+ : o3tl::ends_with(name, u".*")
+ ? name.substr(0, name.size() - std::strlen(".*"))
: name),
typeMgr, generated, options);
}
diff --git a/codemaker/source/cppumaker/dumputils.cxx b/codemaker/source/cppumaker/dumputils.cxx
index 8524b1962ce2..2a3e809e70f3 100644
--- a/codemaker/source/cppumaker/dumputils.cxx
+++ b/codemaker/source/cppumaker/dumputils.cxx
@@ -24,17 +24,18 @@
#include <rtl/ustring.hxx>
#include <sal/types.h>
+#include <o3tl/string_view.hxx>
namespace codemaker::cppumaker {
bool dumpNamespaceOpen(
- FileStream & out, OUString const & entityName, bool fullModuleType)
+ FileStream & out, std::u16string_view entityName, bool fullModuleType)
{
bool bOutput = false;
bool bFirst = true;
for (sal_Int32 i = 0; i >= 0;) {
- OUString id(entityName.getToken(0, '.', i));
+ std::u16string_view id(o3tl::getToken(entityName, 0, '.', i));
if (fullModuleType || i >= 0) {
if (!bFirst) {
out << " ";
diff --git a/codemaker/source/cppumaker/dumputils.hxx b/codemaker/source/cppumaker/dumputils.hxx
index 2fcd708c43fb..24e5bae3bede 100644
--- a/codemaker/source/cppumaker/dumputils.hxx
+++ b/codemaker/source/cppumaker/dumputils.hxx
@@ -30,7 +30,7 @@ class FileStream;
namespace codemaker::cppumaker
{
-bool dumpNamespaceOpen(FileStream& out, rtl::OUString const& entityName, bool fullModuleType);
+bool dumpNamespaceOpen(FileStream& out, std::u16string_view entityName, bool fullModuleType);
bool dumpNamespaceClose(FileStream& out, std::u16string_view entityName, bool fullModuleType);
diff --git a/codemaker/source/javamaker/javamaker.cxx b/codemaker/source/javamaker/javamaker.cxx
index 044292bf6b8f..ee376c8cc484 100644
--- a/codemaker/source/javamaker/javamaker.cxx
+++ b/codemaker/source/javamaker/javamaker.cxx
@@ -32,6 +32,7 @@
#include <sal/main.h>
#include <sal/types.h>
#include <unoidl/unoidl.hxx>
+#include <o3tl/string_view.hxx>
#include "javaoptions.hxx"
#include "javatype.hxx"
@@ -57,13 +58,13 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) {
if (options.isValid("-T")) {
OUString names(b2u(options.getOption("-T")));
for (sal_Int32 i = 0; i != -1;) {
- OUString name(names.getToken(0, ';', i));
- if (!name.isEmpty()) {
+ std::u16string_view name(o3tl::getToken(names, 0, ';', i));
+ if (!name.empty()) {
produce(
- (name == "*"
- ? ""
- : name.endsWith(".*")
- ? name.copy(0, name.getLength() - std::strlen(".*"))
+ OUString(name == u"*"
+ ? u""
+ : o3tl::ends_with(name, u".*")
+ ? name.substr(0, name.size() - std::strlen(".*"))
: name),
typeMgr, generated, options);
}
diff --git a/include/o3tl/string_view.hxx b/include/o3tl/string_view.hxx
index b14258c14d39..d9fc84a0d18b 100644
--- a/include/o3tl/string_view.hxx
+++ b/include/o3tl/string_view.hxx
@@ -59,6 +59,50 @@ inline std::string_view getToken(std::string_view sv, char delimiter, std::size_
return t;
}
+// Similar to OUString::getToken
+inline std::u16string_view getToken(std::u16string_view pStr, sal_Int32 nToken, sal_Unicode cTok,
+ sal_Int32& rnIndex)
+{
+ assert(rnIndex <= static_cast<sal_Int32>(pStr.size()));
+
+ // Return an empty string and set rnIndex to -1 if either nToken or rnIndex is
+ // negative:
+ if (rnIndex >= 0 && nToken >= 0)
+ {
+ const sal_Unicode* pOrgCharStr = pStr.data();
+ const sal_Unicode* pCharStr = pOrgCharStr + rnIndex;
+ sal_Int32 nLen = pStr.size() - rnIndex;
+ sal_Int32 nTokCount = 0;
+ const sal_Unicode* pCharStrStart = pCharStr;
+ while (nLen > 0)
+ {
+ if (*pCharStr == cTok)
+ {
+ nTokCount++;
+
+ if (nTokCount > nToken)
+ break;
+ if (nTokCount == nToken)
+ pCharStrStart = pCharStr + 1;
+ }
+
+ pCharStr++;
+ nLen--;
+ }
+ if (nTokCount >= nToken)
+ {
+ if (nLen > 0)
+ rnIndex = pCharStr - pOrgCharStr + 1;
+ else
+ rnIndex = -1;
+ return std::u16string_view(pCharStrStart, pCharStr - pCharStrStart);
+ }
+ }
+
+ rnIndex = -1;
+ return std::u16string_view();
+}
+
// 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>>
diff --git a/o3tl/qa/test-string_view.cxx b/o3tl/qa/test-string_view.cxx
index 28ea5a2e99b0..80f9bd9e13fd 100644
--- a/o3tl/qa/test-string_view.cxx
+++ b/o3tl/qa/test-string_view.cxx
@@ -15,6 +15,7 @@
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
+#include <o3tl/safeint.hxx>
#include <o3tl/string_view.hxx>
#include <rtl/string.hxx>
#include <rtl/ustring.hxx>
@@ -61,6 +62,7 @@ private:
CPPUNIT_TEST(testEndsWith);
CPPUNIT_TEST(testEndsWithRest);
CPPUNIT_TEST(testEqualsIgnoreAsciiCase);
+ CPPUNIT_TEST(testGetToken);
CPPUNIT_TEST_SUITE_END();
void testStartsWith()
@@ -597,6 +599,111 @@ private:
CPPUNIT_ASSERT_GREATER(0, o3tl::compareToIgnoreAsciiCase(u"zest"sv, u"test"sv));
CPPUNIT_ASSERT_LESS(0, o3tl::compareToIgnoreAsciiCase(u"test"sv, u"test2"sv));
}
+
+ void testGetToken()
+ {
+ {
+ OUString suTokenStr;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ } while (nIndex >= 0);
+ // should not GPF
+ }
+ {
+ OUString suTokenStr("a;b");
+
+ sal_Int32 nIndex = 0;
+
+ std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'a'", std::u16string_view(u"a"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'b'", std::u16string_view(u"b"),
+ suToken);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1),
+ nIndex);
+ }
+ {
+ std::u16string_view suTokenStr(u"a;b.c");
+
+ sal_Int32 nIndex = 0;
+
+ std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'a'", std::u16string_view(u"a"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'b'", std::u16string_view(u"b"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'c'", std::u16string_view(u"c"),
+ suToken);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1),
+ nIndex);
+ }
+ {
+ std::u16string_view suTokenStr(u"a;;b");
+
+ sal_Int32 nIndex = 0;
+
+ std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'a'", std::u16string_view(u"a"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.empty());
+
+ suToken = o3tl::getToken(suTokenStr, 0, ';', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be a 'b'", std::u16string_view(u"b"),
+ suToken);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1),
+ nIndex);
+ }
+ {
+ std::u16string_view suTokenStr(u"longer.then.ever.");
+
+ sal_Int32 nIndex = 0;
+
+ std::u16string_view suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be 'longer'", std::u16string_view(u"longer"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be 'then'", std::u16string_view(u"then"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Token should be 'ever'", std::u16string_view(u"ever"),
+ suToken);
+
+ suToken = o3tl::getToken(suTokenStr, 0, '.', nIndex);
+ CPPUNIT_ASSERT_MESSAGE("Token should be empty", suToken.empty());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("index should be negative", static_cast<sal_Int32>(-1),
+ nIndex);
+ }
+ {
+ std::u16string_view ab(u"ab");
+ sal_Int32 n = 0;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("token should be 'ab'", ab, o3tl::getToken(ab, 0, '-', n));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("n should be -1", static_cast<sal_Int32>(-1), n);
+ CPPUNIT_ASSERT_MESSAGE("token should be empty", o3tl::getToken(ab, 0, '-', n).empty());
+ }
+ {
+ std::u16string_view suTokenStr;
+ auto pTokenStr = suTokenStr.data();
+ sal_uInt64 n64 = reinterpret_cast<sal_uInt64>(pTokenStr) / sizeof(sal_Unicode);
+ // Point either to 0x0, or to some random address -4GiB away from this string
+ sal_Int32 n = n64 > o3tl::make_unsigned(SAL_MAX_INT32) ? -SAL_MAX_INT32
+ : -static_cast<sal_Int32>(n64);
+ o3tl::getToken(suTokenStr, 0, ';', n);
+ // should not GPF with negative index
+ }
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
diff --git a/sal/osl/all/debugbase.cxx b/sal/osl/all/debugbase.cxx
index 208fa3e92a92..59848a883c9d 100644
--- a/sal/osl/all/debugbase.cxx
+++ b/sal/osl/all/debugbase.cxx
@@ -23,6 +23,7 @@
#include <osl/process.h>
#include <osl/diagnose.hxx>
#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
#include <algorithm>
#include <vector>
@@ -42,7 +43,7 @@ struct StaticDebugBaseAddressFilter
sal_Int32 nIndex = 0;
do {
vec.push_back( OUStringToOString(
- str.getToken( 0, ';', nIndex ),
+ o3tl::getToken(str, 0, ';', nIndex ),
RTL_TEXTENCODING_ASCII_US ) );
}
while (nIndex >= 0);