implement stream frame splitting in StreamFrame

This commit is contained in:
Lucas Clemente
2016-04-20 16:16:01 +02:00
parent 6be70bc29c
commit 2e87459677
2 changed files with 98 additions and 49 deletions

View File

@@ -93,3 +93,23 @@ func (f *StreamFrame) Write(b *bytes.Buffer) error {
func (f *StreamFrame) MaxLength() int { func (f *StreamFrame) MaxLength() int {
return 1 + 4 + 8 + 2 + 1 return 1 + 4 + 8 + 2 + 1
} }
// MaybeSplitOffFrame removes the first n bytes and returns them as a separate frame. If n >= len(n), nil is returned and nothing is modified.
func (f *StreamFrame) MaybeSplitOffFrame(n int) *StreamFrame {
if n >= f.MaxLength()-1+len(f.Data) {
return nil
}
n -= f.MaxLength() - 1
defer func() {
f.Data = f.Data[n:]
f.Offset += uint64(n)
}()
return &StreamFrame{
FinBit: false,
StreamID: f.StreamID,
Offset: f.Offset,
Data: f.Data[:n],
}
}

View File

@@ -9,59 +9,88 @@ import (
) )
var _ = Describe("StreamFrame", func() { var _ = Describe("StreamFrame", func() {
Context("stream frames", func() { Context("when parsing", func() {
Context("when parsing", func() { It("accepts sample frame", func() {
It("accepts sample frame", func() { b := bytes.NewReader([]byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'})
b := bytes.NewReader([]byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}) frame, err := ParseStreamFrame(b)
frame, err := ParseStreamFrame(b) Expect(err).ToNot(HaveOccurred())
Expect(err).ToNot(HaveOccurred()) Expect(frame.FinBit).To(BeFalse())
Expect(frame.FinBit).To(BeFalse()) Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
Expect(frame.StreamID).To(Equal(protocol.StreamID(1))) Expect(frame.Offset).To(BeZero())
Expect(frame.Offset).To(BeZero()) Expect(frame.Data).To(Equal([]byte("foobar")))
Expect(frame.Data).To(Equal([]byte("foobar")))
})
It("accepts frame without datalength", func() {
b := bytes.NewReader([]byte{0x80, 0x1, 'f', 'o', 'o', 'b', 'a', 'r'})
frame, err := ParseStreamFrame(b)
Expect(err).ToNot(HaveOccurred())
Expect(frame.FinBit).To(BeFalse())
Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
Expect(frame.Offset).To(BeZero())
Expect(frame.Data).To(Equal([]byte("foobar")))
})
}) })
Context("when writing", func() { It("accepts frame without datalength", func() {
It("writes sample frame", func() { b := bytes.NewReader([]byte{0x80, 0x1, 'f', 'o', 'o', 'b', 'a', 'r'})
b := &bytes.Buffer{} frame, err := ParseStreamFrame(b)
(&StreamFrame{ Expect(err).ToNot(HaveOccurred())
StreamID: 1, Expect(frame.FinBit).To(BeFalse())
Data: []byte("foobar"), Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
}).Write(b) Expect(frame.Offset).To(BeZero())
Expect(b.Bytes()).To(Equal([]byte{0xa3, 0x1, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'})) Expect(frame.Data).To(Equal([]byte("foobar")))
}) })
})
It("writes offsets", func() { Context("when writing", func() {
b := &bytes.Buffer{} It("writes sample frame", func() {
(&StreamFrame{ b := &bytes.Buffer{}
StreamID: 1, (&StreamFrame{
Offset: 16, StreamID: 1,
Data: []byte("foobar"), Data: []byte("foobar"),
}).Write(b) }).Write(b)
Expect(b.Bytes()).To(Equal([]byte{0xbf, 0x1, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'})) Expect(b.Bytes()).To(Equal([]byte{0xa3, 0x1, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
}) })
It("has proper max length", func() { It("writes offsets", func() {
b := &bytes.Buffer{} b := &bytes.Buffer{}
f := &StreamFrame{ (&StreamFrame{
StreamID: 1, StreamID: 1,
Data: []byte("f"), Offset: 16,
Offset: 1, Data: []byte("foobar"),
} }).Write(b)
f.Write(b) Expect(b.Bytes()).To(Equal([]byte{0xbf, 0x1, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
Expect(f.MaxLength()).To(Equal(b.Len())) })
})
It("has proper max length", func() {
b := &bytes.Buffer{}
f := &StreamFrame{
StreamID: 1,
Data: []byte("f"),
Offset: 1,
}
f.Write(b)
Expect(f.MaxLength()).To(Equal(b.Len()))
})
})
Context("splitting off earlier stream frames", func() {
It("splits off nothing", func() {
f := &StreamFrame{
StreamID: 1,
Data: []byte("bar"),
Offset: 3,
}
Expect(f.MaybeSplitOffFrame(1000)).To(BeNil())
Expect(f.Offset).To(Equal(uint64(3)))
})
It("splits off initial frame", func() {
f := &StreamFrame{
StreamID: 1,
Data: []byte("foobar"),
Offset: 3,
FinBit: true,
}
previous := f.MaybeSplitOffFrame(f.MaxLength() - 1 + 3)
Expect(previous).ToNot(BeNil())
Expect(previous.StreamID).To(Equal(protocol.StreamID(1)))
Expect(previous.Data).To(Equal([]byte("foo")))
Expect(previous.Offset).To(Equal(uint64(3)))
Expect(previous.FinBit).To(BeFalse())
Expect(f.StreamID).To(Equal(protocol.StreamID(1)))
Expect(f.Data).To(Equal([]byte("bar")))
Expect(f.Offset).To(Equal(uint64(6)))
Expect(f.FinBit).To(BeTrue())
}) })
}) })
}) })