Example #1
0
 public static bool PutBytes(Buffer buf, byte[] data)
 {
     for (int i = 0; i < data.Length; i++)
     {
         Bitstream.PutBits(buf, 8, data[i]);
     }
     return(buf.error != 0);
 }
Example #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);
        }
Example #3
0
        // Return if there is more to come.
        public static bool ProcessLanesSend(LaneSetup setup, Lane[] lanes, DateTime now, Send[] output, out uint numOut)
        {
            numOut = 0;
            for (int i = 0; i < lanes.Length; i++)
            {
                Lane lane  = lanes[i];
                int  holes = 0;
                for (int j = 0; j < lane.OutCount; j++)
                {
                    if (lane.Out[j].Source == null)
                    {
                        holes++;
                        continue;
                    }
                    if (lane.Out[j].SendTime <= now)
                    {
                        lane.Stats.SendCount++;
                        lane.Out[j].SendCount++;
                        if (lane.Out[j].SendCount > 1)
                        {
                            lane.Stats.SendResends++;
                        }

                        uint resendMsAdd = lane.Out[j].SendCount * lane.Out[j].SendCount * lane.ResendMs;
                        if (resendMsAdd > 5000)
                        {
                            resendMsAdd = 5000;
                        }

                        lane.Out[j].SendTime = lane.Out[j].SendTime.AddMilliseconds(resendMsAdd);

                        Bitstream.Buffer tmp = setup.Factory.GetBuffer(setup.MaxPacketSize);
                        tmp.bytepos = setup.ReservedHeaderBytes;

                        Bitstream.PutBits(tmp, 1, lane.Out[j].Reliable ? 1u : 0u);
                        Bitstream.PutCompressedUint(tmp, lane.Out[j].SeqId);

                        if (lane.Out[j].Reliable)
                        {
                            Bitstream.PutBits(tmp, 1, lane.Out[j].IsFinalPiece ? 1u : 0u);

                            // flush out a max number of acks or all.
                            int wrote = 0;
                            for (int k = 0; k < lane.AckCount && k < 4; k++)
                            {
                                Bitstream.PutCompressedUint(tmp, lane.Acks[k]);
                                wrote++;
                            }
                            Bitstream.PutCompressedUint(tmp, 0);
                            for (int k = 0; k < (int)lane.AckCount - wrote; k++)
                            {
                                lane.Acks[k] = lane.Acks[k + wrote];
                            }
                            lane.AckCount = (ushort)(lane.AckCount - wrote);
                        }

                        Bitstream.SyncByte(tmp);

                        uint   begin = lane.Out[j].Begin;
                        uint   end   = lane.Out[j].End;
                        uint   ofs   = tmp.bytepos;
                        byte[] src   = lane.Out[j].Source.buf;
                        byte[] dst   = tmp.buf;
                        for (uint k = begin; k != end; k++)
                        {
                            dst[ofs++] = src[k];
                        }
                        tmp.bytepos           = 0;
                        tmp.bitpos            = 0;
                        tmp.bytesize          = ofs;
                        tmp.bitsize           = 0;
                        output[numOut].Data   = tmp;
                        output[numOut].Lane   = lane;
                        lane.Stats.SendBytes += ofs;
                        if (++numOut == output.Length)
                        {
                            return(true);
                        }
                    }
                }

                if (holes > 0 && holes >= lane.OutCount / 4)
                {
                    ushort write = 0;
                    for (uint j = 0; j < lane.OutCount; j++)
                    {
                        if (lane.Out[j].Source != null)
                        {
                            if (write != j)
                            {
                                lane.Out[write] = lane.Out[j];
                            }
                            ++write;
                        }
                    }
                    lane.OutCount = write;
                }
            }

            // Unsent acks
            for (int i = 0; i < lanes.Length; i++)
            {
                Lane lane = lanes[i];
                if (lane.AckCount > 0)
                {
                    Bitstream.Buffer tmp = setup.Factory.GetBuffer(setup.MaxPacketSize);
                    tmp.bytepos = setup.ReservedHeaderBytes;
                    Bitstream.PutBits(tmp, 1, 1);                     // reliable
                    Bitstream.PutCompressedUint(tmp, 0);              // ack only
                    Bitstream.PutBits(tmp, 1, 1);                     // final

                    for (int k = 0; k < lane.AckCount; k++)
                    {
                        Bitstream.PutCompressedUint(tmp, lane.Acks[k]);
                    }

                    Bitstream.PutCompressedUint(tmp, 0);
                    lane.AckCount = 0;
                    Bitstream.SyncByte(tmp);
                    tmp.Flip();
                    output[numOut].Data = tmp;
                    output[numOut].Lane = lane;

                    lane.Stats.SendCount++;
                    lane.Stats.SendAckOnly++;
                    lane.Stats.SendBytes += tmp.bytesize;

                    if (++numOut == output.Length)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }