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); }
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); }
// 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); }