Commit a581da3f authored by Jeromy's avatar Jeromy

add method to lookup values in a multiaddr

parent b185168c
...@@ -39,4 +39,7 @@ type Multiaddr interface { ...@@ -39,4 +39,7 @@ type Multiaddr interface {
// /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80 // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80
// //
Decapsulate(Multiaddr) Multiaddr Decapsulate(Multiaddr) Multiaddr
// ValueForProtocol returns the value (if any) following the specified protocol
ValueForProtocol(code int) (string, error)
} }
...@@ -113,3 +113,32 @@ func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr { ...@@ -113,3 +113,32 @@ func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr {
} }
return ma return ma
} }
var ErrProtocolNotFound = fmt.Errorf("protocol not found in multiaddr")
func (m *multiaddr) ValueForProtocol(code int) (string, error) {
protos := m.Protocols()
found := -1
index := 2
for i, p := range protos {
if code == p.Code {
if p.Size == 0 {
return "", nil
}
found = i
break
} else {
index += 2
if p.Size == 0 {
index--
}
}
}
if found == -1 {
return "", ErrProtocolNotFound
}
return strings.Split(m.String(), "/")[index], nil
}
...@@ -300,3 +300,34 @@ func TestEncapsulate(t *testing.T) { ...@@ -300,3 +300,34 @@ func TestEncapsulate(t *testing.T) {
t.Error("decapsulate /ip4 failed.", "/", s) t.Error("decapsulate /ip4 failed.", "/", s)
} }
} }
func assertValueForProto(t *testing.T, a Multiaddr, p int, exp string) {
t.Logf("checking for %s in %s", ProtocolWithCode(p).Name, a)
fv, err := a.ValueForProtocol(p)
if err != nil {
t.Fatal(err)
}
if fv != exp {
t.Fatalf("expected %q for %d in %d, but got %q instead", exp, p, a, fv)
}
}
func TestGetValue(t *testing.T) {
a := newMultiaddr(t, "/ip4/127.0.0.1/utp/tcp/5555/udp/1234/utp/ipfs/QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP")
assertValueForProto(t, a, P_IP4, "127.0.0.1")
assertValueForProto(t, a, P_UTP, "")
assertValueForProto(t, a, P_TCP, "5555")
assertValueForProto(t, a, P_UDP, "1234")
assertValueForProto(t, a, P_IPFS, "QmbHVEEepCi7rn7VL7Exxpd2Ci9NNB6ifvqwhsrbRMgQFP")
_, err := a.ValueForProtocol(P_IP6)
switch err {
case ErrProtocolNotFound:
break
case nil:
t.Fatal("expected value lookup to fail")
default:
t.Fatalf("expected ErrProtocolNotFound but got: %s", err)
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment