示例#1
0
        /// <summary>Implements scan for new packets (invoked internally after reception of new data) and implements stale rx data detection and handling when no new data has been received.</summary>
        public void Service(bool performFullRescan)
        {
            // check for unscanned data
            if (performFullRescan)
                lastScannedContentCount = 0;

            if (BufferDataCount == 0 || BufferDataCount == lastScannedContentCount)
                return;

            PacketEndScannerDelegate scannerDelegate = packetEndScannerDelegate ?? defaultPacketEndScannerDelegate ?? (defaultPacketEndScannerDelegate = DefaultPacketEndScannerDelegate);

            bool foundPacket = false;

            for (;;)
            {
                int bufferDataCount = BufferDataCount;
                int nextPacketLen = scannerDelegate(buffer, getIdx, bufferDataCount, lastScannedContentCount);

                if (nextPacketLen == 0)
                {
                    lastScannedContentCount = bufferDataCount;
                    break;
                }
                else
                {
                    lastScannedContentCount = 0;
                    foundPacket = true;

                    int dataCopyStartIdx = getIdx;
                    bool isFlushedData = (nextPacketLen < 0);

                    nextPacketLen = Math.Abs(nextPacketLen);
                    int dataCopyLen = Math.Min(bufferDataCount, nextPacketLen);

                    bool isWhitespace = false;
                    if (isFlushedData)
                    {
                        // we do not strip whitespace from flushed data.
                    }
                    else if (StripWhitespace)
                    {
                        while (dataCopyLen > 0)
                        {
                            if (!IsWhiteSpace(buffer[dataCopyStartIdx]))
                                break;

                            dataCopyStartIdx++;
                            dataCopyLen--;
                        }

                        while (dataCopyLen > 0)
                        {
                            if (!IsWhiteSpace(buffer[dataCopyStartIdx + dataCopyLen - 1]))
                                break;

                            dataCopyLen--;
                        }

                        isWhitespace = (dataCopyLen == 0);
                    }
                    else
                    {
                        isWhitespace = true;    // assume that it is all whitespace
                        for (int scanOffset = 0; scanOffset < dataCopyLen; scanOffset++)
                        {
                            if (!IsWhiteSpace(buffer[getIdx + scanOffset]))
                                isWhitespace = false;
                        }
                    }

                    // extract bytes from buffer and append into new packet
                    if (!isWhitespace || !DiscardWhitespacePackets)
                    {
                        Packet p;
                        if (!isFlushedData)
                            p = new Packet((!isWhitespace ? PacketType.Data : PacketType.WhiteSpace), new byte[dataCopyLen]);
                        else
                            p = new Packet(PacketType.Flushed, new byte[dataCopyLen]);

                        if (dataCopyLen > 0)
                            System.Buffer.BlockCopy(buffer, dataCopyStartIdx, p.Data, 0, dataCopyLen);

                        extractedPacketQueue.Enqueue(p);
                    }

                    UsedNChars(nextPacketLen);
                }
            }

            // drop leading whitespace from buffer immediately (this will prevent them from causing generation of unexpected timeout packets for trailing whitespace that is ignored)
            if (StripWhitespace && BufferDataCount > 0)
            {
                if (IsWhiteSpace(buffer[getIdx]))
                    UsedNChars(1);
            }

            // check for timeout: when both the contentPutAge and the contentGetAge are larger than the PacketTimeout and it is not zero.
            if (!foundPacket && BufferDataCount > 0 && PacketTimeout != TimeSpan.Zero)
            {
                QpcTimeStamp now = QpcTimeStamp.Now;
                TimeSpan contentPutAge = now - ContentPutTime;
                TimeSpan contentGetAge = now - ContentGetTime;

                if (contentPutAge > PacketTimeout && contentGetAge > PacketTimeout)
                {
                    double contentAgeInSec = System.Math.Min(contentPutAge.TotalSeconds, contentGetAge.TotalSeconds);
                    string opStr = ((contentPutAge < contentGetAge) ? "Put" : "Get");

                    // transfer the current bytes in the sliding buffer into a new packet and reset the sliding buffer
                    Packet p = new Packet(PacketType.Timeout, new byte[BufferDataCount], Utils.Fcns.CheckedFormat("Timeout: {0} stale chars found in buffer {1:f3} seconds after most recent {2}", BufferDataCount, contentAgeInSec, opStr));
                    System.Buffer.BlockCopy(buffer, getIdx, p.Data, 0, BufferDataCount);

                    extractedPacketQueue.Enqueue(p);

                    UsedNChars(BufferDataCount);
                }
            }
        }
示例#2
0
        /// <summary>Attempts to extract the next packet from the queue and return it.  Returns null if there are currently no packets in the queue.</summary>
        /// <param name="flushBuffer">When true, if the buffer is not empty, the outstanding bytes will be placed into a flush packet which will be enqueued before attempting to extract and return the next packet from the queue.</param>
        /// <returns>next Packet from the queue of extracted packets or null if there are none.</returns>
        public Packet GetNextPacket(bool flushBuffer)
        {
            if (flushBuffer)
            {
                Service();

                int flushCount = BufferDataCount;

                if (flushCount > 0)
                {
                    // extract bytes from buffer and append into new packet
                    Packet p = new Packet(PacketType.Flushed, new byte[flushCount]);

                    System.Buffer.BlockCopy(buffer, getIdx, p.Data, 0, flushCount);

                    extractedPacketQueue.Enqueue(p);

                    UsedNChars(flushCount);
                }
            }

            if (extractedPacketQueue.Count != 0)
                return extractedPacketQueue.Dequeue();

            Service();

            if (extractedPacketQueue.Count != 0)
                return extractedPacketQueue.Dequeue();

            return null;
        }