Esempio n. 1
0
 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);
 }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        // 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;
                }
            }
        }