From 9d0413216685892ff51a86bb4d22284e6f56812e Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Wed, 5 Nov 2014 02:20:27 -0800 Subject: [PATCH] Split + Join --- interface.go | 6 ------ multiaddr.go | 34 ---------------------------------- multiaddr_test.go | 10 +++++++--- util.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 43 deletions(-) create mode 100644 util.go diff --git a/interface.go b/interface.go index 3ce6d2a..6f57625 100644 --- a/interface.go +++ b/interface.go @@ -39,10 +39,4 @@ type Multiaddr interface { // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80 // Decapsulate(Multiaddr) Multiaddr - - // Split returns the sub-address portions of this multiaddr. - // - // m, _ := NewMultiaddr("/ip4/1.2.3.4/tcp/1234") - // m.Split() -> [/ip4/1.2.3.4, /tcp/1234] - Split() []Multiaddr } diff --git a/multiaddr.go b/multiaddr.go index a316a36..4ee63ca 100644 --- a/multiaddr.go +++ b/multiaddr.go @@ -108,37 +108,3 @@ func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr { } return ma } - -// Split returns the sub-address portions of this multiaddr. -func (m *multiaddr) Split() []Multiaddr { - split, err := bytesSplit(m.bytes) - if err != nil { - panic(fmt.Errorf("invalid multiaddr %s", m.String())) - } - - addrs := make([]Multiaddr, len(split)) - for i, addr := range split { - c := make([]byte, len(addr)) - copy(c, addr) - addrs[i] = &multiaddr{bytes: c} - } - return addrs -} - -// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse. -func Cast(b []byte) Multiaddr { - _, err := bytesToString(b) - if err != nil { - panic(fmt.Errorf("multiaddr failed to parse: %s", err)) - } - return &multiaddr{bytes: b} -} - -// StringCast like Cast, but parses a string. Will also panic if it fails to parse. -func StringCast(s string) Multiaddr { - m, err := NewMultiaddr(s) - if err != nil { - panic(fmt.Errorf("multiaddr failed to parse: %s", err)) - } - return m -} diff --git a/multiaddr_test.go b/multiaddr_test.go index dca43ab..a5cb666 100644 --- a/multiaddr_test.go +++ b/multiaddr_test.go @@ -91,7 +91,7 @@ func TestBytesToString(t *testing.T) { testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2") } -func TestBytesSplit(t *testing.T) { +func TestBytesSplitAndJoin(t *testing.T) { testString := func(s string, res []string) { m, err := NewMultiaddr(s) @@ -99,7 +99,7 @@ func TestBytesSplit(t *testing.T) { t.Error("failed to convert", s) } - split := m.Split() + split := Split(m) if len(split) != len(res) { t.Error("not enough split components", split) return @@ -111,6 +111,11 @@ func TestBytesSplit(t *testing.T) { } } + joined := Join(split...) + if !m.Equal(joined) { + t.Errorf("joined components failed: %s != %s", m, joined) + } + // modifying underlying bytes is fine. m2 := m.(*multiaddr) for i := range m2.bytes { @@ -122,7 +127,6 @@ func TestBytesSplit(t *testing.T) { t.Errorf("split component failed: %s != %s", a, res[i]) } } - } testString("/ip4/1.2.3.4/udp/1234", []string{"/ip4/1.2.3.4", "/udp/1234"}) diff --git a/util.go b/util.go new file mode 100644 index 0000000..d8f8872 --- /dev/null +++ b/util.go @@ -0,0 +1,47 @@ +package multiaddr + +import ( + "bytes" + "fmt" +) + +// Split returns the sub-address portions of a multiaddr. +func Split(m Multiaddr) []Multiaddr { + split, err := bytesSplit(m.Bytes()) + if err != nil { + panic(fmt.Errorf("invalid multiaddr %s", m.String())) + } + + addrs := make([]Multiaddr, len(split)) + for i, addr := range split { + addrs[i] = &multiaddr{bytes: addr} + } + return addrs +} + +// Join returns a combination of addresses. +func Join(ms ...Multiaddr) Multiaddr { + var b bytes.Buffer + for _, m := range ms { + b.Write(m.Bytes()) + } + return &multiaddr{bytes: b.Bytes()} +} + +// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse. +func Cast(b []byte) Multiaddr { + _, err := bytesToString(b) + if err != nil { + panic(fmt.Errorf("multiaddr failed to parse: %s", err)) + } + return &multiaddr{bytes: b} +} + +// StringCast like Cast, but parses a string. Will also panic if it fails to parse. +func StringCast(s string) Multiaddr { + m, err := NewMultiaddr(s) + if err != nil { + panic(fmt.Errorf("multiaddr failed to parse: %s", err)) + } + return m +}