mirror of https://github.com/hashicorp/consul
69 lines
1.3 KiB
Go
69 lines
1.3 KiB
Go
|
package frame
|
||
|
|
||
|
import (
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// data frames are actually longer, but they are variable length
|
||
|
dataFrameSize = headerSize
|
||
|
)
|
||
|
|
||
|
type RStreamData struct {
|
||
|
Header
|
||
|
fixed [dataFrameSize]byte
|
||
|
|
||
|
toRead io.LimitedReader // when reading, the underlying connection's io.Reader is handed up
|
||
|
}
|
||
|
|
||
|
func (f *RStreamData) Reader() io.Reader {
|
||
|
return &f.toRead
|
||
|
}
|
||
|
|
||
|
func (f *RStreamData) readFrom(d deserializer) (err error) {
|
||
|
// not using io.LimitReader to avoid a heap memory allocation in the hot path
|
||
|
f.toRead.R = d
|
||
|
f.toRead.N = int64(f.Length())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// WStreamData is a StreamData frame that you can write
|
||
|
// It delivers opaque data on a stream to the application layer
|
||
|
type WStreamData struct {
|
||
|
Header
|
||
|
fixed [dataFrameSize]byte
|
||
|
toWrite []byte // when writing, you just pass a byte slice to write
|
||
|
}
|
||
|
|
||
|
func (f *WStreamData) writeTo(s serializer) (err error) {
|
||
|
if _, err = s.Write(f.fixed[:]); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if _, err = s.Write(f.toWrite); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (f *WStreamData) Set(streamId StreamId, data []byte, fin bool) (err error) {
|
||
|
var flags flagsType
|
||
|
if fin {
|
||
|
flags.Set(flagFin)
|
||
|
}
|
||
|
|
||
|
if err = f.Header.SetAll(TypeStreamData, len(data), streamId, flags); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
f.toWrite = data
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func NewWStreamData() (f *WStreamData) {
|
||
|
f = new(WStreamData)
|
||
|
f.Header = f.fixed[:headerSize]
|
||
|
return
|
||
|
}
|