Exemplo n.º 1
0
        /// <summary>
        /// trigger for the registered {@code MSRPSessionListener} callback.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="outgoingMessage"></param>
        public void TriggerUpdateSendStatus(Session session, OutgoingMessage outgoingMessage)
        {
            _logger.Debug("Called the triggerUpdateSendStatus hook");

            _myListener.UpdateSendStatus(session, outgoingMessage, outgoingMessage.SentBytes);
        }
        /// <summary>
        /// Method used by the connection object to retrieve a byte array of data
        /// to be sent by the connection.
        ///
        /// 3 mechanisms are active here:
        /// - 1 piggyback multiple transactions to send into the byte array.
        /// - 2 split large data over multiple byte-array blocks
        /// - 3 interrupt transactions that contain endline-data in the content
        ///     (and split into multiple transactions, using the validator).
        ///
        /// It is also at this level that the sending of bytes is accounted for
        /// purposes of triggering the sendUpdateStatus and the prioritiser
        /// </summary>
        /// <param name="outData">the byte array to fill with data to be sent</param>
        /// <returns>the number of bytes filled on outData</returns>
        public int GetDataToSend(byte[] outData)
        {
            int byteCounter = 0;

            //Variable that accounts the number of bytes per transaction sent
            int bytesToAccount = 0;

            lock (_transactionsToSendLock)
            {
                while (byteCounter < outData.Length && HasDataToSend)
                {
                    Transaction t = _transactionsToSend[0];
                    _outgoingDataValidator.Init(t.TransactionId);

                    bool stopTransmission = false;
                    while (byteCounter < outData.Length && !stopTransmission)
                    {
                        if (t.HasData)
                        {
                            // if we are still transmitting data
                            int result = t.GetData(outData, byteCounter);
                            byteCounter    += result;
                            bytesToAccount += result;
                        }
                        else
                        {
                            // Let's check to see if we should transmit the end of line
                            if (t.HasEndLine)
                            {
                                /*
                                 * the first time we get here we should check if the
                                 * end-line was found, and if it was we should rewind,
                                 * interrupt the transaction and set the bytesToAccount
                                 * back the appropriate positions and also the index i
                                 * we can also do the reset of the outgoingDataValidator
                                 * because we have for certain that the end-line won't
                                 * appear again on the content before the transaction
                                 * finishes
                                 */
                                _outgoingDataValidator.Parse(outData, byteCounter);
                                _outgoingDataValidator.Reset();
                                if (_outgoingDataValidator.DataHasEndLine)
                                {
                                    int rewindAmount = _outgoingDataValidator.Amount2Rewind();
                                    t.Rewind(rewindAmount);
                                    t.Interrupt();
                                    byteCounter    -= rewindAmount;
                                    bytesToAccount -= rewindAmount;
                                    continue;
                                }

                                int nrBytes = t.GetEndLine(outData, byteCounter);
                                byteCounter    += nrBytes;
                                bytesToAccount += nrBytes;
                            }
                            else
                            {
                                // Removing the given transaction from the queue of
                                // transactions to send
                                RemoveTransactionToSend(t);

                                // we should also reset the outgoingDataValidator, so
                                // that future calls to the parser won't misjudge the
                                //correct end-line as an end-line on the body content.
                                _outgoingDataValidator.Reset();

                                stopTransmission = true; // let's get the next transaction if any
                            }
                        }
                    }// end of transaction while

                    stopTransmission = false;

                    /*
                     * the buffer is full and or the transaction has been removed from
                     * the list of transactions to send and if that was the case the
                     * outgoingValidator won't make a false positive because it has been
                     * reset
                     */
                    _outgoingDataValidator.Parse(outData, byteCounter);
                    if (_outgoingDataValidator.DataHasEndLine)
                    {
                        int rewindAmount = _outgoingDataValidator.Amount2Rewind();
                        t.Rewind(rewindAmount);
                        t.Interrupt();
                        byteCounter    -= rewindAmount;
                        bytesToAccount -= rewindAmount;

                        int nrBytes = t.GetEndLine(outData, byteCounter);
                        byteCounter    += nrBytes;
                        bytesToAccount += nrBytes;

                        RemoveTransactionToSend(t);
                        _outgoingDataValidator.Reset();
                    }

                    // account for the bytes sent from this transaction if they should
                    // be accounted for
                    if (!t.IsIncomingResponse && t.TransactionType == TransactionType.SEND && !t.HasResponse)
                    {
                        // reporting the sent update status seen that this is an
                        // outgoing send request
                        OutgoingMessage transactionMessage = (OutgoingMessage)t.Message;
                        if (transactionMessage != null)
                        {
                            transactionMessage.ReportMechanism.CountSentBodyBytes(transactionMessage, bytesToAccount);
                            bytesToAccount = 0;
                        }
                    }
                }// end of main while, the one that goes across transactions
            }

            return(byteCounter);
        }