VirtualBox

Changeset 73909 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 27, 2018 11:22:26 AM (6 years ago)
Author:
vboxsync
Message:

iprt/string.h: Added percent encoded formatters: %RMpf, %RMpp, %RMpq. bugref:9167

File:
1 edited

Legend:

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

    r73801 r73909  
    6161*********************************************************************************************************************************/
    6262static char g_szHexDigits[17] = "0123456789abcdef";
     63static char g_szHexDigitsUpper[17] = "0123456789ABCDEF";
    6364
    6465
     
    12951296            {
    12961297                char chWhat = (*ppszFormat)[0];
    1297                 bool fAttr  = chWhat == 'a';
    1298                 char chType = (*ppszFormat)[1];
    1299                 AssertMsgBreak(chWhat == 'a' || chWhat == 'e', ("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
    1300                 *ppszFormat += 2;
    1301                 switch (chType)
    1302                 {
    1303                     case 's':
    1304                     {
    1305                         static const char   s_szElemEscape[] = "<>&\"'";
    1306                         static const char   s_szAttrEscape[] = "<>&\"\n\r"; /* more? */
    1307                         const char * const  pszEscape =  fAttr ?             s_szAttrEscape  :             s_szElemEscape;
    1308                         size_t       const  cchEscape = (fAttr ? RT_ELEMENTS(s_szAttrEscape) : RT_ELEMENTS(s_szElemEscape)) - 1;
    1309                         size_t      cchOutput = 0;
    1310                         const char *pszStr    = va_arg(*pArgs, char *);
    1311                         ssize_t     cchStr;
    1312                         ssize_t     offCur;
    1313                         ssize_t     offLast;
    1314 
    1315                         if (!VALID_PTR(pszStr))
    1316                             pszStr = "<NULL>";
    1317                         cchStr = RTStrNLen(pszStr, (unsigned)cchPrecision);
    1318 
    1319                         if (fAttr)
    1320                             cchOutput += pfnOutput(pvArgOutput, "\"", 1);
    1321                         if (!(fFlags & RTSTR_F_LEFT))
     1298                if (chWhat == 'a' || chWhat == 'e')
     1299                {
     1300                    bool fAttr  = chWhat == 'a';
     1301                    char chType = (*ppszFormat)[1];
     1302                    *ppszFormat += 2;
     1303                    switch (chType)
     1304                    {
     1305                        case 's':
     1306                        {
     1307                            static const char   s_szElemEscape[] = "<>&\"'";
     1308                            static const char   s_szAttrEscape[] = "<>&\"\n\r"; /* more? */
     1309                            const char * const  pszEscape =  fAttr ?             s_szAttrEscape  :             s_szElemEscape;
     1310                            size_t       const  cchEscape = (fAttr ? RT_ELEMENTS(s_szAttrEscape) : RT_ELEMENTS(s_szElemEscape)) - 1;
     1311                            size_t      cchOutput = 0;
     1312                            const char *pszStr    = va_arg(*pArgs, char *);
     1313                            ssize_t     cchStr;
     1314                            ssize_t     offCur;
     1315                            ssize_t     offLast;
     1316
     1317                            if (!VALID_PTR(pszStr))
     1318                                pszStr = "<NULL>";
     1319                            cchStr = RTStrNLen(pszStr, (unsigned)cchPrecision);
     1320
     1321                            if (fAttr)
     1322                                cchOutput += pfnOutput(pvArgOutput, "\"", 1);
     1323                            if (!(fFlags & RTSTR_F_LEFT))
     1324                                while (--cchWidth >= cchStr)
     1325                                    cchOutput += pfnOutput(pvArgOutput, " ", 1);
     1326
     1327                            offLast = offCur = 0;
     1328                            while (offCur < cchStr)
     1329                            {
     1330                                if (memchr(pszEscape, pszStr[offCur], cchEscape))
     1331                                {
     1332                                    if (offLast < offCur)
     1333                                        cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
     1334                                    switch (pszStr[offCur])
     1335                                    {
     1336                                        case '<':   cchOutput += pfnOutput(pvArgOutput, "&lt;", 4); break;
     1337                                        case '>':   cchOutput += pfnOutput(pvArgOutput, "&gt;", 4); break;
     1338                                        case '&':   cchOutput += pfnOutput(pvArgOutput, "&amp;", 5); break;
     1339                                        case '\'':  cchOutput += pfnOutput(pvArgOutput, "&apos;", 6); break;
     1340                                        case '"':   cchOutput += pfnOutput(pvArgOutput, "&quot;", 6); break;
     1341                                        case '\n':  cchOutput += pfnOutput(pvArgOutput, "&#xA;", 5); break;
     1342                                        case '\r':  cchOutput += pfnOutput(pvArgOutput, "&#xD;", 5); break;
     1343                                        default:
     1344                                            AssertFailed();
     1345                                    }
     1346                                    offLast = offCur + 1;
     1347                                }
     1348                                offCur++;
     1349                            }
     1350                            if (offLast < offCur)
     1351                                cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
     1352
    13221353                            while (--cchWidth >= cchStr)
    13231354                                cchOutput += pfnOutput(pvArgOutput, " ", 1);
    1324 
    1325                         offLast = offCur = 0;
    1326                         while (offCur < cchStr)
     1355                            if (fAttr)
     1356                                cchOutput += pfnOutput(pvArgOutput, "\"", 1);
     1357                            return cchOutput;
     1358                        }
     1359
     1360                        default:
     1361                            AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
     1362                    }
     1363                }
     1364                else if (chWhat == 'p')
     1365                {
     1366                    /* Percent encoded string (RTC-3986). */
     1367                    char const  chVariant = (*ppszFormat)[1];
     1368                    char const  chAddSafe = chVariant == 'p' ? '/'
     1369                                          : chVariant == 'q' ? '+' /* '+' in queries is problematic, so no escape. */
     1370                                          :                    '~' /* whatever */;
     1371                    size_t      cchOutput = 0;
     1372                    const char *pszStr    = va_arg(*pArgs, char *);
     1373                    ssize_t     cchStr;
     1374                    ssize_t     offCur;
     1375                    ssize_t     offLast;
     1376
     1377                    *ppszFormat += 2;
     1378                    AssertMsgBreak(chVariant == 'p' || chVariant == 'q' || chVariant == 'f',
     1379                                   ("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
     1380
     1381                    if (!VALID_PTR(pszStr))
     1382                        pszStr = "<NULL>";
     1383                    cchStr = RTStrNLen(pszStr, (unsigned)cchPrecision);
     1384
     1385                    if (!(fFlags & RTSTR_F_LEFT))
     1386                        while (--cchWidth >= cchStr)
     1387                            cchOutput += pfnOutput(pvArgOutput, "%20", 3);
     1388
     1389                    offLast = offCur = 0;
     1390                    while (offCur < cchStr)
     1391                    {
     1392                        ch = pszStr[offCur];
     1393                        if (   RT_C_IS_ALPHA(ch)
     1394                            || RT_C_IS_DIGIT(ch)
     1395                            || ch == '-'
     1396                            || ch == '.'
     1397                            || ch == '_'
     1398                            || ch == '~'
     1399                            || ch == chAddSafe)
     1400                            offCur++;
     1401                        else
    13271402                        {
    1328                             if (memchr(pszEscape, pszStr[offCur], cchEscape))
    1329                             {
    1330                                 if (offLast < offCur)
    1331                                     cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
    1332                                 switch (pszStr[offCur])
    1333                                 {
    1334                                     case '<':   cchOutput += pfnOutput(pvArgOutput, "&lt;", 4); break;
    1335                                     case '>':   cchOutput += pfnOutput(pvArgOutput, "&gt;", 4); break;
    1336                                     case '&':   cchOutput += pfnOutput(pvArgOutput, "&amp;", 5); break;
    1337                                     case '\'':  cchOutput += pfnOutput(pvArgOutput, "&apos;", 6); break;
    1338                                     case '"':   cchOutput += pfnOutput(pvArgOutput, "&quot;", 6); break;
    1339                                     case '\n':  cchOutput += pfnOutput(pvArgOutput, "&#xA;", 5); break;
    1340                                     case '\r':  cchOutput += pfnOutput(pvArgOutput, "&#xD;", 5); break;
    1341                                     default:
    1342                                         AssertFailed();
    1343                                 }
    1344                                 offLast = offCur + 1;
     1403                            if (offLast < offCur)
     1404                                cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
     1405                            if (ch != ' ' || chVariant != 'f')
     1406                            {
     1407                                szBuf[0] = '%';
     1408                                szBuf[1] = g_szHexDigitsUpper[((uint8_t)ch >> 4) & 0xf];
     1409                                szBuf[2] = g_szHexDigitsUpper[(uint8_t)ch & 0xf];
     1410                                szBuf[3] = '\0';
     1411                                cchOutput += pfnOutput(pvArgOutput, szBuf, 3);
    13451412                            }
    1346                             offCur++;
     1413                            else
     1414                                cchOutput += pfnOutput(pvArgOutput, "+", 1);
     1415                            offLast = ++offCur;
    13471416                        }
    1348                         if (offLast < offCur)
    1349                             cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
    1350 
    1351                         while (--cchWidth >= cchStr)
    1352                             cchOutput += pfnOutput(pvArgOutput, " ", 1);
    1353                         if (fAttr)
    1354                             cchOutput += pfnOutput(pvArgOutput, "\"", 1);
    1355                         return cchOutput;
    1356                     }
    1357 
    1358                     default:
    1359                         AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
    1360                 }
     1417                    }
     1418                    if (offLast < offCur)
     1419                        cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
     1420
     1421                    while (--cchWidth >= cchStr)
     1422                        cchOutput += pfnOutput(pvArgOutput, "%20", 3);
     1423                }
     1424                else
     1425                    AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
    13611426                break;
    13621427            }
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