public static byte[] ReadBytes(Buffer buf, int count) { byte[] dst = new byte[count]; for (int i = 0; i < count; i++) { dst[i] = (byte)Bitstream.ReadBits(buf, 8); } return(dst); }
public static bool Insert(Buffer dest, Buffer source) { if (dest.BitsLeft() < source.BitsLeft()) { return(false); } Bitstream.Buffer tmp = new Bitstream.Buffer(); Copy(tmp, source); while (tmp.BitsLeft() > 0) { if (tmp.bitpos > 0) { uint bits = (uint)(8 - tmp.bitpos); if (bits > tmp.BitsLeft()) { bits = tmp.BitsLeft(); } Bitstream.PutBits(dest, bits, Bitstream.ReadBits(tmp, bits)); } if (tmp.BitsLeft() > 32) { Bitstream.PutBits(dest, 32, Bitstream.ReadBits(tmp, 32)); } uint left = tmp.BitsLeft(); if (left >= 8) { Bitstream.PutBits(dest, 8, Bitstream.ReadBits(tmp, 8)); } else if (left > 0) { Bitstream.PutBits(dest, left, Bitstream.ReadBits(tmp, left)); } } return(true); }
// This will start reading from the buffers and modify the incoming array. public static void HandleIncomingPackets(LaneSetup setup, Incoming[] packets, uint packetsCount) { // Zero pass make own buffers. for (uint i = 0; i < packetsCount; i++) { if (!packets[i].CanKeepData) { Bitstream.Buffer tmp = packets[i].Packet; Bitstream.Buffer copy = setup.Factory.GetBuffer((uint)tmp.buf.Length); Bitstream.Insert(copy, tmp); copy.Flip(); packets[i].Packet = copy; } } // First pass extract. for (uint i = 0; i < packetsCount; i++) { Bitstream.Buffer tmp = packets[i].Packet; Lane lane = packets[i].Lane; lane.Stats.RecvCount++; lane.Stats.RecvBytes += tmp.BitsLeft() / 8; bool reliable = Bitstream.ReadBits(tmp, 1) == 1; uint seq = Bitstream.ReadCompressedUint(tmp); packets[i].Internal.Seq = seq; packets[i].Internal.IsReliable = reliable; if (seq == 0) { lane.Stats.RecvAckOnly++; } if (reliable) { packets[i].Internal.IsFinalPiece = Bitstream.ReadBits(tmp, 1) == 1; if (!packets[i].Internal.IsFinalPiece) { lane.Stats.RecvNonFinal++; } if (seq != 0) { if (lane.AckCount < lane.Acks.Length) { lane.Acks[lane.AckCount++] = seq; } } while (true) { uint seqAck = Bitstream.ReadCompressedUint(tmp); if (seqAck != 0) { for (int j = 0; j != lane.OutCount; j++) { if (lane.Out[j].SeqId == seqAck) { double msLag = (packets[i].ArrivalTime - lane.Out[j].InitialSendTime).TotalMilliseconds; if (msLag > 0) { uint ms = (uint)msLag; if (ms < lane.LagMsMin || lane.LagMsMin == 0) { if (ms >= setup.MinResendTimeMs) { lane.LagMsMin = ms; lane.ResendMs = 2 * ms; } } } if (lane.Out[j].Source != null) { if (--lane.Out[j].Source.userdata == 0) { setup.Factory.ReturnBuffer(lane.Out[j].Source); } lane.Out[j].Source = null; } } } continue; } break; } } else { packets[i].Internal.IsFinalPiece = true; } Bitstream.SyncByte(tmp); } // Unreliable packets, these are placed in the out queue after reading out the sequence and mode. for (int i = 0; i < packets.Length; i++) { if (packets[i].Internal.IsReliable || packets[i].Internal.Seq == 0) { continue; } Lane lane = packets[i].Lane; if (lane.DoneHead - lane.DoneTail != lane.Done.Length) { uint head = lane.DoneHead % (uint)lane.Done.Length; lane.Done[head].Data = packets[i].Packet; lane.Done[head].Reliable = false; lane.Done[head].SeqId = packets[i].Internal.Seq; lane.Done[head].ArrivalTime = packets[i].ArrivalTime; lane.Done[head].CompletionTime = packets[i].ArrivalTime; lane.Done[head].Lane = lane; lane.DoneHead = lane.DoneHead + 1; } } // Handle reliable. These go straight for (int i = 0; i < packets.Length; i++) { if (!packets[i].Internal.IsReliable || packets[i].Internal.Seq == 0) { continue; } Lane lane = packets[i].Lane; if (packets[i].Internal.Seq <= lane.ReliableSeq) { lane.Stats.RecvDupes++; continue; } // If packet arrives a second time, ignore. uint numProgress = (uint)lane.Progress.Length; bool hadit = false; for (uint p = lane.ProgressTail; p != lane.ProgressHead; p++) { uint idx = p % numProgress; if (lane.Progress[idx].SeqId == packets[i].Internal.Seq) { hadit = true; break; } } if (hadit) { // Already got the packet for this sequence id. lane.Stats.RecvDupes++; continue; } if (lane.ProgressHead - lane.ProgressTail != lane.Progress.Length) { uint head = lane.ProgressHead % (uint)lane.Progress.Length; lane.Progress[head].Data = packets[i].Packet; lane.Progress[head].IsFinalPiece = packets[i].Internal.IsFinalPiece; lane.Progress[head].ArrivalTime = packets[i].ArrivalTime; lane.Progress[head].SeqId = packets[i].Internal.Seq; lane.ProgressHead = lane.ProgressHead + 1; } } }