Changeset 54836 in vbox for trunk/src/VBox/Runtime/common/string/strformatrt.cpp
- Timestamp:
- Mar 18, 2015 4:25:19 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/strformatrt.cpp
r52331 r54836 56 56 #include "internal/string.h" 57 57 58 /******************************************************************************* 59 * Global Variables * 60 *******************************************************************************/ 61 static 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 */ 71 static 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 58 94 59 95 /** … … 67 103 static size_t rtstrFormatIPv6(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PCRTNETADDRIPV6 pIpv6Addr) 68 104 { 69 size_t cch = 0; /* result */ 70 71 bool fEmbeddedIpv4; 105 size_t cch; /* result */ 106 bool fEmbeddedIpv4; 72 107 size_t cwHexPart; 73 size_t cw ZeroRun, cwLongestZeroRun;74 size_t i ZeroStart, iLongestZeroStart;108 size_t cwLongestZeroRun; 109 size_t iLongestZeroStart; 75 110 size_t idx; 111 char szHexWord[8]; 76 112 77 113 Assert(pIpv6Addr != NULL); … … 86 122 fEmbeddedIpv4 = false; 87 123 cwHexPart = RT_ELEMENTS(pIpv6Addr->au16); 88 if ( pIpv6Addr->au64[0] == 089 && ( ( pIpv6Addr->au32[2] == 090 && (pIpv6Addr->au32[3] != 091 && 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) ) 92 128 || 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) ) ) 94 130 { 95 131 fEmbeddedIpv4 = true; … … 97 133 } 98 134 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) 104 142 { 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) 106 150 { 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; 124 155 } 125 156 } 126 } 127 157 158 /* 159 * Do the formatting. 160 */ 161 cch = 0; 128 162 if (cwLongestZeroRun == 0) 129 163 { 130 164 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 } 135 170 136 171 if (fEmbeddedIpv4) 137 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");172 cch += pfnOutput(pvArgOutput, ":", 1); 138 173 } 139 174 else … … 142 177 143 178 if (iLongestZeroStart == 0) 144 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");179 cch += pfnOutput(pvArgOutput, ":", 1); 145 180 else 146 181 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 } 149 186 150 187 if (iLongestZeroEnd == cwHexPart) 151 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");188 cch += pfnOutput(pvArgOutput, ":", 1); 152 189 else 153 190 { 154 191 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 } 157 196 158 197 if (fEmbeddedIpv4) 159 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");198 cch += pfnOutput(pvArgOutput, ":", 1); 160 199 } 161 200 }
Note:
See TracChangeset
for help on using the changeset viewer.