1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
package frame
import (
"fmt"
"io"
)
const (
maxSynBodySize = 8
maxSynFrameSize = headerSize + maxSynBodySize
)
type RStreamSyn struct {
Header
body [maxSynBodySize]byte
streamPriority StreamPriority
streamType StreamType
}
// StreamType returns the stream's defined type as specified by
// the remote endpoint
func (f *RStreamSyn) StreamType() StreamType {
return f.streamType
}
// StreamPriority returns the stream priority set on this frame
func (f *RStreamSyn) StreamPriority() StreamPriority {
return f.streamPriority
}
func (f *RStreamSyn) parseFields() error {
var length uint16 = 0
flags := f.Flags()
if flags.IsSet(flagStreamPriority) {
f.streamPriority = StreamPriority(order.Uint32(f.body[length : length+4]))
length += 4
} else {
f.streamPriority = 0
}
if flags.IsSet(flagStreamType) {
f.streamType = StreamType(order.Uint32(f.body[length : length+4]))
length += 4
} else {
f.streamType = 0
}
if length != f.Length() {
return fmt.Errorf("Expected length %d for flags %v, but got %v", length, flags, f.Length())
}
return nil
}
func (f *RStreamSyn) readFrom(d deserializer) (err error) {
if _, err = io.ReadFull(d, f.body[:f.Length()]); err != nil {
return
}
if err = f.parseFields(); err != nil {
return
}
return
}
type WStreamSyn struct {
Header
data [maxSynFrameSize]byte
length int
}
func (f *WStreamSyn) writeTo(s serializer) (err error) {
_, err = s.Write(f.data[:headerSize+f.Length()])
return
}
func (f *WStreamSyn) Set(streamId StreamId, streamPriority StreamPriority, streamType StreamType, fin bool) (err error) {
var (
flags flagsType
length int = 0
)
// set fin bit
if fin {
flags.Set(flagFin)
}
if streamPriority != 0 {
if streamPriority > priorityMask {
err = protoError("Priority %d is out of range", streamPriority)
return
}
flags.Set(flagStreamPriority)
start := headerSize + length
order.PutUint32(f.data[start:start+4], uint32(streamPriority))
length += 4
}
if streamType != 0 {
flags.Set(flagStreamType)
start := headerSize + length
order.PutUint32(f.data[start:start+4], uint32(streamType))
length += 4
}
// make the frame
if err = f.Header.SetAll(TypeStreamSyn, length, streamId, flags); err != nil {
return
}
return
}
func NewWStreamSyn() (f *WStreamSyn) {
f = new(WStreamSyn)
f.Header = Header(f.data[:headerSize])
return
}
|