Skip to content

Commit

Permalink
Implement packet clone method
Browse files Browse the repository at this point in the history
Clone performs deep copy on a packet to produce equivalent
but independently mutable packet.

Fixes #88
  • Loading branch information
ffmiruz authored and Sean-Der committed Jun 14, 2023
1 parent a11a460 commit e655591
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
33 changes: 33 additions & 0 deletions packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,3 +507,36 @@ func (p Packet) MarshalTo(buf []byte) (n int, err error) {
func (p Packet) MarshalSize() int {
return p.Header.MarshalSize() + len(p.Payload) + int(p.PaddingSize)
}

// Clone returns a deep copy of p.
func (p Packet) Clone() *Packet {
clone := &Packet{}
clone.Header = p.Header.Clone()
if p.Payload != nil {
clone.Payload = make([]byte, len(p.Payload))
copy(clone.Payload, p.Payload)
}
clone.PaddingSize = p.PaddingSize
return clone
}

// Clone returns a deep copy h.
func (h Header) Clone() Header {
clone := h
if h.CSRC != nil {
clone.CSRC = make([]uint32, len(h.CSRC))
copy(clone.CSRC, h.CSRC)
}
if h.Extensions != nil {
ext := make([]Extension, len(h.Extensions))
for i, e := range h.Extensions {
ext[i] = e
if e.payload != nil {
ext[i].payload = make([]byte, len(e.payload))
copy(ext[i].payload, e.payload)
}
}
clone.Extensions = ext
}
return clone
}
53 changes: 53 additions & 0 deletions packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,59 @@ func TestRoundtrip(t *testing.T) {
}
}

func TestCloneHeader(t *testing.T) {
h := Header{
Marker: true,
Extension: true,
ExtensionProfile: 1,
Extensions: []Extension{
{0, []byte{
0xFF, 0xFF, 0xFF, 0xFF,
}},
},
Version: 2,
PayloadType: 96,
SequenceNumber: 27023,
Timestamp: 3653407706,
SSRC: 476325762,
CSRC: []uint32{},
}
clone := h.Clone()
if !reflect.DeepEqual(h, clone) {
t.Errorf("Cloned clone does not match the original")
}

h.CSRC = append(h.CSRC, 1)
if len(clone.CSRC) == len(h.CSRC) {
t.Errorf("Expected CSRC to be unchanged")
}
h.Extensions[0].payload[0] = 0x1F
if clone.Extensions[0].payload[0] == 0x1F {
t.Errorf("Expected Extensions to be unchanged")
}
}

func TestClonePacket(t *testing.T) {
rawPkt := []byte{
0x90, 0xe0, 0x69, 0x8f, 0xd9, 0xc2, 0x93, 0xda, 0x1c, 0x64,
0x27, 0x82, 0xBE, 0xDE, 0x00, 0x01, 0x50, 0xAA, 0x00, 0x00,
0x98, 0x36, 0xbe, 0x88, 0x9e,
}
p := &Packet{
Payload: rawPkt[20:],
}

clone := p.Clone()
if !reflect.DeepEqual(p, clone) {
t.Errorf("Cloned Packet does not match the original")
}

p.Payload[0] = 0x1F
if clone.Payload[0] == 0x1F {
t.Errorf("Expected Payload to be unchanged")
}
}

func BenchmarkMarshal(b *testing.B) {
rawPkt := []byte{
0x90, 0x60, 0x69, 0x8f, 0xd9, 0xc2, 0x93, 0xda, 0x1c, 0x64,
Expand Down

0 comments on commit e655591

Please sign in to comment.