Files
quic-go/frame.go
2016-04-08 19:28:14 +02:00

70 lines
1.4 KiB
Go

package quic
import (
"bytes"
"io/ioutil"
)
// A StreamFrame of QUIC
// TODO: Maybe remove unneeded stuff, e.g. lengths?
type StreamFrame struct {
FinBit bool
DataLengthPresent bool
OffsetLength uint8
StreamIDLength uint8
StreamID uint32
Offset uint64
DataLength uint16
Data []byte
}
// ParseStreamFrame reads a stream frame. The type byte must not have been read yet.
func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) {
frame := &StreamFrame{}
typeByte, err := r.ReadByte()
if err != nil {
return nil, err
}
frame.FinBit = typeByte&0x40 > 0
frame.DataLengthPresent = typeByte&0x20 > 0
frame.OffsetLength = typeByte & 0x1C >> 2
if frame.OffsetLength != 0 {
frame.OffsetLength++
}
frame.StreamIDLength = typeByte&0x03 + 1
sid, err := readUintN(r, frame.StreamIDLength)
if err != nil {
return nil, err
}
frame.StreamID = uint32(sid)
frame.Offset, err = readUintN(r, frame.OffsetLength)
if err != nil {
return nil, err
}
if frame.DataLengthPresent {
frame.DataLength, err = readUint16(r)
if err != nil {
return nil, err
}
}
if frame.DataLength == 0 {
// The rest of the packet is data
frame.Data, err = ioutil.ReadAll(r)
if err != nil {
return nil, err
}
} else {
frame.Data = make([]byte, frame.DataLength)
if _, err := r.Read(frame.Data); err != nil {
return nil, err
}
}
return frame, nil
}