VirtualBox

Changeset 95336 in vbox


Ignore:
Timestamp:
Jun 21, 2022 8:48:58 PM (2 years ago)
Author:
vboxsync
Message:

IPRT/RTCString: Added a truncate() method that takes UTF-8 encoding into account when truncating the string. bugref:10185

Location:
trunk
Files:
3 edited

Legend:

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

    r93115 r95336  
    853853
    854854    /**
     855     * Truncates the string to a max length of @a cchMax.
     856     *
     857     * If the string is shorter than @a cchMax characters, no change is made.
     858     *
     859     * If the @a cchMax is not at the start of a UTF-8 sequence, it will be adjusted
     860     * down to the start of the UTF-8 sequence.  Thus, after a truncation, the
     861     * length() may be smaller than @a cchMax.
     862     *
     863     */
     864    RTCString &truncate(size_t cchMax) RT_NOEXCEPT;
     865
     866    /**
    855867     * Index operator.
    856868     *
  • trunk/src/VBox/Runtime/common/string/ministring.cpp

    r93115 r95336  
    774774
    775775
     776RTCString &RTCString::truncate(size_t cchMax) RT_NOEXCEPT
     777{
     778    if (cchMax < m_cch)
     779    {
     780        /*
     781         * Make sure the truncated string ends with a correctly encoded
     782         * codepoint and is not missing a few bytes.
     783         */
     784        if (cchMax > 0)
     785        {
     786            char chTail = m_psz[cchMax];
     787            if (   (chTail & 0x80) == 0         /* single byte codepoint */
     788                || (chTail & 0xc0) == 0xc0)     /* first byte of codepoint sequence. */
     789            { /* likely */ }
     790            else
     791            {
     792                /* We need to find the start of the codepoint sequence: */
     793                do
     794                    cchMax -= 1;
     795                while (   cchMax > 0
     796                       && (m_psz[cchMax] & 0xc0) != 0xc0);
     797            }
     798        }
     799
     800        /*
     801         * Do the truncating.
     802         */
     803        m_psz[cchMax] = '\0';
     804        m_cch = cchMax;
     805    }
     806    return *this;
     807}
     808
     809
    776810size_t RTCString::find(const char *pszNeedle, size_t offStart /*= 0*/) const RT_NOEXCEPT
    777811{
  • trunk/src/VBox/Runtime/testcase/tstIprtMiniString.cpp

    r93115 r95336  
    361361        RTTESTI_CHECK(StrAssign.length() == 0);
    362362    }
     363
     364    /* truncation */
     365    RTCString StrTruncate1("abcdef");
     366    RTTESTI_CHECK(StrTruncate1.length() == 6);
     367    for (int i = 5; i >= 0; i--)
     368    {
     369        StrTruncate1.truncate(i);
     370        RTTESTI_CHECK(StrTruncate1.length() == (size_t)i);
     371    }
     372
     373    RTCString StrTruncate2("01ßä6");
     374    CHECK_EQUAL(StrTruncate2, "01ßä6");
     375    StrTruncate2.truncate(6);
     376    CHECK_EQUAL(StrTruncate2, "01ßä");
     377    StrTruncate2.truncate(5);
     378    CHECK_EQUAL(StrTruncate2, "01ß");
     379    StrTruncate2.truncate(10);
     380    CHECK_EQUAL(StrTruncate2, "01ß");
     381    StrTruncate2.truncate(4);
     382    CHECK_EQUAL(StrTruncate2, "01ß");
     383    StrTruncate2.truncate(3);
     384    CHECK_EQUAL(StrTruncate2, "01");
     385    StrTruncate2.truncate(1);
     386    CHECK_EQUAL(StrTruncate2, "0");
     387    StrTruncate2.truncate(0);
     388    CHECK_EQUAL(StrTruncate2, "");
    363389
    364390#undef CHECK
Note: See TracChangeset for help on using the changeset viewer.

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