summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/common/string/strformatrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Runtime/common/string/strformatrt.cpp')
-rw-r--r--src/VBox/Runtime/common/string/strformatrt.cpp189
1 files changed, 128 insertions, 61 deletions
diff --git a/src/VBox/Runtime/common/string/strformatrt.cpp b/src/VBox/Runtime/common/string/strformatrt.cpp
index b5d23853..4dd69f17 100644
--- a/src/VBox/Runtime/common/string/strformatrt.cpp
+++ b/src/VBox/Runtime/common/string/strformatrt.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -56,6 +56,121 @@
#include "internal/string.h"
+/**
+ * Helper function to format IPv6 address according to RFC 5952.
+ *
+ * @returns The number of bytes formatted.
+ * @param pfnOutput Pointer to output function.
+ * @param pvArgOutput Argument for the output function.
+ * @param pIpv6Addr IPv6 address
+ */
+static size_t rtstrFormatIPv6(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PCRTNETADDRIPV6 pIpv6Addr)
+{
+ size_t cch = 0; /* result */
+
+ bool fEmbeddedIpv4;
+ size_t cwHexPart;
+ size_t cwZeroRun, cwLongestZeroRun;
+ size_t iZeroStart, iLongestZeroStart;
+ size_t idx;
+
+ Assert(pIpv6Addr != NULL);
+
+ /*
+ * Check for embedded IPv4 address.
+ *
+ * IPv4-compatible - ::11.22.33.44 (obsolete)
+ * IPv4-mapped - ::ffff:11.22.33.44
+ * IPv4-translated - ::ffff:0:11.22.33.44 (RFC 2765)
+ */
+ fEmbeddedIpv4 = false;
+ cwHexPart = RT_ELEMENTS(pIpv6Addr->au16);
+ if (pIpv6Addr->au64[0] == 0
+ && ( (pIpv6Addr->au32[2] == 0
+ && ( pIpv6Addr->au32[3] != 0
+ && pIpv6Addr->au32[3] != RT_H2BE_U32_C(1)))
+ || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0x0000ffff)
+ || pIpv6Addr->au32[2] == RT_H2BE_U32_C(0xffff0000)))
+ {
+ fEmbeddedIpv4 = true;
+ cwHexPart -= 2;
+ }
+
+ cwZeroRun = cwLongestZeroRun = 0;
+ iZeroStart = iLongestZeroStart = -1;
+ for (idx = 0; idx <= cwHexPart; ++idx)
+ {
+ if (idx < cwHexPart && pIpv6Addr->au16[idx] == 0)
+ {
+ if (cwZeroRun == 0)
+ {
+ cwZeroRun = 1;
+ iZeroStart = idx;
+ }
+ else
+ ++cwZeroRun;
+ }
+ else
+ {
+ if (cwZeroRun != 0)
+ {
+ if (cwZeroRun > 1 && cwZeroRun > cwLongestZeroRun)
+ {
+ cwLongestZeroRun = cwZeroRun;
+ iLongestZeroStart = iZeroStart;
+ }
+ cwZeroRun = 0;
+ iZeroStart = -1;
+ }
+ }
+ }
+
+ if (cwLongestZeroRun == 0)
+ {
+ for (idx = 0; idx < cwHexPart; ++idx)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "%s%x",
+ idx == 0 ? "" : ":",
+ RT_BE2H_U16(pIpv6Addr->au16[idx]));
+
+ if (fEmbeddedIpv4)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+ }
+ else
+ {
+ const size_t iLongestZeroEnd = iLongestZeroStart + cwLongestZeroRun;
+
+ if (iLongestZeroStart == 0)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+ else
+ for (idx = 0; idx < iLongestZeroStart; ++idx)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "%x:", RT_BE2H_U16(pIpv6Addr->au16[idx]));
+
+ if (iLongestZeroEnd == cwHexPart)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+ else
+ {
+ for (idx = iLongestZeroEnd; idx < cwHexPart; ++idx)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ ":%x", RT_BE2H_U16(pIpv6Addr->au16[idx]));
+
+ if (fEmbeddedIpv4)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, ":");
+ }
+ }
+
+ if (fEmbeddedIpv4)
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
+ "%u.%u.%u.%u",
+ pIpv6Addr->au8[12],
+ pIpv6Addr->au8[13],
+ pIpv6Addr->au8[14],
+ pIpv6Addr->au8[15]);
+
+ return cch;
+}
+
/**
* Callback to format iprt formatting extentions.
@@ -141,7 +256,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
{ STRMEM("Gx"), sizeof(RTGCUINT), 16, RTSF_INT, 0 },
{ STRMEM("Hi"), sizeof(RTHCINT), 10, RTSF_INT, RTSTR_F_VALSIGNED },
{ STRMEM("Hp"), sizeof(RTHCPHYS), 16, RTSF_INTW, 0 },
- { STRMEM("Hr"), sizeof(RTGCUINTREG), 16, RTSF_INTW, 0 },
+ { STRMEM("Hr"), sizeof(RTHCUINTREG), 16, RTSF_INTW, 0 },
{ STRMEM("Hu"), sizeof(RTHCUINT), 10, RTSF_INT, 0 },
{ STRMEM("Hv"), sizeof(RTHCPTR), 16, RTSF_INTW, 0 },
{ STRMEM("Hx"), sizeof(RTHCUINT), 16, RTSF_INT, 0 },
@@ -394,24 +509,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
case RTSF_IPV6:
{
if (VALID_PTR(u.pIpv6Addr))
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
- "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
- u.pIpv6Addr->au8[0],
- u.pIpv6Addr->au8[1],
- u.pIpv6Addr->au8[2],
- u.pIpv6Addr->au8[3],
- u.pIpv6Addr->au8[4],
- u.pIpv6Addr->au8[5],
- u.pIpv6Addr->au8[6],
- u.pIpv6Addr->au8[7],
- u.pIpv6Addr->au8[8],
- u.pIpv6Addr->au8[9],
- u.pIpv6Addr->au8[10],
- u.pIpv6Addr->au8[11],
- u.pIpv6Addr->au8[12],
- u.pIpv6Addr->au8[13],
- u.pIpv6Addr->au8[14],
- u.pIpv6Addr->au8[15]);
+ return rtstrFormatIPv6(pfnOutput, pvArgOutput, u.pIpv6Addr);
return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
}
@@ -453,42 +551,11 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
case RTNETADDRTYPE_IPV6:
if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
- return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
- "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
- u.pNetAddr->uAddr.IPv6.au8[0],
- u.pNetAddr->uAddr.IPv6.au8[1],
- u.pNetAddr->uAddr.IPv6.au8[2],
- u.pNetAddr->uAddr.IPv6.au8[3],
- u.pNetAddr->uAddr.IPv6.au8[4],
- u.pNetAddr->uAddr.IPv6.au8[5],
- u.pNetAddr->uAddr.IPv6.au8[6],
- u.pNetAddr->uAddr.IPv6.au8[7],
- u.pNetAddr->uAddr.IPv6.au8[8],
- u.pNetAddr->uAddr.IPv6.au8[9],
- u.pNetAddr->uAddr.IPv6.au8[10],
- u.pNetAddr->uAddr.IPv6.au8[11],
- u.pNetAddr->uAddr.IPv6.au8[12],
- u.pNetAddr->uAddr.IPv6.au8[13],
- u.pNetAddr->uAddr.IPv6.au8[14],
- u.pNetAddr->uAddr.IPv6.au8[15]);
+ return rtstrFormatIPv6(pfnOutput, pvArgOutput, &u.pNetAddr->uAddr.IPv6);
+
return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
- "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x %u",
- u.pNetAddr->uAddr.IPv6.au8[0],
- u.pNetAddr->uAddr.IPv6.au8[1],
- u.pNetAddr->uAddr.IPv6.au8[2],
- u.pNetAddr->uAddr.IPv6.au8[3],
- u.pNetAddr->uAddr.IPv6.au8[4],
- u.pNetAddr->uAddr.IPv6.au8[5],
- u.pNetAddr->uAddr.IPv6.au8[6],
- u.pNetAddr->uAddr.IPv6.au8[7],
- u.pNetAddr->uAddr.IPv6.au8[8],
- u.pNetAddr->uAddr.IPv6.au8[9],
- u.pNetAddr->uAddr.IPv6.au8[10],
- u.pNetAddr->uAddr.IPv6.au8[11],
- u.pNetAddr->uAddr.IPv6.au8[12],
- u.pNetAddr->uAddr.IPv6.au8[13],
- u.pNetAddr->uAddr.IPv6.au8[14],
- u.pNetAddr->uAddr.IPv6.au8[15],
+ "[%RTnaipv6]:%u",
+ &u.pNetAddr->uAddr.IPv6,
u.pNetAddr->uPort);
case RTNETADDRTYPE_MAC:
@@ -558,7 +625,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
const char *pszLastSep;
const char *psz = pszLastSep = va_arg(*pArgs, const char *);
if (!VALID_PTR(psz))
- return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
+ return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
while ((ch = *psz) != '\0')
{
@@ -602,7 +669,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
const char *pszStart;
const char *psz = pszStart = va_arg(*pArgs, const char *);
if (!VALID_PTR(psz))
- return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
+ return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
while ((ch = *psz) != '\0' && ch != '(')
{
@@ -664,7 +731,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
while (off < cchPrecision)
{
int i;
- cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s%0*x %04x:", off ? "\n" : "", sizeof(pu8) * 2, (uintptr_t)pu8, off);
+ cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s%0*p %04x:", off ? "\n" : "", sizeof(pu8) * 2, (uintptr_t)pu8, off);
for (i = 0; i < cchWidth && off + i < cchPrecision ; i++)
cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
off + i < cchPrecision ? !(i & 7) && i ? "-%02x" : " %02x" : " ", pu8[i]);
@@ -707,7 +774,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
}
}
else
- return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
+ return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
break;
}
@@ -903,7 +970,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
* If it's a pointer, we'll check if it's valid before going on.
*/
if ((s_aTypes[i].fFlags & RTST_FLAGS_POINTER) && !VALID_PTR(u.pv))
- return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
+ return pfnOutput(pvArgOutput, RT_STR_TUPLE("<null>"));
/*
* Format the output.
@@ -1098,7 +1165,7 @@ DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, co
REG_OUT_BIT(cr4, X86_CR4_SMXE, "SMXE");
REG_OUT_BIT(cr4, X86_CR4_PCIDE, "PCIDE");
REG_OUT_BIT(cr4, X86_CR4_OSXSAVE, "OSXSAVE");
- REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMPE");
+ REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMEP");
REG_OUT_CLOSE(cr4);
}
else