Example #1
0
        /// <summary>
        /// Remove all the objects from the cache.
        /// </summary>
        /// <returns>All the objects that were in the cache.</returns>
        internal List <PacketInfoData> Drain()
        {
            // if neither there,we did not cache at all
            if (_frontEndQueue == null && _groupQueue == null)
            {
                return(null);
            }

            List <PacketInfoData> retVal = new List <PacketInfoData>();

            if (_frontEndQueue != null)
            {
                if (_groupQueue == null)
                {
                    // drain the front queue and return the data
                    while (_frontEndQueue.Count > 0)
                    {
                        retVal.Add(_frontEndQueue.Dequeue());
                    }

                    return(retVal);
                }

                // move from the front to the back queue
                while (_frontEndQueue.Count > 0)
                {
                    List <PacketInfoData> groupQueueOut = _groupQueue.Add(_frontEndQueue.Dequeue());

                    if (groupQueueOut != null)
                    {
                        foreach (PacketInfoData x in groupQueueOut)
                        {
                            retVal.Add(x);
                        }
                    }
                }
            }

            // drain the back queue
            while (true)
            {
                PacketInfoData obj = _groupQueue.Dequeue();

                if (obj == null)
                {
                    break;
                }

                retVal.Add(obj);
            }

            return(retVal);
        }
Example #2
0
        private void UpdateObjectCount(PacketInfoData o)
        {
            // add only of it's not a control message
            // and it's not out of band
            FormatEntryData fed = o as FormatEntryData;

            if (fed == null || fed.outOfBand)
            {
                return;
            }

            _currentObjectCount++;
        }
Example #3
0
        /// <summary>
        /// Add an object to the cache. the behavior depends on the object added, the
        /// objects already in the cache and the cache settings.
        /// </summary>
        /// <param name="o">Object to add.</param>
        /// <returns>List of objects the cache is flushing.</returns>
        internal List <PacketInfoData> Add(PacketInfoData o)
        {
            // if neither there, pass thru
            if (_frontEndQueue == null && _groupQueue == null)
            {
                List <PacketInfoData> retVal = new List <PacketInfoData>();
                retVal.Add(o);
                return(retVal);
            }

            // if front present, add to front
            if (_frontEndQueue != null)
            {
                _frontEndQueue.Enqueue(o);
                return(null);
            }

            // if back only, add to back
            return(_groupQueue.Add(o));
        }
Example #4
0
        /// <summary>
        /// Add an object to the cache.
        /// </summary>
        /// <param name="o">Object to add.</param>
        /// <returns>Objects the cache needs to return. It can be null.</returns>
        internal List <PacketInfoData> Add(PacketInfoData o)
        {
            FormatStartData fsd = o as FormatStartData;

            if (fsd != null)
            {
                // just cache the reference (used during the notification call)
                _formatStartData = fsd;
            }

            UpdateObjectCount(o);

            // STATE TRANSITION: we are not processing and we start
            if (!_processingGroup && (o is GroupStartData))
            {
                // just set the flag and start caching
                _processingGroup    = true;
                _currentObjectCount = 0;

                if (_groupingDuration > TimeSpan.MinValue)
                {
                    _groupingTimer = Stopwatch.StartNew();
                }

                _queue.Enqueue(o);
                return(null);
            }

            // STATE TRANSITION: we are processing and we stop
            if (_processingGroup &&
                ((o is GroupEndData) ||
                 (_objectCount > 0) && (_currentObjectCount >= _objectCount)) ||
                ((_groupingTimer != null) && (_groupingTimer.Elapsed > _groupingDuration))
                )
            {
                // reset the object count
                _currentObjectCount = 0;

                if (_groupingTimer != null)
                {
                    _groupingTimer.Stop();
                    _groupingTimer = null;
                }

                // add object to queue, to be picked up
                _queue.Enqueue(o);

                // we are at the end of a group, drain the queue
                Notify();
                _processingGroup = false;

                List <PacketInfoData> retVal = new List <PacketInfoData>();

                while (_queue.Count > 0)
                {
                    retVal.Add(_queue.Dequeue());
                }

                return(retVal);
            }

            // NO STATE TRANSITION: check the state we are in
            if (_processingGroup)
            {
                // we are in the caching state
                _queue.Enqueue(o);
                return(null);
            }

            // we are not processing, so just return it
            List <PacketInfoData> ret = new List <PacketInfoData>();

            ret.Add(o);
            return(ret);
        }
        /// <summary>
        /// Process an object from an input stream. It manages the context stack and
        /// calls back on the specified event delegates.
        /// </summary>
        /// <param name="o">Object to process.</param>
        internal void Process(object o)
        {
            PacketInfoData  formatData = o as PacketInfoData;
            FormatEntryData fed        = formatData as FormatEntryData;

            if (fed != null)
            {
                OutputContext ctx = null;

                if (!fed.outOfBand)
                {
                    ctx = _stack.Peek();
                }
                //  notify for Payload
                this.payload(fed, ctx);
            }
            else
            {
                bool formatDataIsFormatStartData = formatData is FormatStartData;
                bool formatDataIsGroupStartData  = formatData is GroupStartData;
                // it's one of our formatting messages
                // we assume for the moment that they are in the correct sequence
                if (formatDataIsFormatStartData || formatDataIsGroupStartData)
                {
                    OutputContext oc = this.contextCreation(this.ActiveOutputContext, formatData);
                    _stack.Push(oc);

                    // now we have the context properly set: need to notify the
                    // underlying algorithm to do the start document or group stuff
                    if (formatDataIsFormatStartData)
                    {
                        // notify for Fs
                        this.fs(oc);
                    }
                    else if (formatDataIsGroupStartData)
                    {
                        // GroupStartData gsd = (GroupStartData) formatData;
                        // notify for Gs
                        this.gs(oc);
                    }
                }
                else
                {
                    GroupEndData  ged   = formatData as GroupEndData;
                    FormatEndData fEndd = formatData as FormatEndData;
                    if (ged != null || fEndd != null)
                    {
                        OutputContext oc = _stack.Peek();
                        if (fEndd != null)
                        {
                            // notify for Fe, passing the Fe info, before a Pop()
                            this.fe(fEndd, oc);
                        }
                        else if (ged != null)
                        {
                            // notify for Fe, passing the Fe info, before a Pop()
                            this.ge(ged, oc);
                        }

                        _stack.Pop();
                    }
                }
            }
        }