VirtualBox

Changeset 101346 in vbox


Ignore:
Timestamp:
Oct 4, 2023 11:33:39 PM (18 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159347
Message:

IPRT/ministring: More complete set of endsWith[I] and startsWith[I] methods.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/ministring.h

    r101343 r101346  
    12491249
    12501250    /**
    1251      * Returns true if @a this ends with @a that.
    1252      *
    1253      * @param   that    Suffix to test for.
    1254      * @param   cs      Case sensitivity selector.
    1255      * @returns true if match, false if mismatch.
    1256      */
    1257     bool endsWith(const RTCString &that, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
     1251     * Returns true if @a this ends with @a a_rThat (case sensitive compare).
     1252     *
     1253     * @param   a_rThat Suffix to test for.
     1254     * @returns true if match, false if mismatch.
     1255     */
     1256    bool endsWith(const RTCString &a_rThat) const RT_NOEXCEPT;
     1257
     1258    /**
     1259     * Returns true if @a this ends with @a a_rThat, ignoring case when comparing.
     1260     *
     1261     * @param   a_rThat Suffix to test for.
     1262     * @returns true if match, false if mismatch.
     1263     */
     1264    bool endsWithI(const RTCString &a_rThat) const RT_NOEXCEPT;
     1265
     1266    /**
     1267     * Returns true if @a this ends with @a that, selective case compare.
     1268     *
     1269     * @param   a_rThat     Suffix to test for.
     1270     * @param   a_enmCase   Case sensitivity selector.
     1271     * @returns true if match, false if mismatch.
     1272     */
     1273    inline bool endsWith(const RTCString &a_rThat, CaseSensitivity a_enmCase) const RT_NOEXCEPT
     1274    {
     1275        if (a_enmCase == CaseSensitive)
     1276            return endsWith(a_rThat);
     1277        return endsWithI(a_rThat);
     1278    }
    12581279
    12591280    /**
     
    13011322     * @returns true if match, false if mismatch.
    13021323     */
    1303     inline bool endsWith(const char *a_pszSuffix, CaseSensitivity enmCase) const RT_NOEXCEPT
    1304     {
    1305         if (enmCase == CaseSensitive)
     1324    inline bool endsWith(const char *a_pszSuffix, CaseSensitivity a_enmCase) const RT_NOEXCEPT
     1325    {
     1326        if (a_enmCase == CaseSensitive)
    13061327            return endsWith(a_pszSuffix);
    13071328        return endsWithI(a_pszSuffix);
     
    13141335     * @param   a_pszSuffix The suffix to test for.
    13151336     * @param   a_cchSuffix The length of the suffix string.
    1316      * @param   enmCase     Case sensitivity selector.
    1317      * @returns true if match, false if mismatch.
    1318      */
    1319     inline bool endsWith(const char *a_pszSuffix, size_t a_cchSuffix, CaseSensitivity enmCase) const RT_NOEXCEPT
    1320     {
    1321         if (enmCase == CaseSensitive)
     1337     * @param   a_enmCase   Case sensitivity selector.
     1338     * @returns true if match, false if mismatch.
     1339     */
     1340    inline bool endsWith(const char *a_pszSuffix, size_t a_cchSuffix, CaseSensitivity a_enmCase) const RT_NOEXCEPT
     1341    {
     1342        if (a_enmCase == CaseSensitive)
    13221343            return endsWith(a_pszSuffix, a_cchSuffix);
    13231344        return endsWithI(a_pszSuffix, a_cchSuffix);
     
    13251346
    13261347    /**
     1348     * Returns true if @a this begins with @a a_rThat (case sensitive compare).
     1349     *
     1350     * @param   a_rThat    Prefix to test for.
     1351     * @returns true if match, false if mismatch.
     1352     */
     1353    bool startsWith(const RTCString &a_rThat) const RT_NOEXCEPT;
     1354
     1355    /**
     1356     * Returns true if @a this begins with @a a_rThat, ignoring case when comparing.
     1357     *
     1358     * @param   a_rThat    Prefix to test for.
     1359     * @returns true if match, false if mismatch.
     1360     */
     1361    bool startsWithI(const RTCString &a_rThat) const RT_NOEXCEPT;
     1362
     1363    /**
    13271364     * Returns true if @a this begins with @a that.
    1328      * @param   that    Prefix to test for.
    1329      * @param   cs      Case sensitivity selector.
    1330      * @returns true if match, false if mismatch.
    1331      */
    1332     bool startsWith(const RTCString &that, CaseSensitivity cs = CaseSensitive) const RT_NOEXCEPT;
     1365     *
     1366     * @param   a_rThat     Prefix to test for.
     1367     * @param   a_enmCase   Case sensitivity selector.
     1368     * @returns true if match, false if mismatch.
     1369     */
     1370    inline bool startsWith(const RTCString &a_rThat, CaseSensitivity a_enmCase) const RT_NOEXCEPT
     1371    {
     1372        if (a_enmCase == CaseSensitive)
     1373            return endsWith(a_rThat);
     1374        return endsWithI(a_rThat);
     1375    }
     1376
     1377    /**
     1378     * Returns true if @a this begins with @a that.
     1379     *
     1380     * @param   a_pszPrefix The prefix to test for.
     1381     * @returns true if match, false if mismatch.
     1382     */
     1383    bool startsWith(const char *a_pszPrefix) const RT_NOEXCEPT;
     1384
     1385    /**
     1386     * Returns true if @a this begins with @a a_pszPrefix of @a a_cchPrefix length
     1387     * (case sensitive compare).
     1388     *
     1389     * @param   a_pszPrefix The prefix to test for.
     1390     * @param   a_cchPrefix The length of the prefix string.
     1391     * @returns true if match, false if mismatch.
     1392     */
     1393    bool startsWith(const char *a_pszPrefix, size_t a_cchPrefix) const RT_NOEXCEPT;
     1394
     1395    /**
     1396     * Returns true if @a this begins with @a a_pszPrefix, ignoring case when
     1397     * comparing.
     1398     *
     1399     * @param   a_pszPrefix The prefix to test for.
     1400     * @returns true if match, false if mismatch.
     1401     */
     1402    bool startsWithI(const char *a_pszPrefix) const RT_NOEXCEPT;
     1403
     1404    /**
     1405     * Returns true if @a this begins with @a a_pszPrefix of @a a_cchPrefix length,
     1406     * ignoring case when comparing.
     1407     *
     1408     * @param   a_pszPrefix The prefix to test for.
     1409     * @param   a_cchPrefix The length of the prefix string.
     1410     * @returns true if match, false if mismatch.
     1411     */
     1412    bool startsWithI(const char *a_pszPrefix, size_t a_cchPrefix) const RT_NOEXCEPT;
     1413
     1414    /**
     1415     * Returns true if @a this begins with @a a_pszPrefix, selective case version.
     1416     *
     1417     * @param   a_pszPrefix The prefix to test for.
     1418     * @param   enmCase     Case sensitivity selector.
     1419     * @returns true if match, false if mismatch.
     1420     */
     1421    inline bool startsWith(const char *a_pszPrefix, CaseSensitivity a_enmCase) const RT_NOEXCEPT
     1422    {
     1423        if (a_enmCase == CaseSensitive)
     1424            return startsWith(a_pszPrefix);
     1425        return startsWithI(a_pszPrefix);
     1426    }
     1427
     1428    /**
     1429     * Returns true if @a this begins with @a a_pszPrefix of @a a_cchPrefix length,
     1430     * selective case version.
     1431     *
     1432     * @param   a_pszPrefix The prefix to test for.
     1433     * @param   a_cchPrefix The length of the prefix string.
     1434     * @param   a_enmCase   Case sensitivity selector.
     1435     * @returns true if match, false if mismatch.
     1436     */
     1437    inline bool startsWith(const char *a_pszPrefix, size_t a_cchPrefix, CaseSensitivity a_enmCase) const RT_NOEXCEPT
     1438    {
     1439        if (a_enmCase == CaseSensitive)
     1440            return startsWith(a_pszPrefix, a_cchPrefix);
     1441        return startsWithI(a_pszPrefix, a_cchPrefix);
     1442    }
    13331443
    13341444    /**
  • trunk/src/VBox/Runtime/common/string/ministring.cpp

    r101343 r101346  
    10171017}
    10181018
    1019 bool RTCString::endsWith(const RTCString &that, CaseSensitivity cs /*= CaseSensitive*/) const RT_NOEXCEPT
    1020 {
    1021     size_t l1 = length();
    1022     if (l1 == 0)
    1023         return false;
    1024 
    1025     size_t l2 = that.length();
    1026     if (l1 < l2)
    1027         return false;
    1028 
    1029     if (!m_psz) /* Don't crash when running against an empty string. */
    1030         return false;
    1031 
    1032     /** @todo r=bird: See handling of l2 == in startsWith; inconsistent output (if l2 == 0, it matches anything). */
    1033 
    1034     size_t l = l1 - l2;
    1035     if (cs == CaseSensitive)
    1036         return ::RTStrCmp(&m_psz[l], that.m_psz) == 0;
    1037     return ::RTStrICmp(&m_psz[l], that.m_psz) == 0;
     1019bool RTCString::endsWith(const RTCString &a_rThat) const RT_NOEXCEPT
     1020{
     1021    size_t const cchThis = length();
     1022    size_t const cchThat = a_rThat.length();
     1023    if (   cchThat > 0
     1024        && cchThat <= cchThis)
     1025        return ::memcmp(&m_psz[cchThis - cchThat], a_rThat.m_psz, cchThat) == 0;
     1026    return false;
     1027}
     1028
     1029bool RTCString::endsWithI(const RTCString &a_rThat) const RT_NOEXCEPT
     1030{
     1031    size_t const cchThis = length();
     1032    size_t const cchThat = a_rThat.length();
     1033    if (   cchThat > 0
     1034        && cchThat <= cchThis)
     1035        return ::RTStrICmp(&m_psz[cchThis - cchThat], a_rThat.m_psz) == 0;
     1036    return false;
    10381037}
    10391038
     
    10481047bool RTCString::endsWith(const char *a_pszSuffix) const RT_NOEXCEPT
    10491048{
    1050     return endsWith(a_pszSuffix, strlen(a_pszSuffix));
     1049    if (a_pszSuffix)
     1050        return endsWith(a_pszSuffix, strlen(a_pszSuffix));
     1051    return false;
    10511052}
    10521053
     
    10611062bool RTCString::endsWithI(const char *a_pszSuffix) const RT_NOEXCEPT
    10621063{
    1063     return endsWithI(a_pszSuffix, strlen(a_pszSuffix));
    1064 }
    1065 
    1066 bool RTCString::startsWith(const RTCString &that, CaseSensitivity cs /*= CaseSensitive*/) const RT_NOEXCEPT
    1067 {
    1068     size_t l1 = length();
    1069     size_t l2 = that.length();
    1070     if (l1 == 0 || l2 == 0) /** @todo r=bird: this differs from endsWith, and I think other IPRT code. If l2 == 0, it matches anything. */
    1071         return false;
    1072 
    1073     if (l1 < l2)
    1074         return false;
    1075 
    1076     if (cs == CaseSensitive)
    1077         return ::RTStrNCmp(m_psz, that.m_psz, l2) == 0;
    1078     return ::RTStrNICmp(m_psz, that.m_psz, l2) == 0;
     1064    if (a_pszSuffix)
     1065        return endsWithI(a_pszSuffix, strlen(a_pszSuffix));
     1066    return false;
     1067}
     1068
     1069bool RTCString::startsWith(const RTCString &a_rThat) const RT_NOEXCEPT
     1070{
     1071    size_t const cchThis = length();
     1072    size_t const cchThat = a_rThat.length();
     1073    if (   cchThat > 0
     1074        && cchThat <= cchThis)
     1075        return ::memcmp(m_psz, a_rThat.m_psz, cchThat) == 0;
     1076    return false;
     1077}
     1078
     1079bool RTCString::startsWithI(const RTCString &a_rThat) const RT_NOEXCEPT
     1080{
     1081    size_t const cchThis = length();
     1082    size_t const cchThat = a_rThat.length();
     1083    if (   cchThat > 0
     1084        && cchThat <= cchThis)
     1085        return ::RTStrNICmp(m_psz, a_rThat.m_psz, cchThat) == 0;
     1086    return false;
     1087}
     1088
     1089bool RTCString::startsWith(const char *a_pszPrefix, size_t a_cchPrefix) const RT_NOEXCEPT
     1090{
     1091    Assert(RTStrNLen(a_pszPrefix, a_cchPrefix) == a_cchPrefix);
     1092    return a_cchPrefix >  0
     1093        && a_cchPrefix <= length()
     1094        && ::memcmp(m_psz, a_pszPrefix, a_cchPrefix) == 0;
     1095}
     1096
     1097bool RTCString::startsWith(const char *a_pszPrefix) const RT_NOEXCEPT
     1098{
     1099    if (a_pszPrefix)
     1100        return startsWith(a_pszPrefix, strlen(a_pszPrefix));
     1101    return false;
     1102}
     1103
     1104bool RTCString::startsWithI(const char *a_pszPrefix, size_t a_cchPrefix) const RT_NOEXCEPT
     1105{
     1106    Assert(RTStrNLen(a_pszPrefix, a_cchPrefix) == a_cchPrefix);
     1107    return a_cchPrefix >  0
     1108        && a_cchPrefix <= length()
     1109        && ::RTStrNICmp(m_psz, a_pszPrefix, a_cchPrefix) == 0;
     1110}
     1111
     1112bool RTCString::startsWithI(const char *a_pszPrefix) const RT_NOEXCEPT
     1113{
     1114    if (a_pszPrefix)
     1115        return startsWithI(a_pszPrefix, strlen(a_pszPrefix));
     1116    return false;
    10791117}
    10801118
  • trunk/src/VBox/Runtime/testcase/tstIprtMiniString.cpp

    r101343 r101346  
    411411    CHECK(strTest.endsWith("ty"));
    412412    CHECK(strTest.endsWith("y"));
     413    CHECK(!strTest.endsWith("ty00", 3));
     414    CHECK(strTest.endsWith("ty00", 2));
    413415    CHECK(!strTest.endsWith(""));
     416    CHECK(!strTest.endsWith(NULL));
     417    CHECK(!strTest.endsWith(strEmpty));
     418    CHECK(!strEmpty.endsWith(""));
     419    CHECK(!strEmpty.endsWith(NULL));
     420    CHECK(!strEmpty.endsWith(strEmpty));
     421
    414422    CHECK(strTest.endsWithI("qwerty"));
    415     CHECK(strTest.endsWithI("werty"));
    416     CHECK(strTest.endsWithI("erty"));
    417     CHECK(strTest.endsWithI("rty"));
     423    CHECK(strTest.endsWithI("QWERTY"));
     424    CHECK(strTest.endsWithI("wErtY"));
     425    CHECK(strTest.endsWithI("eRty"));
     426    CHECK(strTest.endsWithI("rTy"));
    418427    CHECK(strTest.endsWithI("ty"));
    419428    CHECK(strTest.endsWithI("y"));
     429    CHECK(!strTest.endsWithI("ty000", 3));
     430    CHECK(strTest.endsWithI("ty000", 2));
    420431    CHECK(!strTest.endsWithI(""));
    421     CHECK(!strTest.endsWith(strEmpty));
     432    CHECK(!strTest.endsWithI(NULL));
     433    CHECK(!strTest.endsWithI(strEmpty));
     434    CHECK(!strEmpty.endsWithI(""));
     435    CHECK(!strEmpty.endsWithI(NULL));
     436    CHECK(!strEmpty.endsWithI(strEmpty));
    422437
    423438    /* startsWith */
     
    429444    CHECK(strTest.startsWith("qw"));
    430445    CHECK(strTest.startsWith("q"));
     446    CHECK(strTest.startsWith("q00000", 1));
     447    CHECK(strTest.startsWith("qw0000", 2));
     448    CHECK(!strTest.startsWith("qw0000", 3));
    431449    CHECK(!strTest.startsWith(""));
    432450    CHECK(!strTest.startsWith(strEmpty));
     451    CHECK(!strEmpty.startsWith(strTest));
     452    CHECK(!strEmpty.startsWith(strEmpty));
     453    CHECK(!strEmpty.startsWith(""));
     454    CHECK(!strEmpty.startsWith(NULL));
     455
     456    CHECK(strTest.startsWithI(strTest));
     457    CHECK(strTest.startsWithI("qWeRty"));
     458    CHECK(strTest.startsWithI("qWerT"));
     459    CHECK(strTest.startsWithI("qWeR"));
     460    CHECK(strTest.startsWithI("qwE"));
     461    CHECK(strTest.startsWithI("qW"));
     462    CHECK(strTest.startsWithI("q"));
     463    CHECK(strTest.startsWithI("Q00000", 1));
     464    CHECK(strTest.startsWithI("qW0000", 2));
     465    CHECK(!strTest.startsWithI("qW0000", 3));
     466    CHECK(!strTest.startsWithI(""));
     467    CHECK(!strTest.startsWithI(strEmpty));
     468    CHECK(!strEmpty.startsWithI(strTest));
     469    CHECK(!strEmpty.startsWithI(strEmpty));
     470    CHECK(!strEmpty.startsWithI(""));
     471    CHECK(!strEmpty.startsWithI(NULL));
    433472
    434473#undef CHECK
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette