override public void Run() { BufferChunk bc = new BufferChunk(new byte[5], 2, 3); if(bc.Index != 2) { throw new TestCaseException("unexpected index"); } }
override public void Run() { try { BufferChunk bc = new BufferChunk(5); bc.Length = -1; throw new TestCaseException("length must be >= 0"); } catch(ArgumentOutOfRangeException){} }
override public void Run() { byte[] data = new byte[] {1, 2, 3}; BufferChunk bc = new BufferChunk(data); if(bc.Buffer != data) { throw new TestCaseException("buffers are not the same object"); } }
override public void Run() { try { BufferChunk bc = new BufferChunk(2048); bc.Length = 40; if(bc.Length != 40) { throw new TestCaseException("get isn't returning same value as set"); } } catch(ArgumentOutOfRangeException){} }
override public void Run() { byte src = 1; BufferChunk dest = new BufferChunk(new byte[]{1}); try { dest = dest + src; throw new TestCaseException("there should be inadequate room in the buffer"); } catch(BufferChunk.InsufficientSpaceException){} }
override public void Run() { BufferChunk src = new BufferChunk(new byte[]{5, 4, 3, 2, 1}); BufferChunk dest = new BufferChunk(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 5); dest += src; // Validate length if(dest.Length != 10) { throw new TestCaseException("BufferChunk should be length 10"); } // Validate contents byte[] combo = new byte[]{1, 2, 3, 4, 5, 5, 4, 3, 2, 1}; for(int i = 0; i < 10; i++) { if(combo[i] != dest.Buffer[i]) { throw new TestCaseException("bytes don't match"); } } }
/// <summary> /// Make sure the provided buffer might be a real Rtp Packet (version == 2) /// </summary> private void ValidateBuffer(BufferChunk buffer) { int version = buffer[VPXCC_INDEX] >> 6; if (version != Rtp.VERSION) throw new InvalidRtpPacketException(string.Format("Invalid version: {0}, current: {1}", version, Rtp.VERSION)); }
internal void AppendPayload(BufferChunk data) { buffer += data; }
/// <summary> /// Create a packet from an existing packet /// </summary> /// <param name="packet"></param> internal RtpPacketBase(RtpPacketBase packet) { buffer = packet.buffer; }
override public void Run() { try { BufferChunk bc = new BufferChunk(new byte[5], 3, 3); throw new TestCaseException("index + length cannot be > buffer.Length"); } catch(ArgumentException){} }
override public void Run() { BufferChunk bc = new BufferChunk(5); bc.Length = 4; }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[] {74, 97, 115, 111, 110}, 0, 0); try { string contents = (string)bc; throw new TestCaseException("no data"); } catch(BufferChunk.NoDataException){} }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[] {1, 2, 3}, 1, 2); byte[] bytes = (byte[])bc; // Validate the length if(bytes.Length != 2) { throw new TestCaseException("length should be 2"); } // Validate the contents for(int i = 0; i < 2; i++) { if(bytes[i] != i + 2) { throw new TestCaseException("bytes don't match"); } } }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[] {1, 2, 3}, 0, 0); try { byte[] bytes = (byte[])bc; throw new TestCaseException("no data"); } catch(BufferChunk.NoDataException){} }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[5], 1, 2); if(bc.Length != 2) { throw new TestCaseException("Length is invalid"); } }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[5], 1, 2); if(bc.Index != 1) { throw new TestCaseException("Index is invalid"); } }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[]{1, 2, 3}, 1, 2); for(int i = 1; i < 2; i++) { if(bc.Buffer[i] != i + 1) { throw new TestCaseException("bytes don't match"); } } }
override public void Run() { byte src = 1; BufferChunk dest = new BufferChunk(new byte[]{1, 2}, 0, 0); dest = dest + src; }
override public void Run() { byte src = 1; BufferChunk dest = new BufferChunk(new byte[]{1, 2, 3}, 0, 2); dest += src; // Validate length if(dest.Length != 3) { throw new TestCaseException("BufferChunk should be length 3"); } // Validate contents byte[] combo = new byte[]{1, 2, 1}; for(int i = 0; i < combo.Length; i++) { if(combo[i] != dest.Buffer[i]) { throw new TestCaseException("bytes don't match"); } } }
/// <summary> /// Creates a packet of the given size /// </summary> internal RtpPacketBase(int packetSize) { buffer = new BufferChunk(new byte[packetSize]); Reset(); }
/// <summary> /// Broadcasts a single chunk and stores it in the frame buffer. /// </summary> /// <param name="chunk">The chunk to send</param> private void RtpSend(Chunk chunk, MessagePriority priority) { using(Synchronizer.Lock(this)) { using(MemoryStream stream = new MemoryStream((int) (this.m_Encoder.MaximumChunkSize * 2))) { // Store the sequence number of non-real-time chunks so they can be NACKed. // Use "++this.m_FrameSequence" so that non-real-time chunks always have a // FrameSequence that is greater than 0. if (priority != MessagePriority.RealTime) chunk.FrameSequence = ++this.m_FrameSequence; // If the chunk is not real time (or it is being resent a second time), // store the chunk in the buffer so a NACK request can resend it. if (chunk.FrameSequence > ulong.MinValue) this.m_FrameBuffer.Insert(chunk); // Buffering the chunk probably evicted other chunks from the buffer, // so get the oldest frame in the buffer so receivers don't waste time // sending NACKs for chunks that are no longer available. chunk.OldestRecoverableFrame = this.m_FrameBuffer.OldestRecoverableFrame; chunk.OldestRecoverableMessage = this.m_FrameBuffer.OldestRecoverableMessage; // Serialize the chunk (which itself contains a serialized message). // TODO: see whether the wire protocol can be made more efficient. stream.Position = 0; this.m_Encoder.EncodeChunk(stream, chunk); // Prepare the frame to be sent over RTP. BufferChunk buffer = new BufferChunk(stream.GetBuffer(), 0, (int) stream.Length); // Send it (or drop some percentage of packets if the debug option is enabled). if(DEBUG_DROP_RANDOM_FRAMES <= 0 || new Random().Next(100) >= DEBUG_DROP_RANDOM_FRAMES) { Debug.WriteLine(string.Format("Sending frame #{0} ({1} bytes, message #{2}, chunk #{3} of {4}, depending on #{5}, priority {6})", chunk.FrameSequence, chunk.Data.Length, chunk.MessageSequence, chunk.ChunkSequenceInMessage + 1, chunk.NumberOfChunksInMessage, chunk.MessageDependency, priority), this.GetType().ToString()); try { this.m_RtpSender.Send( buffer ); } catch( Exception ) { this.Reset(); } } else { Debug.WriteLine(string.Format("DEBUG: Dropping frame #{0} ({1} bytes, message #{2}, chunk #{3} of {4}, depending on #{5}, priority {6})", chunk.FrameSequence, chunk.Data.Length, chunk.MessageSequence, chunk.ChunkSequenceInMessage + 1, chunk.NumberOfChunksInMessage, chunk.MessageDependency, priority), this.GetType().ToString()); } } } }
override public void Run() { BufferChunk bc = new BufferChunk(new byte[] {74, 97, 115, 111, 110}); string contents = (string)bc; if(contents != "Jason") { throw new TestCaseException("string should be 'Jason' but is " + contents); } }
/// <summary> /// Create a packet from an existing buffer /// </summary> /// <param name="buffer"></param> internal RtpPacketBase(BufferChunk buffer) { ValidateBuffer(buffer); this.buffer = buffer; }
override public void Run() { BufferChunk src = null; BufferChunk dest = new BufferChunk(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 5); try { dest = dest + src; throw new TestCaseException("argument can't be null"); } catch(ArgumentNullException){} }
internal void AppendPayload(Int32 data) { buffer += data; }
override public void Run() { BufferChunk src = new BufferChunk(new byte[]{1, 2, 3, 4, 5}, 0, 0); BufferChunk dest = new BufferChunk(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 5); try { dest = dest + src; throw new TestCaseException("no data"); } catch(BufferChunk.NoDataException){} }
/// <summary> /// Release the BufferChunk held by this packet so it can be reused outside the scope of this packet. /// </summary> /// <returns></returns> internal BufferChunk ReleaseBuffer() { BufferChunk ret = buffer; buffer = null; return ret; }
override public void Run() { BufferChunk src = new BufferChunk(new byte[]{5, 4, 3, 2, 1}); BufferChunk dest = new BufferChunk(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 0, 6); try { dest = dest + src; throw new TestCaseException("there should be inadequate room in the buffer"); } catch(BufferChunk.InsufficientSpaceException){} }
internal RtpPacket(BufferChunk buffer) : base(buffer){}
override public void Run() { BufferChunk bc = new BufferChunk(new byte[]{1, 2}); bc.Length = 1; }