Commit 41d11170 authored by Juan Benet's avatar Juan Benet

Merge pull request #16 from whyrusleeping/feat/modular

Feat/modular
parents dd8f16c4 ae64eb99
...@@ -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,19 @@ func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr { ...@@ -113,3 +113,19 @@ 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) {
for _, sub := range Split(m) {
p := sub.Protocols()[0]
if p.Code == code {
if p.Size == 0 {
return "", nil
}
return strings.Split(sub.String(), "/")[2], nil
}
}
return "", ErrProtocolNotFound
}
...@@ -300,3 +300,45 @@ func TestEncapsulate(t *testing.T) { ...@@ -300,3 +300,45 @@ 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)
}
a = newMultiaddr(t, "/ip4/0.0.0.0") // only one addr
assertValueForProto(t, a, P_IP4, "0.0.0.0")
a = newMultiaddr(t, "/ip4/0.0.0.0/ip4/0.0.0.0/ip4/0.0.0.0") // same sub-addr
assertValueForProto(t, a, P_IP4, "0.0.0.0")
a = newMultiaddr(t, "/ip4/0.0.0.0/udp/12345/utp") // ending in a no-value one.
assertValueForProto(t, a, P_IP4, "0.0.0.0")
assertValueForProto(t, a, P_UDP, "12345")
assertValueForProto(t, a, P_UTP, "")
}
...@@ -55,6 +55,20 @@ var Protocols = []Protocol{ ...@@ -55,6 +55,20 @@ var Protocols = []Protocol{
Protocol{P_IPFS, LengthPrefixedVarSize, "ipfs", CodeToVarint(P_IPFS)}, Protocol{P_IPFS, LengthPrefixedVarSize, "ipfs", CodeToVarint(P_IPFS)},
} }
func AddProtocol(p Protocol) error {
for _, pt := range Protocols {
if pt.Code == p.Code {
return fmt.Errorf("protocol code %d already taken by %q", p.Code, pt.Name)
}
if pt.Name == p.Name {
return fmt.Errorf("protocol by the name %q already exists", p.Name)
}
}
Protocols = append(Protocols, p)
return nil
}
// ProtocolWithName returns the Protocol description with given string name. // ProtocolWithName returns the Protocol description with given string name.
func ProtocolWithName(s string) Protocol { func ProtocolWithName(s string) Protocol {
for _, p := range Protocols { for _, p := range Protocols {
......
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