add more methods to the protocol.ConnectionID

This will make it easier to change the underlying type of the connection
ID (potentially an array is faster than a byte slice).
This commit is contained in:
Marten Seemann
2018-04-19 08:47:43 +09:00
parent 74ccd194f7
commit d47124d14d
8 changed files with 124 additions and 47 deletions

View File

@@ -3,6 +3,8 @@ package protocol
import (
"bytes"
"crypto/rand"
"fmt"
"io"
)
// A ConnectionID in QUIC
@@ -17,7 +19,38 @@ func GenerateConnectionID() (ConnectionID, error) {
return ConnectionID(b), nil
}
// ReadConnectionID reads a connection ID of length len from the given io.Reader.
// It returns io.EOF if there are not enough bytes to read.
func ReadConnectionID(r io.Reader, len int) (ConnectionID, error) {
if len == 0 {
return nil, nil
}
c := make(ConnectionID, len)
_, err := io.ReadFull(r, c)
if err == io.ErrUnexpectedEOF {
return nil, io.EOF
}
return c, err
}
// Equal says if two connection IDs are equal
func (c ConnectionID) Equal(other ConnectionID) bool {
return bytes.Equal(c, other)
}
// Len returns the length of the connection ID in bytes
func (c ConnectionID) Len() int {
return len(c)
}
// Bytes returns the byte representation
func (c ConnectionID) Bytes() []byte {
return []byte(c)
}
func (c ConnectionID) String() string {
if c.Len() == 0 {
return "(empty)"
}
return fmt.Sprintf("%#x", c.Bytes())
}

View File

@@ -1,6 +1,9 @@
package protocol
import (
"bytes"
"io"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -23,4 +26,59 @@ var _ = Describe("Connection ID generation", func() {
Expect(c1.Equal(c2)).To(BeFalse())
Expect(c2.Equal(c1)).To(BeFalse())
})
It("reads the connection ID", func() {
buf := bytes.NewBuffer([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9})
c, err := ReadConnectionID(buf, 9)
Expect(err).ToNot(HaveOccurred())
Expect(c.Bytes()).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9}))
})
It("returns io.EOF if there's not enough data to read", func() {
buf := bytes.NewBuffer([]byte{1, 2, 3, 4})
_, err := ReadConnectionID(buf, 5)
Expect(err).To(MatchError(io.EOF))
})
It("returns nil for a 0 length connection ID", func() {
buf := bytes.NewBuffer([]byte{1, 2, 3, 4})
c, err := ReadConnectionID(buf, 0)
Expect(err).ToNot(HaveOccurred())
Expect(c).To(BeNil())
})
It("returns the length", func() {
c := ConnectionID{1, 2, 3, 4, 5, 6, 7}
Expect(c.Len()).To(Equal(7))
})
It("has 0 length for the default value", func() {
var c ConnectionID
Expect(c.Len()).To(BeZero())
})
It("returns the bytes", func() {
c := ConnectionID([]byte{1, 2, 3, 4, 5, 6, 7})
Expect(c.Bytes()).To(Equal([]byte{1, 2, 3, 4, 5, 6, 7}))
})
It("returns a nil byte slice for the default value", func() {
var c ConnectionID
Expect(c.Bytes()).To(BeNil())
})
It("has a string representation", func() {
c := ConnectionID([]byte{0xde, 0xad, 0xbe, 0xef, 0x42})
Expect(c.String()).To(Equal("0xdeadbeef42"))
})
It("has a long string representation", func() {
c := ConnectionID{0x13, 0x37, 0, 0, 0xde, 0xca, 0xfb, 0xad}
Expect(c.String()).To(Equal("0x13370000decafbad"))
})
It("has a string representation for the default value", func() {
var c ConnectionID
Expect(c.String()).To(Equal("(empty)"))
})
})