Extend tcpip.Address.String to ipv6 addresses

PiperOrigin-RevId: 214039349
Change-Id: Ia7d09c5f85eddd1e5634f3c21b0bd60b10be6bd2
This commit is contained in:
Tamir Duberstein
2018-09-21 13:58:31 -07:00
committed by Shentubot
parent d260e808f4
commit 4634cd66ad
2 changed files with 92 additions and 0 deletions
+37
View File
@@ -666,6 +666,43 @@ func (a Address) String() string {
switch len(a) {
case 4:
return fmt.Sprintf("%d.%d.%d.%d", int(a[0]), int(a[1]), int(a[2]), int(a[3]))
case 16:
// Find the longest subsequence of hexadecimal zeros.
start, end := -1, -1
for i := 0; i < len(a); i += 2 {
j := i
for j < len(a) && a[j] == 0 && a[j+1] == 0 {
j += 2
}
if j > i+2 && j-i > end-start {
start, end = i, j
}
}
var b strings.Builder
for i := 0; i < len(a); i += 2 {
if i == start {
b.WriteString("::")
i = end
if end >= len(a) {
break
}
} else if i > 0 {
b.WriteByte(':')
}
v := uint16(a[i+0])<<8 | uint16(a[i+1])
if v == 0 {
b.WriteByte('0')
} else {
const digits = "0123456789abcdef"
for i := uint(3); i < 4; i-- {
if v := v >> (i * 4); v != 0 {
b.WriteByte(digits[v&0xf])
}
}
}
}
return b.String()
default:
return fmt.Sprintf("%x", []byte(a))
}
+55
View File
@@ -15,6 +15,7 @@
package tcpip
import (
"net"
"testing"
)
@@ -138,3 +139,57 @@ func TestRouteMatch(t *testing.T) {
}
}
}
func TestAddressString(t *testing.T) {
for _, want := range []string{
// Taken from stdlib.
"2001:db8::123:12:1",
"2001:db8::1",
"2001:db8:0:1:0:1:0:1",
"2001:db8:1:0:1:0:1:0",
"2001::1:0:0:1",
"2001:db8:0:0:1::",
"2001:db8::1:0:0:1",
"2001:db8::a:b:c:d",
// Leading zeros.
"::1",
// Trailing zeros.
"8::",
// No zeros.
"1:1:1:1:1:1:1:1",
// Longer sequence is after other zeros, but not at the end.
"1:0:0:1::1",
// Longer sequence is at the beginning, shorter sequence is at
// the end.
"::1:1:1:0:0",
// Longer sequence is not at the beginning, shorter sequence is
// at the end.
"1::1:1:0:0",
// Longer sequence is at the beginning, shorter sequence is not
// at the end.
"::1:1:0:0:1",
// Neither sequence is at an end, longer is after shorter.
"1:0:0:1::1",
// Shorter sequence is at the beginning, longer sequence is not
// at the end.
"0:0:1:1::1",
// Shorter sequence is at the beginning, longer sequence is at
// the end.
"0:0:1:1:1::",
// Short sequences at both ends, longer one in the middle.
"0:1:1::1:1:0",
// Short sequences at both ends, longer one in the middle.
"0:1::1:0:0",
// Short sequences at both ends, longer one in the middle.
"0:0:1::1:0",
// Longer sequence surrounded by shorter sequences, but none at
// the end.
"1:0:1::1:0:1",
} {
addr := Address(net.ParseIP(want))
if got := addr.String(); got != want {
t.Errorf("Address(%x).String() = '%s', want = '%s'", addr, got, want)
}
}
}