Esempio n. 1
0
 /// <summary>
 /// Adds the current chunk to the terminal and starts a new chunk.
 /// </summary>
 private void _NextChunk()
 {
     this._Terminal._Push(this._Current);
     this._Current = new _Chunk()
     {
         Data = new byte[this._ChunkSize]
     };
 }
Esempio n. 2
0
 public _SendStream(int ChunkSize, OutTerminal Terminal)
 {
     this._ChunkSize = ChunkSize;
     this._Terminal = Terminal;
     this._Current = new _Chunk
     {
         Data = new byte[ChunkSize],
         Initial = true
     };
 }
Esempio n. 3
0
 /// <summary>
 /// Appends a new chunk to this terminal.
 /// </summary>
 private void _Push(_Chunk Chunk)
 {
     lock (this)
     {
         LinkedListNode<_Chunk> node = this._Chunks.AddLast(Chunk);
         if (this._SendNode == null)
         {
             this._SendNode = node;
             this._SendNumber = this._SequenceNumber;
         }
         this._SequenceNumber++;
     }
 }
Esempio n. 4
0
 /// <summary>
 /// Advances to the next chunk.
 /// </summary>
 private void _Continue()
 {
     if (this._Current.Final)
     {
         throw new StreamUnderflowException();
     }
     if (this._Remove)
     {
         this._Chunks.Remove(this._SequenceNumber);
     }
     else
     {
         this._Current.Data = null;
     }
     this._Offset = 0;
     this._Current = this._Chunks[++this._SequenceNumber];
 }
Esempio n. 5
0
 public _ReceiveStream(int SequenceNumber, bool Remove, InTerminal Terminal)
 {
     this._Remove = Remove;
     this._Chunks = Terminal._Chunks;
     this._SequenceNumber = SequenceNumber;
     this._Current = this._Chunks[SequenceNumber];
 }
Esempio n. 6
0
        /// <summary>
        /// Processes the receipt of a chunk. Returns true and sets the message stream if a full message has been received.
        /// </summary>
        /// <param name="SequenceNumber">The sequence number for the received chunk.</param>
        /// <param name="Acknowledged">Indicates wether the receipt of this chunk has changed the acknowledgement number.</param>
        public bool Process(int SequenceNumber, byte[] Data, bool Initial, bool Final, out bool Acknowledged, ref Disposable<InStream> Message)
        {
            _Chunk chunk;

            // Make sure we need this chunk
            if (this._Chunks.ContainsKey(SequenceNumber) || this._AcknowledgementNumber - SequenceNumber > 0)
            {
                Acknowledged = false;
                return false;
            }

            // Update acknowledgement number
            if (Acknowledged = this._AcknowledgementNumber == SequenceNumber)
            {
                while (this._Chunks.TryGetValue(++this._AcknowledgementNumber, out chunk))
                {
                    // If the chunk has already been read in a message, remove it
                    if (chunk.Data == null)
                    {
                        this._Chunks.Remove(this._AcknowledgementNumber);
                    }
                }
            }

            // Add chunk
            chunk = new _Chunk
            {
                Data = Data,
                Initial = Initial,
                Final = Final
            };

            // Find "First" chunk
            _Chunk first;
            int firstsq = SequenceNumber - 1;
            if (!Initial && this._Chunks.TryGetValue(firstsq, out first))
            {
                firstsq = first.First;
                first = this._Chunks[firstsq];
                chunk.First = firstsq;
            }
            else
            {
                chunk.First = firstsq = SequenceNumber;
                first = chunk;
            }

            // Find "Last" chunk
            _Chunk last;
            int lastsq = SequenceNumber + 1;
            if (!Final && this._Chunks.TryGetValue(lastsq, out last))
            {
                lastsq = last.Last;
                last = this._Chunks[lastsq];
                chunk.Last = lastsq;
            }
            else
            {
                chunk.Last = lastsq = SequenceNumber;
                last = chunk;
            }

            // Check if a full message can be formed
            this._Chunks[SequenceNumber] = chunk;
            if (first.Initial && last.Final)
            {
                Message = new _ReceiveStream(firstsq, Acknowledged, this);
                return true;
            }
            else
            {
                first.Last = lastsq;
                last.First = firstsq;
                return false;
            }
        }