public virtual int CompleteFrom(System.Net.Sockets.Socket socket, MemorySegment buffer) { if (IsReadOnly) { throw new InvalidOperationException("Cannot modify a RtcpPacket when IsReadOnly is false."); } //If the packet is complete then return if (IsDisposed || IsComplete) { return(0); } //Needs to account for buffer or socket. //Calulcate the amount of octets remaining in the RtcpPacket including the header int octetsRemaining = ((ushort)(Header.LengthInWordsMinusOne + 1)) * 4 - Length, offset = Payload != null ? Payload.Count : 0; if (octetsRemaining > 0) { //There is not enough room in the array to finish the packet if (Payload.Count < octetsRemaining) { //Allocte the memory for the required data if (m_OwnedOctets == null) { m_OwnedOctets = new byte[octetsRemaining]; } else { m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray(); } } System.Net.Sockets.SocketError error; int recieved = 0; //Read from the stream, decrementing from octetsRemaining what was read. while (octetsRemaining > 0) { int rec = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error); offset += rec; octetsRemaining -= rec; recieved += rec; } //Re-allocate the segment around the received data. //length + received Payload = new MemorySegment(m_OwnedOctets, 0, m_OwnedOctets.Length); return(recieved); } return(0); }
public virtual int CompleteFrom(System.Net.Sockets.Socket socket, MemorySegment buffer) { if (IsReadOnly) { throw new InvalidOperationException("Cannot modify a RtpPacket when IsReadOnly is false."); } //If the packet is complete then return if (IsDisposed || IsComplete) { return(0); } // Cache the size of the original payload int payloadCount = Payload.Count, octetsRemaining = payloadCount, //Cache how many octets remain in the payload offset = Payload.Offset, //Cache the offset in parsing sourceListOctets = ContributingSourceListOctets, //Cache the amount of octets required in the ContributingSourceList. extensionSize = Header.Extension ? RtpExtension.MinimumSize : 0, //Cache the amount of octets required to read the ExtensionHeader recieved = 0; //If the ContributingSourceList is not complete if (payloadCount < sourceListOctets) { //Calulcate the amount of octets to receive, ABS is weird and not required since paycount is checked to be less octetsRemaining = sourceListOctets - payloadCount; //Binary.Abs(payloadCount - sourceListOctets); //octetsRemaining = Binary.Min(payloadCount, sourceListOctets); //Allocte the memory for the required data if (m_OwnedOctets == null) { m_OwnedOctets = new byte[octetsRemaining]; } else { m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray(); } System.Net.Sockets.SocketError error; //Read from the stream, decrementing from octetsRemaining what was read. while (octetsRemaining > 0) { //Receive octetsRemaining or less int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error); //Move the offset offset += justReceived; //Decrement how many octets were receieved octetsRemaining -= justReceived; recieved += justReceived; } } //At the end of the sourceList offset = sourceListOctets; //ContribuingSourceList is now Complete //If there is a RtpExtension indicated by the RtpHeader if (Header.Extension) { //Determine if the extension header was read octetsRemaining = RtpExtension.MinimumSize - (payloadCount - offset); //If the extension header is not yet read if (octetsRemaining > 0) { //Allocte the memory for the extension header if (m_OwnedOctets == null) { m_OwnedOctets = new byte[octetsRemaining]; } else { m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray(); } System.Net.Sockets.SocketError error; //Read from the socket, decrementing from octetsRemaining what was read. while (octetsRemaining > 0) { //Receive octetsRemaining or less int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error); //Move the offset offset += justReceived; //Decrement how many octets were receieved octetsRemaining -= justReceived; recieved += justReceived; } } //at least 4 octets are now present in Payload @ Payload.Offset //Use a RtpExtension instance to read the Extension Header and data. using (RtpExtension extension = GetExtension()) { if (extension != null && false == extension.IsComplete) { //Cache the size of the RtpExtension (not including the Flags and LengthInWords [The Extension Header]) extensionSize = extension.Size - RtpExtension.MinimumSize; //The amount of octets required for for completion are indicated by the Size property of the RtpExtension. //Calulcate the amount of octets to receive octetsRemaining = (payloadCount - offset) - RtpExtension.MinimumSize; if (octetsRemaining > 0 && octetsRemaining < extensionSize) { //Allocte the memory for the required data if (m_OwnedOctets == null) { m_OwnedOctets = new byte[octetsRemaining]; } else { m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray(); } System.Net.Sockets.SocketError error; //Read from the stream, decrementing from octetsRemaining what was read. while (octetsRemaining > 0) { //Receive octetsRemaining or less int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error); //Move the offset offset += justReceived; //Decrement how many octets were receieved octetsRemaining -= justReceived; recieved += justReceived; } } } } } //RtpExtension is now Complete //If the header indicates the payload has padding if (Header.Padding) { //Double check this math octetsRemaining = PaddingOctets - payloadCount; if (octetsRemaining > 0) { //Allocte the memory for the required data if (m_OwnedOctets == null) { m_OwnedOctets = new byte[octetsRemaining]; } else { m_OwnedOctets = m_OwnedOctets.Concat(new byte[octetsRemaining]).ToArray(); } offset = payloadCount; //If the amount of bytes read in the padding is NOT equal to the last byte in the segment the RtpPacket is NOT complete while (octetsRemaining > 0) { System.Net.Sockets.SocketError error; //Receive 1 byte //Receive octetsRemaining or less int justReceived = SocketExtensions.AlignedReceive(m_OwnedOctets, offset, octetsRemaining, socket, out error); //Move the offset offset += justReceived; recieved += justReceived; octetsRemaining -= justReceived; } } } //Padding is now complete //Re allocate the payload segment to include any completed data Payload = new MemorySegment(m_OwnedOctets, Payload.Offset, m_OwnedOctets.Length); //RtpPacket is complete return(recieved); }