Index: ppapi/shared_impl/private/net_address_private_impl.cc |
diff --git a/ppapi/shared_impl/private/net_address_private_impl.cc b/ppapi/shared_impl/private/net_address_private_impl.cc |
index 61033a74fec5bdc9abca957e6257e68e0f93b673..691dc232fa9e9874452e1f592e56475062dd8384 100644 |
--- a/ppapi/shared_impl/private/net_address_private_impl.cc |
+++ b/ppapi/shared_impl/private/net_address_private_impl.cc |
@@ -88,6 +88,73 @@ PP_Bool AreEqual(const PP_NetAddress_Private* addr1, |
return PP_FALSE; |
} |
+#if defined(OS_WIN) |
+namespace { |
+ |
+std::string ConvertIPv4AddressToString(const sockaddr_in* a, |
+ bool include_port) { |
+ unsigned ip = ntohl(a->sin_addr.s_addr); |
+ unsigned port = ntohs(a->sin_port); |
+ std::string description = base::StringPrintf( |
+ "%u.%u.%u.%u", |
+ (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); |
+ if (include_port) |
+ base::StringAppendF(&description, ":%u", port); |
+ return description; |
+} |
+ |
+std::string ConvertIPv6AddressToString(const sockaddr_in6* a, |
+ bool include_port) { |
+ unsigned port = ntohs(a->sin6_port); |
+ unsigned scope = a->sin6_scope_id; |
yzshen1
2011/11/17 18:17:56
It is also in network-byte-order, isn't it?
|
+ std::string description(include_port ? "[" : ""); |
+ |
+ // Find the first longest run of 0s (of length > 1), to collapse to "::". |
+ int longest_start = 0; |
+ int longest_length = 0; |
+ int curr_start = 0; |
+ int curr_length = 0; |
+ for (int i = 0; i < 8; i++) { |
+ if (ntohs(a->sin6_addr.s6_addr16[i]) != 0) { |
+ curr_length = 0; |
+ continue; |
+ } |
+ if (!curr_length) |
+ curr_start = i; |
+ curr_length++; |
+ if (curr_length > longest_length) { |
+ longest_start = curr_start; |
+ longest_length = curr_length; |
+ } |
+ } |
+ |
+ bool need_sep = false; // Whether the next item needs a ':' to separate. |
+ for (int i = 0; i < 8;) { |
+ if (longest_length > 1 && i == longest_start) { |
+ description.append("::"); |
+ need_sep = false; |
+ i += longest_length; |
+ } else { |
+ unsigned v = ntohs(a->sin6_addr.s6_addr16[i]); |
+ base::StringAppendF(&description, need_sep ? ":%x" : "%x", v); |
+ need_sep = true; |
+ i++; |
+ } |
+ } |
+ |
+ // Nonzero scopes, e.g., 123, are indicated by appending, e.g., "%123". |
+ if (scope != 0) |
+ base::StringAppendF(&description, "%%%u", scope); |
+ |
+ if (include_port) |
+ base::StringAppendF(&description, "]:%u", port); |
+ |
+ return description; |
+} |
+ |
+} // namespace |
+#endif // OS_WIN |
+ |
PP_Var Describe(PP_Module module, |
const struct PP_NetAddress_Private* addr, |
PP_Bool include_port) { |
@@ -101,19 +168,14 @@ PP_Var Describe(PP_Module module, |
switch (GetFamily(*addr)) { |
case AF_INET: { |
const sockaddr_in* a = reinterpret_cast<const sockaddr_in*>(addr->data); |
- unsigned ip = ntohl(a->sin_addr.s_addr); |
- unsigned port = ntohs(a->sin_port); |
- std::string description = base::StringPrintf( |
- "%u.%u.%u.%u", |
- (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); |
- if (include_port) |
- description.append(base::StringPrintf(":%u", port)); |
- return StringVar::StringToPPVar(module, description); |
+ return StringVar::StringToPPVar( |
+ module, ConvertIPv4AddressToString(a, include_port)); |
+ } |
+ case AF_INET6: { |
+ const sockaddr_in6* a = reinterpret_cast<const sockaddr_in6*>(addr->data); |
+ return StringVar::StringToPPVar( |
+ module, ConvertIPv6AddressToString(a, include_port)); |
} |
- case AF_INET6: |
- // TODO(viettrungluu): crbug.com/103969 |
- NOTIMPLEMENTED(); |
- break; |
default: |
NOTREACHED(); |
break; |