package rtcp
import (
"encoding/binary"
"fmt"
)
type Goodbye struct {
Sources []uint32
Reason string
}
func (g Goodbye ) Marshal () ([]byte , error ) {
rawPacket := make ([]byte , g .MarshalSize ())
packetBody := rawPacket [headerLength :]
if len (g .Sources ) > countMax {
return nil , errTooManySources
}
for i , s := range g .Sources {
binary .BigEndian .PutUint32 (packetBody [i *ssrcLength :], s )
}
if g .Reason != "" {
reason := []byte (g .Reason )
if len (reason ) > sdesMaxOctetCount {
return nil , errReasonTooLong
}
reasonOffset := len (g .Sources ) * ssrcLength
packetBody [reasonOffset ] = uint8 (len (reason ))
copy (packetBody [reasonOffset +1 :], reason )
}
hData , err := g .Header ().Marshal ()
if err != nil {
return nil , err
}
copy (rawPacket , hData )
return rawPacket , nil
}
func (g *Goodbye ) Unmarshal (rawPacket []byte ) error {
var header Header
if err := header .Unmarshal (rawPacket ); err != nil {
return err
}
if header .Type != TypeGoodbye {
return errWrongType
}
if getPadding (len (rawPacket )) != 0 {
return errPacketTooShort
}
g .Sources = make ([]uint32 , header .Count )
reasonOffset := int (headerLength + header .Count *ssrcLength )
if reasonOffset > len (rawPacket ) {
return errPacketTooShort
}
for i := 0 ; i < int (header .Count ); i ++ {
offset := headerLength + i *ssrcLength
g .Sources [i ] = binary .BigEndian .Uint32 (rawPacket [offset :])
}
if reasonOffset < len (rawPacket ) {
reasonLen := int (rawPacket [reasonOffset ])
reasonEnd := reasonOffset + 1 + reasonLen
if reasonEnd > len (rawPacket ) {
return errPacketTooShort
}
g .Reason = string (rawPacket [reasonOffset +1 : reasonEnd ])
}
return nil
}
func (g *Goodbye ) Header () Header {
return Header {
Padding : false ,
Count : uint8 (len (g .Sources )),
Type : TypeGoodbye ,
Length : uint16 ((g .MarshalSize () / 4 ) - 1 ),
}
}
func (g *Goodbye ) MarshalSize () int {
srcsLength := len (g .Sources ) * ssrcLength
reasonLength := len (g .Reason )
if reasonLength > 0 {
reasonLength ++
}
l := headerLength + srcsLength + reasonLength
return l + getPadding (l )
}
func (g *Goodbye ) DestinationSSRC () []uint32 {
out := make ([]uint32 , len (g .Sources ))
copy (out , g .Sources )
return out
}
func (g Goodbye ) String () string {
out := "Goodbye\n"
for i , s := range g .Sources {
out += fmt .Sprintf ("\tSource %d: %x\n" , i , s )
}
out += fmt .Sprintf ("\tReason: %s\n" , g .Reason )
return out
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .