VirtualBox

Changeset 66731 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
May 1, 2017 11:21:06 PM (8 years ago)
Author:
vboxsync
Message:

iprt/string.h,iprt/utf16.h: Added some big endian UTF-16 related functions/features.

Location:
trunk/src/VBox/Runtime/common/string
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/string/strformatrt.cpp

    r66415 r66731  
    670670
    671671            /*
    672              * Base name printing.
     672             * Base name printing, big endian UTF-16.
    673673             */
    674674            case 'b':
     
    699699                        return pfnOutput(pvArgOutput, pszLastSep, psz - pszLastSep);
    700700                    }
     701
     702                    /* %lRbs */
     703                    case 's':
     704                        if (chArgSize == 'l')
     705                        {
     706                            /* utf-16BE -> utf-8 */
     707                            int         cchStr;
     708                            PCRTUTF16   pwszStr = va_arg(*pArgs, PRTUTF16);
     709
     710                            if (RT_VALID_PTR(pwszStr))
     711                            {
     712                                cchStr = 0;
     713                                while (cchStr < cchPrecision && pwszStr[cchStr] != '\0')
     714                                    cchStr++;
     715                            }
     716                            else
     717                            {
     718                                static RTUTF16  s_wszBigNull[] =
     719                                {
     720                                    RT_H2BE_U16_C((uint16_t)'<'), RT_H2BE_U16_C((uint16_t)'N'), RT_H2BE_U16_C((uint16_t)'U'),
     721                                    RT_H2BE_U16_C((uint16_t)'L'), RT_H2BE_U16_C((uint16_t)'L'), RT_H2BE_U16_C((uint16_t)'>'), '\0'
     722                                };
     723                                pwszStr = s_wszBigNull;
     724                                cchStr  = RT_ELEMENTS(s_wszBigNull) - 1;
     725                            }
     726
     727                            cch = 0;
     728                            if (!(fFlags & RTSTR_F_LEFT))
     729                                while (--cchWidth >= cchStr)
     730                                    cch += pfnOutput(pvArgOutput, " ", 1);
     731                            cchWidth -= cchStr;
     732                            while (cchStr-- > 0)
     733                            {
     734/** @todo \#ifndef IN_RC*/
     735#ifdef IN_RING3
     736                                RTUNICP Cp = 0;
     737                                RTUtf16BigGetCpEx(&pwszStr, &Cp);
     738                                char *pszEnd = RTStrPutCp(szBuf, Cp);
     739                                *pszEnd = '\0';
     740                                cch += pfnOutput(pvArgOutput, szBuf, pszEnd - szBuf);
     741#else
     742                                char ch = (char)(*pwszStr++ >> 8);
     743                                cch += pfnOutput(pvArgOutput, &ch, 1);
     744#endif
     745                            }
     746                            while (--cchWidth >= 0)
     747                                cch += pfnOutput(pvArgOutput, " ", 1);
     748                            return cch;
     749                        }
     750                    /* fall thru */
    701751
    702752                    default:
  • trunk/src/VBox/Runtime/common/string/utf-16-case.cpp

    r62477 r66731  
    3434#include <iprt/uni.h>
    3535#include <iprt/alloc.h>
     36#include <iprt/asm.h>
    3637#include <iprt/assert.h>
    3738#include <iprt/err.h>
     
    104105}
    105106RT_EXPORT_SYMBOL(RTUtf16ICmp);
     107
     108
     109RTDECL(int) RTUtf16BigICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2)
     110{
     111    if (pwsz1 == pwsz2)
     112        return 0;
     113    if (!pwsz1)
     114        return -1;
     115    if (!pwsz2)
     116        return 1;
     117
     118    PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
     119    for (;;)
     120    {
     121        register RTUTF16  wc1 = *pwsz1;
     122        register RTUTF16  wc2 = *pwsz2;
     123        register int     iDiff = wc1 - wc2;
     124        if (iDiff)
     125        {
     126            /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
     127            wc1 = RT_BE2H_U16(wc1);
     128            wc2 = RT_BE2H_U16(wc2);
     129            if (    wc1 < 0xd800
     130                ||  wc2 < 0xd800
     131                ||  wc1 > 0xdfff
     132                ||  wc2 > 0xdfff)
     133            {
     134                /* simple UCS-2 char */
     135                iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
     136                if (iDiff)
     137                    iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
     138            }
     139            else
     140            {
     141                /* a damned pair */
     142                RTUNICP uc1;
     143                RTUNICP uc2;
     144                if (wc1 >= 0xdc00)
     145                {
     146                    if (pwsz1Start == pwsz1)
     147                        return iDiff;
     148                    uc1 = RT_BE2H_U16(pwsz1[-1]);
     149                    if (uc1 < 0xd800 || uc1 >= 0xdc00)
     150                        return iDiff;
     151                    uc1 = 0x10000 + (((uc1                    & 0x3ff) << 10) | (wc1 & 0x3ff));
     152                    uc2 = 0x10000 + (((RT_BE2H_U16(pwsz2[-1]) & 0x3ff) << 10) | (wc2 & 0x3ff));
     153                }
     154                else
     155                {
     156                    RTUTF16 wcTmp = *++pwsz1;
     157                    uc1 = RT_BE2H_U16(wcTmp);
     158                    if (uc1 < 0xdc00 || uc1 >= 0xe000)
     159                        return iDiff;
     160                    uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1                & 0x3ff));
     161                    wcTmp = *++pwsz2;
     162                    uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (RT_BE2H_U16(wcTmp) & 0x3ff));
     163                }
     164                iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
     165                if (iDiff)
     166                    iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
     167            }
     168            if (iDiff)
     169                return iDiff;
     170        }
     171        if (!wc1)
     172            return 0;
     173        pwsz1++;
     174        pwsz2++;
     175    }
     176}
     177RT_EXPORT_SYMBOL(RTUtf16BigICmp);
    106178
    107179
     
    145217
    146218
     219RTDECL(int) RTUtf16NICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2, size_t cwcMax)
     220{
     221    if (pwsz1 == pwsz2)
     222        return 0;
     223    if (!pwsz1)
     224        return -1;
     225    if (!pwsz2)
     226        return 1;
     227
     228    PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
     229    while (cwcMax-- > 0)
     230    {
     231        register RTUTF16  wc1 = *pwsz1;
     232        register RTUTF16  wc2 = *pwsz2;
     233        register int     iDiff = wc1 - wc2;
     234        if (iDiff)
     235        {
     236            /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
     237            if (    wc1 < 0xd800
     238                ||  wc2 < 0xd800
     239                ||  wc1 > 0xdfff
     240                ||  wc2 > 0xdfff)
     241            {
     242                /* simple UCS-2 char */
     243                iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
     244                if (iDiff)
     245                    iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
     246            }
     247            else
     248            {
     249                /* a damned pair */
     250                RTUNICP uc1;
     251                RTUNICP uc2;
     252                if (wc1 >= 0xdc00)
     253                {
     254                    if (pwsz1Start == pwsz1)
     255                        return iDiff;
     256                    uc1 = pwsz1[-1];
     257                    if (uc1 < 0xd800 || uc1 >= 0xdc00)
     258                        return iDiff;
     259                    uc1 = 0x10000 + (((uc1       & 0x3ff) << 10) | (wc1 & 0x3ff));
     260                    uc2 = 0x10000 + (((pwsz2[-1] & 0x3ff) << 10) | (wc2 & 0x3ff));
     261                }
     262                else if (cwcMax-- > 0)
     263                {
     264                    uc1 = *++pwsz1;
     265                    if (uc1 < 0xdc00 || uc1 >= 0xe000)
     266                        return iDiff;
     267                    uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1      & 0x3ff));
     268                    uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (*++pwsz2 & 0x3ff));
     269                }
     270                else
     271                {
     272                    iDiff = wc1 - wc2;
     273                    return iDiff;
     274                }
     275                iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
     276                if (iDiff)
     277                    iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
     278            }
     279            if (iDiff)
     280                return iDiff;
     281        }
     282        if (!wc1)
     283            return 0;
     284        pwsz1++;
     285        pwsz2++;
     286    }
     287    return 0;
     288}
     289RT_EXPORT_SYMBOL(RTUtf16NICmp);
     290
     291
     292RTDECL(int) RTUtf16BigNICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2, size_t cwcMax)
     293{
     294    if (pwsz1 == pwsz2)
     295        return 0;
     296    if (!pwsz1)
     297        return -1;
     298    if (!pwsz2)
     299        return 1;
     300
     301    PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
     302    while (cwcMax-- > 0)
     303    {
     304        register RTUTF16  wc1 = *pwsz1;
     305        register RTUTF16  wc2 = *pwsz2;
     306        register int     iDiff = wc1 - wc2;
     307        if (iDiff)
     308        {
     309            /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
     310            wc1 = RT_BE2H_U16(wc1);
     311            wc2 = RT_BE2H_U16(wc2);
     312            if (    wc1 < 0xd800
     313                ||  wc2 < 0xd800
     314                ||  wc1 > 0xdfff
     315                ||  wc2 > 0xdfff)
     316            {
     317                /* simple UCS-2 char */
     318                iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
     319                if (iDiff)
     320                    iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
     321            }
     322            else
     323            {
     324                /* a damned pair */
     325                RTUNICP uc1;
     326                RTUNICP uc2;
     327                if (wc1 >= 0xdc00)
     328                {
     329                    if (pwsz1Start == pwsz1)
     330                        return iDiff;
     331                    uc1 = RT_BE2H_U16(pwsz1[-1]);
     332                    if (uc1 < 0xd800 || uc1 >= 0xdc00)
     333                        return iDiff;
     334                    uc1 = 0x10000 + (((uc1                    & 0x3ff) << 10) | (wc1 & 0x3ff));
     335                    uc2 = 0x10000 + (((RT_BE2H_U16(pwsz2[-1]) & 0x3ff) << 10) | (wc2 & 0x3ff));
     336                }
     337                else if (cwcMax > 0)
     338                {
     339                    RTUTF16 wcTmp = *++pwsz1;
     340                    uc1 = RT_BE2H_U16(wcTmp);
     341                    if (uc1 < 0xdc00 || uc1 >= 0xe000)
     342                        return iDiff;
     343                    uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1                & 0x3ff));
     344                    wcTmp = *++pwsz2;
     345                    uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (RT_BE2H_U16(wcTmp) & 0x3ff));
     346                }
     347                else
     348                {
     349                    iDiff = wc1 - wc2;
     350                    return iDiff;
     351                }
     352                iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
     353                if (iDiff)
     354                    iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
     355            }
     356            if (iDiff)
     357                return iDiff;
     358        }
     359        if (!wc1)
     360            return 0;
     361        pwsz1++;
     362        pwsz2++;
     363    }
     364    return 0;
     365}
     366RT_EXPORT_SYMBOL(RTUtf16BigNICmp);
     367
     368
    147369RTDECL(PRTUTF16) RTUtf16ToLower(PRTUTF16 pwsz)
    148370{
  • trunk/src/VBox/Runtime/common/string/utf-16.cpp

    r62930 r66731  
    3333
    3434#include <iprt/uni.h>
    35 #include <iprt/alloc.h>
     35#include <iprt/asm.h>
     36#include <iprt/mem.h>
    3637#include <iprt/assert.h>
    3738#include <iprt/err.h>
     
    735736
    736737
     738RTDECL(int) RTUtf16BigGetCpExInternal(PCRTUTF16 *ppwsz, PRTUNICP pCp)
     739{
     740    const RTUTF16 wc = RT_BE2H_U16(**ppwsz);
     741
     742    /* simple */
     743    if (wc < 0xd800 || (wc > 0xdfff && wc < 0xfffe))
     744    {
     745        (*ppwsz)++;
     746        *pCp = wc;
     747        return VINF_SUCCESS;
     748    }
     749
     750    int rc;
     751    if (wc < 0xfffe)
     752    {
     753        /* surrogate pair */
     754        if (wc < 0xdc00)
     755        {
     756            const RTUTF16 wc2 = RT_BE2H_U16((*ppwsz)[1]);
     757            if (wc2 >= 0xdc00 && wc2 <= 0xdfff)
     758            {
     759                RTUNICP uc = 0x10000 + (((wc & 0x3ff) << 10) | (wc2 & 0x3ff));
     760                *pCp = uc;
     761                (*ppwsz) += 2;
     762                return VINF_SUCCESS;
     763            }
     764
     765            RTStrAssertMsgFailed(("wc=%#08x wc2=%#08x - invalid 2nd char in surrogate pair\n", wc, wc2));
     766        }
     767        else
     768            RTStrAssertMsgFailed(("wc=%#08x - invalid surrogate pair order\n", wc));
     769        rc = VERR_INVALID_UTF16_ENCODING;
     770    }
     771    else
     772    {
     773        RTStrAssertMsgFailed(("wc=%#08x - endian indicator\n", wc));
     774        rc = VERR_CODE_POINT_ENDIAN_INDICATOR;
     775    }
     776    *pCp = RTUNICP_INVALID;
     777    (*ppwsz)++;
     778    return rc;
     779}
     780RT_EXPORT_SYMBOL(RTUtf16GetCpExInternal);
     781
     782
    737783RTDECL(PRTUTF16) RTUtf16PutCpInternal(PRTUTF16 pwsz, RTUNICP CodePoint)
    738784{
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