VirtualBox

Ignore:
Timestamp:
Mar 18, 2015 4:25:19 PM (10 years ago)
Author:
vboxsync
Message:

strformatrt.cpp: Fixed warning unsigned in rtstrformatIPv6 and optimized the code a bit.

File:
1 edited

Legend:

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

    r52331 r54836  
    5656#include "internal/string.h"
    5757
     58/*******************************************************************************
     59*   Global Variables                                                           *
     60*******************************************************************************/
     61static char g_szHexDigits[17] = "0123456789abcdef";
     62
     63
     64/**
     65 * Helper that formats a 16-bit hex word in a IPv6 address.
     66 *
     67 * @returns Length in chars.
     68 * @param   pszDst      The output buffer.  Written from the start.
     69 * @param   uWord       The word to format as hex.
     70 */
     71static size_t rtstrFormatIPv6HexWord(char *pszDst, uint16_t uWord)
     72{
     73    size_t   off;
     74    uint16_t cDigits;
     75
     76    if (uWord & UINT16_C(0xff00))
     77        cDigits = uWord & UINT16_C(0xf000) ? 4 : 3;
     78    else
     79        cDigits = uWord & UINT16_C(0x00f0) ? 2 : 1;
     80
     81    off = 0;
     82    switch (cDigits)
     83    {
     84        case 4: pszDst[off++] = g_szHexDigits[(uWord >> 12) & 0xf];
     85        case 3: pszDst[off++] = g_szHexDigits[(uWord >>  8) & 0xf];
     86        case 2: pszDst[off++] = g_szHexDigits[(uWord >>  4) & 0xf];
     87        case 1: pszDst[off++] = g_szHexDigits[(uWord >>  0) & 0xf];
     88            break;
     89    }
     90    pszDst[off] = '\0';
     91    return off;
     92}
     93
    5894
    5995/**
     
    67103static size_t rtstrFormatIPv6(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PCRTNETADDRIPV6 pIpv6Addr)
    68104{
    69     size_t cch = 0; /* result */
    70 
    71     bool fEmbeddedIpv4;
     105    size_t cch; /* result */
     106    bool   fEmbeddedIpv4;
    72107    size_t cwHexPart;
    73     size_t cwZeroRun, cwLongestZeroRun;
    74     size_t iZeroStart, iLongestZeroStart;
     108    size_t cwLongestZeroRun;
     109    size_t iLongestZeroStart;
    75110    size_t idx;
     111    char   szHexWord[8];
    76112
    77113    Assert(pIpv6Addr != NULL);
     
    86122    fEmbeddedIpv4 = false;
    87123    cwHexPart = RT_ELEMENTS(pIpv6Addr->au16);
    88     if (pIpv6Addr->au64[0] == 0
    89         && (   (pIpv6Addr->au32[2] == 0
    90                 && (   pIpv6Addr->au32[3] != 0
    91                     && pIpv6Addr->au32[3] != RT_H2BE_U32_C(1)))
     124    if (   pIpv6Addr->au64[0] == 0
     125        && (   (   pIpv6Addr->au32[2] == 0
     126                && pIpv6Addr->au32[3] != 0
     127                && pIpv6Addr->au32[3] != RT_H2BE_U32_C(1) )
    92128            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0x0000ffff)
    93             || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0xffff0000)))
     129            || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0xffff0000) ) )
    94130    {
    95131        fEmbeddedIpv4 = true;
     
    97133    }
    98134
    99     cwZeroRun = cwLongestZeroRun = 0;
    100     iZeroStart = iLongestZeroStart = -1;
    101     for (idx = 0; idx <= cwHexPart; ++idx)
    102     {
    103         if (idx < cwHexPart && pIpv6Addr->au16[idx] == 0)
     135    /*
     136     * Find the longest sequences of two or more zero words.
     137     */
     138    cwLongestZeroRun  = 0;
     139    iLongestZeroStart = 0;
     140    for (idx = 0; idx < cwHexPart; idx++)
     141        if (pIpv6Addr->au16[idx] == 0)
    104142        {
    105             if (cwZeroRun == 0)
     143            size_t iZeroStart = idx;
     144            size_t cwZeroRun;
     145            do
     146                idx++;
     147            while (idx < cwHexPart && pIpv6Addr->au16[idx] == 0);
     148            cwZeroRun = idx - iZeroStart;
     149            if (cwZeroRun > 1 && cwZeroRun > cwLongestZeroRun)
    106150            {
    107                 cwZeroRun = 1;
    108                 iZeroStart = idx;
    109             }
    110             else
    111                 ++cwZeroRun;
    112         }
    113         else
    114         {
    115             if (cwZeroRun != 0)
    116             {
    117                 if (cwZeroRun > 1 && cwZeroRun > cwLongestZeroRun)
    118                 {
    119                     cwLongestZeroRun = cwZeroRun;
    120                     iLongestZeroStart = iZeroStart;
    121                 }
    122                 cwZeroRun = 0;
    123                 iZeroStart = -1;
     151                cwLongestZeroRun  = cwZeroRun;
     152                iLongestZeroStart = iZeroStart;
     153                if (cwZeroRun >= cwHexPart - idx)
     154                    break;
    124155            }
    125156        }
    126     }
    127 
     157
     158    /*
     159     * Do the formatting.
     160     */
     161    cch = 0;
    128162    if (cwLongestZeroRun == 0)
    129163    {
    130164        for (idx = 0; idx < cwHexPart; ++idx)
    131             cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    132                                "%s%x",
    133                                idx == 0 ? "" : ":",
    134                                RT_BE2H_U16(pIpv6Addr->au16[idx]));
     165        {
     166            if (idx > 0)
     167                cch += pfnOutput(pvArgOutput, ":", 1);
     168            cch += pfnOutput(pvArgOutput, szHexWord, rtstrFormatIPv6HexWord(szHexWord, RT_BE2H_U16(pIpv6Addr->au16[idx])));
     169        }
    135170
    136171        if (fEmbeddedIpv4)
    137             cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     172            cch += pfnOutput(pvArgOutput, ":", 1);
    138173    }
    139174    else
     
    142177
    143178        if (iLongestZeroStart == 0)
    144             cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     179            cch += pfnOutput(pvArgOutput, ":", 1);
    145180        else
    146181            for (idx = 0; idx < iLongestZeroStart; ++idx)
    147                 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    148                                    "%x:", RT_BE2H_U16(pIpv6Addr->au16[idx]));
     182            {
     183                cch += pfnOutput(pvArgOutput, szHexWord, rtstrFormatIPv6HexWord(szHexWord, RT_BE2H_U16(pIpv6Addr->au16[idx])));
     184                cch += pfnOutput(pvArgOutput, ":", 1);
     185            }
    149186
    150187        if (iLongestZeroEnd == cwHexPart)
    151             cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     188            cch += pfnOutput(pvArgOutput, ":", 1);
    152189        else
    153190        {
    154191            for (idx = iLongestZeroEnd; idx < cwHexPart; ++idx)
    155                 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
    156                                    ":%x", RT_BE2H_U16(pIpv6Addr->au16[idx]));
     192            {
     193                cch += pfnOutput(pvArgOutput, ":", 1);
     194                cch += pfnOutput(pvArgOutput, szHexWord, rtstrFormatIPv6HexWord(szHexWord, RT_BE2H_U16(pIpv6Addr->au16[idx])));
     195            }
    157196
    158197            if (fEmbeddedIpv4)
    159                 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
     198                cch += pfnOutput(pvArgOutput, ":", 1);
    160199        }
    161200    }
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