Beispiel #1
0
        }                                                  // IteratorState: Create.

        public bool MoveNext()
        {
            try
            {
                switch (this.State)
                {
                case IteratorState.Start:
                    this.start();
                    this.State = IteratorState.MoveNext;     // IteratorState: Start => MoveNext.
                    goto case IteratorState.MoveNext;

                case IteratorState.MoveNext:
                    if (this.moveNext())
                    {
                        this.Current = this.getCurrent();
                        return(true);    // IteratorState: MoveNext => MoveNext.
                    }

                    this.State = IteratorState.End;     // IteratorState: MoveNext => End.
                    this.dispose();
                    this.end();
                    return(false);

                default:
                    return(false);
                }
            }
            catch // IteratorState: Start, MoveNext, End => End.
            {
                this.State = IteratorState.Error;
                this.Dispose();
                throw;
            }
        }
Beispiel #2
0
            // TODO: Ensure that the state methods work
            private bool moveOnOnlineState()
            {
                m_currentIndex -= 1;
                if (m_currentIndex < 0)
                {
                    saveMessages(new List <FacebookMessage>(m_messageList));
                    m_saveCount += m_messageList.Count;
                    getNextOnlineMessages();
                    m_currentIndex = m_messageList.Count - 1;
                }
                else if (m_cachedMessageList.Count > 0 && m_messageList[m_currentIndex] == m_cachedMessageList[m_cacheIndex])
                {
                    if (m_currentIndex != m_messageList.Count - 1)
                    {
                        m_messageList.RemoveRange(0, m_currentIndex + 1);
                        saveMessages(new List <FacebookMessage>(m_messageList));
                    }
                    m_state        = IteratorState.CacheQuery;
                    m_messageList  = m_cachedMessageList;
                    m_currentIndex = m_cacheIndex;
                }

                if (m_messageList == null || m_messageList.Count == 0)
                {
                    return(false);
                }
                return(true);
            }
Beispiel #3
0
        /// <summary>
        /// Position this iterator to the next node in the union.
        /// </summary>
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator)
        {
            switch (_state)
            {
            case IteratorState.InitLeft:
                // Fetched node from left iterator, now get initial node from right iterator
                _navLeft = nestedNavigator;
                _state   = IteratorState.NeedRight;
                return(SetIteratorResult.InitRightIterator);

            case IteratorState.NeedLeft:
                _navLeft = nestedNavigator;
                break;

            case IteratorState.NeedRight:
                _navRight = nestedNavigator;
                break;

            case IteratorState.NeedLeftAndRight:
                // After fetching left node, still need right node
                _navLeft = nestedNavigator;
                _state   = IteratorState.NeedRight;
                return(SetIteratorResult.NeedRightNode);

            case IteratorState.HaveCurrent:
                // Just returned left node as current, so fetch new left node
                Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned.");
                _state = IteratorState.NeedLeft;
                return(SetIteratorResult.NeedLeftNode);
            }

            if (_navLeft == null)
            {
                // If navLeft is null, then difference operation is complete
                return(SetIteratorResult.NoMoreNodes);
            }
            else if (_navRight != null)
            {
                int order = _runtime.ComparePosition(_navLeft, _navRight);

                // If navLeft is positioned to same node as navRight,
                if (order == 0)
                {
                    // Skip navLeft and navRight
                    _state = IteratorState.NeedLeftAndRight;
                    return(SetIteratorResult.NeedLeftNode);
                }

                // If navLeft is after navRight in document order, then skip navRight
                if (order > 0)
                {
                    _state = IteratorState.NeedRight;
                    return(SetIteratorResult.NeedRightNode);
                }
            }

            // Return navLeft
            _state = IteratorState.HaveCurrent;
            return(SetIteratorResult.HaveCurrentNode);
        }
Beispiel #4
0
        public bool MoveNext()
        {
            try
            {
                switch (this.State)
                {
                case IteratorState.Start:
                    this.start?.Invoke();
                    this.State = IteratorState.MoveNext;     // IteratorState: Start => MoveNext.
                    goto case IteratorState.MoveNext;

                case IteratorState.MoveNext:
                    if (this.moveNext?.Invoke() ?? false)
                    {
                        this.Current = this.getCurrent != null?this.getCurrent() : default;

                        return(true);               // IteratorState: MoveNext => MoveNext.
                    }
                    this.State = IteratorState.End; // IteratorState: MoveNext => End.
                    this.dispose?.Invoke();
                    this.end?.Invoke();
                    break;
                }
                return(false);
            }
            catch
            {
                this.State = IteratorState.Error; // IteratorState: Start, MoveNext, End => Error.
                this.Dispose();
                throw;
            }
        }
        /// <summary>
        /// Position this iterator to the next following node.  Return false if there are no more following nodes,
        /// or if the end node has been reached.  Return true if the Current property is set to the next node in
        /// the iteration.
        /// </summary>
        public bool MoveNext()
        {
            switch (this.state)
            {
            case IteratorState.HaveCurrent:
                this.state = IteratorState.NeedCurrent;
                return(true);

            case IteratorState.NeedCurrent:
                // Move to next following node which matches
                if (!this.filter.MoveToFollowing(this.navCurrent, this.navEnd))
                {
                    // No more nodes unless ending node matches
                    if (filter.IsFiltered(this.navEnd))
                    {
                        this.state = IteratorState.NoNext;
                        return(false);
                    }

                    this.navCurrent.MoveTo(this.navEnd);
                    this.state = IteratorState.NoNext;
                }
                return(true);

            case IteratorState.HaveCurrentNoNext:
                this.state = IteratorState.NoNext;
                return(true);
            }

            Debug.Assert(this.state == IteratorState.NoNext, "Illegal state: " + this.state);
            return(false);
        }
Beispiel #6
0
 private bool moveOnCacheState()
 {
     m_currentIndex--;
     m_cacheIndex--;
     if (m_currentIndex < 0)
     {
         // This should only occur if the cached messages contain all messages up to the initial messsage
         return(false);
     }
     if (m_queryLinks.ContainsKey(m_messageList[m_currentIndex].id))
     {
         lock (this)
         {
             m_queryLinks = CachedMessageManager.Manager.getNextURLs(m_conversationID);
             if (m_queryLinks.ContainsKey(m_messageList[m_currentIndex].id))
             {
                 m_state = IteratorState.RemnantQuery;
                 FBQueryManager.Manager.setNextURL(m_conversationID, m_queryLinks[m_messageList[m_currentIndex].id]);
                 // TODO: Check transition correctness from using cached messages vs. online facebook servers
                 m_cacheIndex  = m_currentIndex;
                 m_messageList = new List <FacebookMessage>();
                 m_messageList.Add(m_cachedMessageList[m_currentIndex]);
                 m_currentIndex = 0;
             }
             else
             {
                 FacebookMessage message = m_cachedMessageList[m_cacheIndex];
                 m_messageList  = m_cachedMessageList = CachedMessageManager.Manager.getMessages(m_conversationID);
                 m_currentIndex = m_cacheIndex = m_cachedMessageList.BinarySearch(message);
             }
         }
     }
     return(true);
 }
        /// <summary>
        /// Position this iterator to the next node in the union.
        /// </summary>
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator) {
            switch (this.state) {
                case IteratorState.InitLeft:
                    // Fetched node from left iterator, now get initial node from right iterator
                    this.navOther = nestedNavigator;
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft:
                    this.navCurr = nestedNavigator;
                    this.state = IteratorState.LeftIsCurrent;
                    break;

                case IteratorState.NeedRight:
                    this.navCurr = nestedNavigator;
                    this.state = IteratorState.RightIsCurrent;
                    break;

                case IteratorState.LeftIsCurrent:
                    // Just returned left node as current, so get new left
                    this.state = IteratorState.NeedLeft;
                    return SetIteratorResult.NeedLeftNode;

                case IteratorState.RightIsCurrent:
                    // Just returned right node as current, so get new right
                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode;
            }

            // Merge left and right nodes
            if (this.navCurr == null) {
                // If both navCurr and navOther are null, then iteration is complete
                if (this.navOther == null)
                    return SetIteratorResult.NoMoreNodes;

                Swap();
            }
            else if (this.navOther != null) {
                int order = this.runtime.ComparePosition(this.navOther, this.navCurr);

                // If navCurr is positioned to same node as navOther,
                if (order == 0) {
                    // Skip navCurr, since it is a duplicate
                    if (this.state == IteratorState.LeftIsCurrent) {
                        this.state = IteratorState.NeedLeft;
                        return SetIteratorResult.NeedLeftNode;
                    }

                    this.state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode;
                }

                // If navOther is before navCurr in document order, then swap navCurr with navOther
                if (order < 0)
                    Swap();
            }

            // Return navCurr
            return SetIteratorResult.HaveCurrentNode;
        }
Beispiel #8
0
        /// <summary>
        /// If the context node-set returns a node that is contained in the subtree of the previous node,
        /// then returning children of each node in "natural" order may not correspond to document order.
        /// Therefore, in order to guarantee document order, keep a stack in order to push the sibling of
        /// ancestor nodes.  These siblings will not be returned until all of the descendants' children are
        /// returned first.
        /// </summary>
        private IteratorResult DocOrderMerge()
        {
            XmlNodeOrder cmp;

            Debug.Assert(_state == IteratorState.HaveCurrentHaveNext);

            // Compare location of navCurrent with navNext
            cmp = _navCurrent.ComparePosition(_navNext);

            // If navCurrent is before navNext in document order,
            // If cmp = XmlNodeOrder.Unknown, then navCurrent is before navNext (since input is is doc order)
            if (cmp == XmlNodeOrder.Before || cmp == XmlNodeOrder.Unknown)
            {
                // Then navCurrent can be returned (it is guaranteed to be first in document order)
                return(IteratorResult.HaveCurrentNode);
            }

            // If navCurrent is after navNext in document order, then delay returning navCurrent
            // Otherwise, discard navNext since it is positioned to the same node as navCurrent
            if (cmp == XmlNodeOrder.After)
            {
                _navStack.Push(_navCurrent);
                _navCurrent = _navNext;
                _navNext    = null;
            }

            // Need next input node
            _state = IteratorState.HaveCurrentNeedNext;
            return(IteratorResult.NeedInputNode);
        }
Beispiel #9
0
        public bool MoveNext()
        {
            switch (_state)
            {
            case IteratorState.HaveCurrent:
                _state = IteratorState.NeedCurrent;
                return(true);

            case IteratorState.NeedCurrent:
                // Move to next following node which matches
                if (!_filter.MoveToFollowing(_navCurrent, _navEnd))
                {
                    // No more nodes unless ending node matches
                    if (_filter.IsFiltered(_navEnd))
                    {
                        _state = IteratorState.NoNext;
                        return(false);
                    }

                    _navCurrent.MoveTo(_navEnd);
                    _state = IteratorState.NoNext;
                }
                return(true);

            case IteratorState.HaveCurrentNoNext:
                _state = IteratorState.NoNext;
                return(true);
            }

            Debug.Assert(_state == IteratorState.NoNext, "Illegal state: " + _state);
            return(false);
        }
        private static void Cleanup(IteratorState[] iterators)
        {
            if (iterators != null)
            {
                List <Exception> errors = null;

                for (int i = 0; i < iterators.Length; i++)
                {
                    if (iterators[i].Active && iterators[i].Iterator != null)
                    {
                        try
                        {
                            var iterator = iterators[i].Iterator;
                            iterators[i] = new IteratorState();
                            iterator.Dispose();
                        }
                        catch (Exception e)
                        {
                            (errors ?? (errors = new List <Exception>())).Add(e);
                        }
                    }
                }

                if (errors != null)
                {
                    throw new AggregateException(errors);
                }
            }
        }
 private void Exclude(IteratorState state)
 {
     if (!_withThis)
         state.This = null;
     if (!_withCurrent)
         state.Current = null;
 }
Beispiel #12
0
        /// <summary>
        /// Position this iterator to the next node in the union.
        /// </summary>
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator)
        {
            int order;

            switch (_state)
            {
            case IteratorState.InitLeft:
                // Fetched node from left iterator, now get initial node from right iterator
                _navLeft = nestedNavigator;
                _state   = IteratorState.NeedRight;
                return(SetIteratorResult.InitRightIterator);

            case IteratorState.NeedLeft:
                _navLeft = nestedNavigator;
                break;

            case IteratorState.NeedRight:
                _navRight = nestedNavigator;
                break;

            case IteratorState.NeedLeftAndRight:
                // After fetching left node, still need right node
                _navLeft = nestedNavigator;
                _state   = IteratorState.NeedRight;
                return(SetIteratorResult.NeedRightNode);

            case IteratorState.HaveCurrent:
                // Just returned left node as current, so fetch new left and right nodes
                Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned.");
                _state = IteratorState.NeedLeftAndRight;
                return(SetIteratorResult.NeedLeftNode);
            }

            if (_navLeft == null || _navRight == null)
            {
                // No more nodes from either left or right iterator (or both), so iteration is complete
                return(SetIteratorResult.NoMoreNodes);
            }

            // Intersect left and right sets
            order = _runtime.ComparePosition(_navLeft, _navRight);

            if (order < 0)
            {
                // If navLeft is positioned to a node that is before navRight, skip left node
                _state = IteratorState.NeedLeft;
                return(SetIteratorResult.NeedLeftNode);
            }
            else if (order > 0)
            {
                // If navLeft is positioned to a node that is after navRight, so skip right node
                _state = IteratorState.NeedRight;
                return(SetIteratorResult.NeedRightNode);
            }

            // Otherwise, navLeft is positioned to the same node as navRight, so found one item in the intersection
            _state = IteratorState.HaveCurrent;
            return(SetIteratorResult.HaveCurrentNode);
        }
Beispiel #13
0
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            IteratorState state = _isc.ToState((IEnumerator)value);

            Exclude(state);

            serializer.Serialize(writer, state);
        }
Beispiel #14
0
 /// <summary>
 /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
 /// </summary>
 /// <param name="disposing">是否释放托管资源。</param>
 protected virtual void Dispose(bool disposing)
 {
     if (this.state == IteratorState.Disposed || !disposing)
     {
         return;
     }
     this.state   = IteratorState.Disposed;
     this.Current = default(T);
 }
Beispiel #15
0
 private void Exclude(IteratorState state)
 {
     if (!_withThis)
     {
         state.This = null;
     }
     if (!_withCurrent)
     {
         state.Current = null;
     }
 }
Beispiel #16
0
 // TODO: Consider removing this state...
 private bool moveOnRemnantState()
 {
     m_currentIndex -= 1;
     if (m_currentIndex < 0)
     {
         getNextOnlineMessages();
         m_currentIndex = m_messageList.Count - 1;
         m_state        = IteratorState.OnlineQuery;
         return(m_messageList.Count > 0);
     }
     return(true);
 }
Beispiel #17
0
        /// <summary>
        ///     Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        ///     A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.
        /// </returns>
        public IEnumerator <TSource> GetEnumerator( )
        {
            if ((_threadId == Thread.CurrentThread.ManagedThreadId) && (State == IteratorState.Uninitialized))
            {
                State = IteratorState.Initialized;
                return(this);
            }

            Iterator <TSource> iterator = Clone( );

            iterator.State = IteratorState.Initialized;
            return(iterator);
        }
Beispiel #18
0
 public void Dispose()
 {
     if (this.State == IteratorState.Error || this.State == IteratorState.MoveNext)
     {
         try { }
         finally
         {
             // Unexecuted finally blocks are executed before the thread is aborted.
             this.State = IteratorState.End; // IteratorState: Error => End.
             this.dispose?.Invoke();
         }
     }
 }
Beispiel #19
0
        /// <summary>
        /// 返回一个循环访问集合的枚举器。
        /// </summary>
        /// <returns>可用于循环访问集合的 <see cref="IEnumerator{T}"/>。</returns>
        public IEnumerator <T> GetEnumerator()
        {
            if (this.threadId == Thread.CurrentThread.ManagedThreadId &&
                this.state == IteratorState.Default)
            {
                this.state = IteratorState.Ready;
                return(this);
            }
            IteratorBase <T> iterator = Clone();

            Debug.Assert(iterator != null);
            iterator.state = IteratorState.Ready;
            return(iterator);
        }
Beispiel #20
0
 public void Dispose()
 {
     if (this.state == IteratorState.Error || this.state == IteratorState.MoveNext)
     {
         try { }
         finally
         {
             // https://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
             // Unexecuted finally blocks are executed before the thread is aborted.
             this.state = IteratorState.End; // IteratorState: Error => End.
             this.dispose(this.data);
         }
     }
 }
        protected override async ValueTask <bool> OnFirstAsync()
        {
            if (m_remaining != null && m_remaining.Value < 0)
            {             // empty list ??
                return(await Completed());
            }

            // even if the caller only wants the first, we will probably need to read more than that...
            var mode = m_mode;

            if (mode == AsyncIterationHint.Head)
            {
                mode = AsyncIterationHint.Iterator;
            }

            var sources = m_sources.ToArray();

            IteratorState[]? iterators = new IteratorState[sources.Length];
            try
            {
                // start all the iterators
                for (int i = 0; i < sources.Length; i++)
                {
                    var state = new IteratorState
                    {
                        Active   = true,
                        Iterator = sources[i] is IConfigurableAsyncEnumerable <TSource> configurable?configurable.GetAsyncEnumerator(m_ct, mode) : sources[i].GetAsyncEnumerator(m_ct)
                    };
                    state.Next = state.Iterator.MoveNextAsync();

                    iterators[i] = state;
                }

                m_remaining = m_limit;
                return(iterators.Length > 0);
            }
            catch (Exception)
            {
                // dispose already opened iterators
                var tmp = iterators;
                iterators = null;
                try { await Cleanup(tmp); } catch { }
                throw;
            }
            finally
            {
                m_iterators = iterators;
            }
        }
Beispiel #22
0
        protected override Task <bool> OnFirstAsync()
        {
            if (m_remaining != null && m_remaining.Value < 0)
            {             // empty list ??
                return(TaskHelpers.FromResult(Completed()));
            }

            // even if the caller only wants the first, we will probably need to read more than that...
            var mode = m_mode;

            if (mode == AsyncIterationHint.Head)
            {
                mode = AsyncIterationHint.Iterator;
            }

            var sources   = m_sources.ToArray();
            var iterators = new IteratorState[sources.Length];

            try
            {
                // start all the iterators
                for (int i = 0; i < sources.Length; i++)
                {
                    var state = new IteratorState
                    {
                        Active   = true,
                        Iterator = sources[i].GetEnumerator(m_ct, mode)
                    };
                    state.Next = state.Iterator.MoveNextAsync();

                    iterators[i] = state;
                }

                m_remaining = m_limit;
                return(TaskHelpers.FromResult(iterators.Length > 0));
            }
            catch (Exception e)
            {
                // dispose already opened iterators
                var tmp = iterators;
                iterators = null;
                try { Cleanup(tmp); } catch { }
                return(Task.FromException <bool>(e));
            }
            finally
            {
                m_iterators = iterators;
            }
        }
Beispiel #23
0
 public Iterator(
     IteratorState state  = IteratorState.Create,
     Action start         = null,
     Func <bool> moveNext = null,
     Func <T> getCurrent  = null,
     Action dispose       = null,
     Action end           = null)
 {
     this.State      = state;
     this.start      = start ?? (() => { });
     this.moveNext   = moveNext ?? (() => false);
     this.getCurrent = getCurrent ?? (() => default(T));
     this.dispose    = dispose ?? (() => { });
     this.end        = end ?? (() => { });
 }
Beispiel #24
0
        /// <summary>
        /// Swap navCurr with navOther and invert state to reflect the change.
        /// </summary>
        private void Swap()
        {
            XPathNavigator navTemp = _navCurr;

            _navCurr  = _navOther;
            _navOther = navTemp;

            if (_state == IteratorState.LeftIsCurrent)
            {
                _state = IteratorState.RightIsCurrent;
            }
            else
            {
                _state = IteratorState.LeftIsCurrent;
            }
        }
Beispiel #25
0
        /// <summary>
        /// Swap navCurr with navOther and invert state to reflect the change.
        /// </summary>
        private void Swap()
        {
            XPathNavigator navTemp = this.navCurr;

            this.navCurr  = this.navOther;
            this.navOther = navTemp;

            if (this.state == IteratorState.LeftIsCurrent)
            {
                this.state = IteratorState.RightIsCurrent;
            }
            else
            {
                this.state = IteratorState.LeftIsCurrent;
            }
        }
Beispiel #26
0
            private void constructorHelper(string conversationID, bool saveMessages)
            {
                m_conversationID = conversationID;
                m_saveCount      = 0;
                m_saveMessages   = saveMessages;

                CachedMessageManager.Manager.addConversation(conversationID);

                m_cachedMessageList = CachedMessageManager.Manager.getMessages(conversationID);
                getNextOnlineMessages();
                m_queryLinks   = CachedMessageManager.Manager.getNextURLs(conversationID);
                m_currentIndex = m_messageList.Count;
                m_cacheIndex   = m_cachedMessageList.Count - 1;

                m_state = IteratorState.OnlineQuery;
            }
Beispiel #27
0
        public void Create(XPathNavigator start, XmlNavigatorFilter filter, XPathNavigator end)
        {
            // Save start node as current node and save ending node
            _navCurrent = XmlQueryRuntime.SyncToNavigator(_navCurrent, start);
            _navEnd     = XmlQueryRuntime.SyncToNavigator(_navEnd, end);
            _filter     = filter;

            if (start.IsSamePosition(end))
            {
                // Start is end, so only return node if it is not filtered
                _state = !filter.IsFiltered(start) ? IteratorState.HaveCurrentNoNext : IteratorState.NoNext;
            }
            else
            {
                // Return nodes until end is reached
                _state = !filter.IsFiltered(start) ? IteratorState.HaveCurrent : IteratorState.NeedCurrent;
            }
        }
        public void StaticYieldOnly()
        {
            var serializer = new IteratorStateConverter();

            IEnumerator <int> iterator = SerializationCoroutines.StaticYieldOnly().GetEnumerator();

            iterator.MoveNext();

            IteratorState state1 = serializer.ToState(iterator);

            Assert.True((int)state1.Current == 1);

            iterator.MoveNext();

            IteratorState state2 = serializer.ToState(iterator);

            Assert.True((int)state2.Current == 2);
        }
Beispiel #29
0
        public IteratorResult MoveNext(XPathNavigator input)
        {
            if (_state != IteratorState.NeedDescendant)
            {
                if (input == null)
                {
                    return(IteratorResult.NoMoreNodes);
                }

                // Descendants of the input node will be duplicates if the input node is in the subtree
                // of the previous root.
                if (_state != IteratorState.NoPrevious && _navRoot.IsDescendant(input))
                {
                    return(IteratorResult.NeedInputNode);
                }

                // Save input node as current node and end of input's tree in navEnd
                _navCurrent = XmlQueryRuntime.SyncToNavigator(_navCurrent, input);
                _navRoot    = XmlQueryRuntime.SyncToNavigator(_navRoot, input);
                _navEnd     = XmlQueryRuntime.SyncToNavigator(_navEnd, input);
                _navEnd.MoveToNonDescendant();

                _state = IteratorState.NeedDescendant;

                // If self node matches, then return it
                if (_orSelf && !_filter.IsFiltered(input))
                {
                    return(IteratorResult.HaveCurrentNode);
                }
            }

            if (_filter.MoveToFollowing(_navCurrent, _navEnd))
            {
                return(IteratorResult.HaveCurrentNode);
            }

            // No more descendants, so transition to NeedCurrent state and get the next input node
            _state = IteratorState.NeedCurrent;
            return(IteratorResult.NeedInputNode);
        }
        public void StaticYieldWithVarAndArg()
        {
            var serializer = new IteratorStateConverter();

            IEnumerator <int> iterator = SerializationCoroutines.StaticYieldWithVarAndArg(5).GetEnumerator();

            iterator.MoveNext();

            IteratorState state1 = serializer.ToState(iterator);

            Assert.True((int)state1.Current == 5);

            iterator.MoveNext();

            IteratorState state2 = serializer.ToState(iterator);

            Assert.True((int)state2.Current == 15);

            var newIterator = (IEnumerator <int>)serializer.FromState(state2);

            Assert.True(newIterator.Current == 15);
        }
Beispiel #31
0
        private IteratorResult MoveFailed()
        {
            XPathNavigator navTemp;

            Debug.Assert(_state == IteratorState.HaveCurrentHaveNext || _state == IteratorState.HaveCurrentNoNext);

            if (_state == IteratorState.HaveCurrentNoNext)
            {
                // No more nodes, so iteration is complete
                _state = IteratorState.NeedCandidateCurrent;
                return(IteratorResult.NoMoreNodes);
            }

            // Make next node the new candidate node
            _state = IteratorState.HaveCandidateCurrent;

            // Swap navigators in order to sometimes avoid creating clones
            navTemp     = _navCurrent;
            _navCurrent = _navNext;
            _navNext    = navTemp;

            return(IteratorResult.NeedInputNode);
        }
        /// <summary>
        /// Position this iterator to the next descendant node.  Return IteratorResult.NoMoreNodes if there are no more
        /// descendant nodes.  Return IteratorResult.NeedInputNode if the next input node needs to be fetched.
        /// Return IteratorResult.HaveCurrent if the Current property is set to the next node in the iteration.
        /// </summary>
        public IteratorResult MoveNext(XPathNavigator input) {
            if (this.state != IteratorState.NeedDescendant) {
                if (input == null)
                    return IteratorResult.NoMoreNodes;

                // Descendants of the input node will be duplicates if the input node is in the subtree
                // of the previous root.
                if (this.state != IteratorState.NoPrevious && this.navRoot.IsDescendant(input))
                    return IteratorResult.NeedInputNode;

                // Save input node as current node and end of input's tree in navEnd
                this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, input);
                this.navRoot = XmlQueryRuntime.SyncToNavigator(this.navRoot, input);
                this.navEnd = XmlQueryRuntime.SyncToNavigator(this.navEnd, input);
                this.navEnd.MoveToNonDescendant();

                this.state = IteratorState.NeedDescendant;

                // If self node matches, then return it
                if (this.orSelf && !this.filter.IsFiltered(input))
                    return IteratorResult.HaveCurrentNode;
            }

            if (this.filter.MoveToFollowing(this.navCurrent, this.navEnd))
                return IteratorResult.HaveCurrentNode;

            // No more descendants, so transition to NeedCurrent state and get the next input node
            this.state = IteratorState.NeedCurrent;
            return IteratorResult.NeedInputNode;
        }
Beispiel #33
0
        /// <summary>
        /// Position this iterator to the next following node.  Return false if there are no more following nodes,
        /// or if the end node has been reached.  Return true if the Current property is set to the next node in
        /// the iteration.
        /// </summary>
        public bool MoveNext()
        {
            switch (_state)
            {
                case IteratorState.HaveCurrent:
                    _state = IteratorState.NeedCurrent;
                    return true;

                case IteratorState.NeedCurrent:
                    // Move to next following node which matches
                    if (!_filter.MoveToFollowing(_navCurrent, _navEnd))
                    {
                        // No more nodes unless ending node matches
                        if (_filter.IsFiltered(_navEnd))
                        {
                            _state = IteratorState.NoNext;
                            return false;
                        }

                        _navCurrent.MoveTo(_navEnd);
                        _state = IteratorState.NoNext;
                    }
                    return true;

                case IteratorState.HaveCurrentNoNext:
                    _state = IteratorState.NoNext;
                    return true;
            }

            Debug.Assert(_state == IteratorState.NoNext, "Illegal state: " + _state);
            return false;
        }
Beispiel #34
0
 /// <summary>
 /// Initialize the DescendantIterator (merge multiple sets of descendant nodes in document order and remove duplicates).
 /// </summary>
 public void Create(XmlNavigatorFilter filter, bool orSelf)
 {
     _filter = filter;
     _state = IteratorState.NoPrevious;
     _orSelf = orSelf;
 }
Beispiel #35
0
 /// <summary>
 /// Initialize the ContentMergeIterator (merge multiple sets of content nodes in document order and remove duplicates).
 /// </summary>
 public void Create(XmlNavigatorFilter filter) {
     this.filter = filter;
     this.navStack.Reset();
     this.state = IteratorState.NeedCurrent;
 }
Beispiel #36
0
        /// <summary>
        /// Position this iterator to the next content or sibling node.  Return IteratorResult.NoMoreNodes if there are
        /// no more content or sibling nodes.  Return IteratorResult.NeedInputNode if the next input node needs to be
        /// fetched first.  Return IteratorResult.HaveCurrent if the Current property is set to the next node in the
        /// iteration.
        /// </summary>
        internal IteratorResult MoveNext(XPathNavigator input, bool isContent) {
            switch (this.state) {
                case IteratorState.NeedCurrent:
                    // If there are no more input nodes, then iteration is complete
                    if (input == null)
                        return IteratorResult.NoMoreNodes;

                    // Save the input node as the current node
                    this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, input);

                    // If matching child or sibling is found, then we have a current node
                    if (isContent ? this.filter.MoveToContent(this.navCurrent) :
                                    this.filter.MoveToFollowingSibling(this.navCurrent))
                        this.state = IteratorState.HaveCurrentNeedNext;

                    return IteratorResult.NeedInputNode;

                case IteratorState.HaveCurrentNeedNext:
                    if (input == null) {
                        // There are no more input nodes, so enter HaveCurrentNoNext state and return Current
                        this.state = IteratorState.HaveCurrentNoNext;
                        return IteratorResult.HaveCurrentNode;
                    }

                    // Save the input node as the next node
                    this.navNext = XmlQueryRuntime.SyncToNavigator(this.navNext, input);

                    // If matching child or sibling is found,
                    if (isContent ? this.filter.MoveToContent(this.navNext) :
                                    this.filter.MoveToFollowingSibling(this.navNext)) {
                        // Then compare position of current and next nodes
                        this.state = IteratorState.HaveCurrentHaveNext;
                        return DocOrderMerge();
                    }

                    // Input node does not result in matching child or sibling, so get next input node
                    return IteratorResult.NeedInputNode;

                case IteratorState.HaveCurrentNoNext:
                case IteratorState.HaveCurrentHaveNext:
                    // If the current node has no more matching siblings,
                    if (isContent ? !this.filter.MoveToNextContent(this.navCurrent) :
                                    !this.filter.MoveToFollowingSibling(this.navCurrent)) {
                        if (this.navStack.IsEmpty) {
                            if (this.state == IteratorState.HaveCurrentNoNext) {
                                // No more input nodes, so iteration is complete
                                return IteratorResult.NoMoreNodes;
                            }

                            // Make navNext the new current node and fetch a new navNext
                            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, this.navNext);
                            this.state = IteratorState.HaveCurrentNeedNext;
                            return IteratorResult.NeedInputNode;
                        }

                        // Pop new current node from the stack
                        this.navCurrent = this.navStack.Pop();
                    }

                    // If there is no next node, then no need to call DocOrderMerge; just return the current node
                    if (this.state == IteratorState.HaveCurrentNoNext)
                        return IteratorResult.HaveCurrentNode;

                    // Compare positions of current and next nodes
                    return DocOrderMerge();
            }

            Debug.Assert(false, "Invalid IteratorState " + this.state);
            return IteratorResult.NoMoreNodes;
        }
        /// <summary>
        /// Swap navCurr with navOther and invert state to reflect the change.
        /// </summary>
        private void Swap() {
            XPathNavigator navTemp = this.navCurr;
            this.navCurr = this.navOther;
            this.navOther = navTemp;

            if (this.state == IteratorState.LeftIsCurrent)
                this.state = IteratorState.RightIsCurrent;
            else
                this.state = IteratorState.LeftIsCurrent;
        }
 /// <summary>
 /// Create SetIterator.
 /// </summary>
 public void Create(XmlQueryRuntime runtime) {
     this.runtime = runtime;
     this.state = IteratorState.InitLeft;
 }
Beispiel #39
0
 /// <summary>
 /// Initialize the ContentMergeIterator (merge multiple sets of content nodes in document order and remove duplicates).
 /// </summary>
 public void Create(XmlNavigatorFilter filter)
 {
     _filter = filter;
     _navStack.Reset();
     _state = IteratorState.NeedCurrent;
 }
Beispiel #40
0
 public void Create(XmlNavigatorFilter filter, bool orSelf)
 {
     _filter = filter;
     _state  = IteratorState.NoPrevious;
     _orSelf = orSelf;
 }
        /// <summary>
        /// Called when an attempt to move to a following node failed.  If a Next node exists, then make that the new
        /// candidate current node.  Otherwise, iteration is complete.
        /// </summary>
        private IteratorResult MoveFailed() {
            XPathNavigator navTemp;
            Debug.Assert(this.state == IteratorState.HaveCurrentHaveNext || this.state == IteratorState.HaveCurrentNoNext);

            if (this.state == IteratorState.HaveCurrentNoNext) {
                // No more nodes, so iteration is complete
                this.state = IteratorState.NeedCandidateCurrent;
                return IteratorResult.NoMoreNodes;
            }

            // Make next node the new candidate node
            this.state = IteratorState.HaveCandidateCurrent;

            // Swap navigators in order to sometimes avoid creating clones
            navTemp = this.navCurrent;
            this.navCurrent = this.navNext;
            this.navNext = navTemp;

            return IteratorResult.NeedInputNode;
        }
Beispiel #42
0
        /// <summary>
        /// If the context node-set returns a node that is contained in the subtree of the previous node,
        /// then returning children of each node in "natural" order may not correspond to document order.
        /// Therefore, in order to guarantee document order, keep a stack in order to push the sibling of
        /// ancestor nodes.  These siblings will not be returned until all of the descendants' children are
        /// returned first.
        /// </summary>
        private IteratorResult DocOrderMerge() {
            XmlNodeOrder cmp;
            Debug.Assert(this.state == IteratorState.HaveCurrentHaveNext);

            // Compare location of navCurrent with navNext
            cmp = this.navCurrent.ComparePosition(this.navNext);

            // If navCurrent is before navNext in document order,
            // If cmp = XmlNodeOrder.Unknown, then navCurrent is before navNext (since input is is doc order)
            if (cmp == XmlNodeOrder.Before || cmp == XmlNodeOrder.Unknown) {
                // Then navCurrent can be returned (it is guaranteed to be first in document order)
                return IteratorResult.HaveCurrentNode;
            }

            // If navCurrent is after navNext in document order, then delay returning navCurrent
            // Otherwise, discard navNext since it is positioned to the same node as navCurrent
            if (cmp == XmlNodeOrder.After) {
                this.navStack.Push(this.navCurrent);
                this.navCurrent = this.navNext;
                this.navNext = null;
            }

            // Need next input node
            this.state = IteratorState.HaveCurrentNeedNext;
            return IteratorResult.NeedInputNode;
        }
Beispiel #43
0
        /// <summary>
        /// Position this iterator to the next node in the union.
        /// </summary>
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator)
        {
            switch (_state)
            {
                case IteratorState.InitLeft:
                    // Fetched node from left iterator, now get initial node from right iterator
                    _navLeft = nestedNavigator;
                    _state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft:
                    _navLeft = nestedNavigator;
                    break;

                case IteratorState.NeedRight:
                    _navRight = nestedNavigator;
                    break;

                case IteratorState.NeedLeftAndRight:
                    // After fetching left node, still need right node
                    _navLeft = nestedNavigator;
                    _state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode;

                case IteratorState.HaveCurrent:
                    // Just returned left node as current, so fetch new left node
                    Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned.");
                    _state = IteratorState.NeedLeft;
                    return SetIteratorResult.NeedLeftNode;
            }

            if (_navLeft == null)
            {
                // If navLeft is null, then difference operation is complete
                return SetIteratorResult.NoMoreNodes;
            }
            else if (_navRight != null)
            {
                int order = _runtime.ComparePosition(_navLeft, _navRight);

                // If navLeft is positioned to same node as navRight,
                if (order == 0)
                {
                    // Skip navLeft and navRight
                    _state = IteratorState.NeedLeftAndRight;
                    return SetIteratorResult.NeedLeftNode;
                }

                // If navLeft is after navRight in document order, then skip navRight
                if (order > 0)
                {
                    _state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode;
                }
            }

            // Return navLeft
            _state = IteratorState.HaveCurrent;
            return SetIteratorResult.HaveCurrentNode;
        }
Beispiel #44
0
 /// <summary>
 /// Create SetIterator.
 /// </summary>
 public void Create(XmlQueryRuntime runtime)
 {
     _runtime = runtime;
     _state = IteratorState.InitLeft;
 }
        /// <summary>
        /// Position this iterator to the next following node.  Prune by finding the first input node in
        /// document order that has no other input nodes in its subtree.  All other input nodes should be
        /// discarded.  Return IteratorResult.NeedInputNode if the next input node needs to be fetched
        /// first.  Return IteratorResult.HaveCurrent if the Current property is set to the next node in the
        /// iteration.
        /// </summary>
        public IteratorResult MoveNext(XPathNavigator input) {
            switch (this.state) {
                case IteratorState.NeedCandidateCurrent:
                    // If there are no more input nodes, then iteration is complete
                    if (input == null)
                        return IteratorResult.NoMoreNodes;

                    // Save input node as current node
                    this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, input);

                    // Still must check next input node to see if is a descendant of this one
                    this.state = IteratorState.HaveCandidateCurrent;
                    return IteratorResult.NeedInputNode;

                case IteratorState.HaveCandidateCurrent:
                    // If there are no more input nodes,
                    if (input == null) {
                        // Then candidate node has been selected, and there are no further input nodes
                        this.state = IteratorState.HaveCurrentNoNext;
                        return MoveFirst();
                    }

                    // If input node is in the subtree of the candidate node, then use the input node instead
                    if (this.navCurrent.IsDescendant(input))
                        goto case IteratorState.NeedCandidateCurrent;

                    // Found node on which to perform following scan.  Now skip past all input nodes in the same document.
                    this.state = IteratorState.HaveCurrentNeedNext;
                    goto case IteratorState.HaveCurrentNeedNext;

                case IteratorState.HaveCurrentNeedNext:
                    // If there are no more input nodes,
                    if (input == null) {
                        // Then candidate node has been selected, and there are no further input nodes
                        this.state = IteratorState.HaveCurrentNoNext;
                        return MoveFirst();
                    }

                    // Skip input node unless it's in a different document than the node on which the following scan was performed
                    if (this.navCurrent.ComparePosition(input) != XmlNodeOrder.Unknown)
                        return IteratorResult.NeedInputNode;

                    // Next node is in a different document, so save it
                    this.navNext = XmlQueryRuntime.SyncToNavigator(this.navNext, input);
                    this.state = IteratorState.HaveCurrentHaveNext;
                    return MoveFirst();
            }

            if (!this.filter.MoveToFollowing(this.navCurrent, null))
                return MoveFailed();

            return IteratorResult.HaveCurrentNode;
        }
        /// <summary>
        /// Position this iterator to the next preceding node in document order.  Discard all input nodes
        /// that are followed by another input node in the same document.  This leaves one node per document from
        /// which the complete set of preceding nodes can be derived without possibility of duplicates.
        /// Return IteratorResult.NeedInputNode if the next input node needs to be fetched first.  Return
        /// IteratorResult.HaveCurrent if the Current property is set to the next node in the iteration.
        /// </summary>
        public IteratorResult MoveNext(XPathNavigator input) {
            switch (this.state) {
                case IteratorState.NeedCandidateCurrent:
                    // If there are no more input nodes, then iteration is complete
                    if (input == null)
                        return IteratorResult.NoMoreNodes;

                    // Save input node as current node
                    this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, input);

                    // Scan for additional input nodes within the same document (since they are after navCurrent in docorder)
                    this.state = IteratorState.HaveCandidateCurrent;
                    return IteratorResult.NeedInputNode;

                case IteratorState.HaveCandidateCurrent:
                    // If there are no more input nodes,
                    if (input == null) {
                        // Then candidate node has been selected, and there are no further input nodes
                        this.state = IteratorState.HaveCurrentNoNext;
                    }
                    else {
                        // If the input node is in the same document as the current node,
                        if (this.navCurrent.ComparePosition(input) != XmlNodeOrder.Unknown) {
                            // Then update the current node and get the next input node
                            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, input);
                            return IteratorResult.NeedInputNode;
                        }

                        // Save the input node as navNext
                        this.navNext = XmlQueryRuntime.SyncToNavigator(this.navNext, input);
                        this.state = IteratorState.HaveCurrentHaveNext;
                    }
                    PushAncestors();
                    break;
            }

            if (!this.navStack.IsEmpty) {
                while (true) {
                    // Move to the next matching node that is before the top node on the stack in document order
                    if (this.filter.MoveToFollowing(this.navCurrent, this.navStack.Peek()))
                        // Found match
                        return IteratorResult.HaveCurrentNode;

                    // Do not include ancestor nodes as part of the preceding axis
                    this.navCurrent.MoveTo(this.navStack.Pop());

                    // No more preceding matches possible
                    if (this.navStack.IsEmpty)
                        break;
                }
            }

            if (this.state == IteratorState.HaveCurrentNoNext) {
                // No more nodes, so iteration is complete
                this.state = IteratorState.NeedCandidateCurrent;
                return IteratorResult.NoMoreNodes;
            }

            // Make next node the current node and start trying to find input node greatest in docorder
            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, this.navNext);
            this.state = IteratorState.HaveCandidateCurrent;
            return IteratorResult.HaveCurrentNode;
        }
 /// <summary>
 /// Initialize the XPathPrecedingMergeIterator (merge multiple sets of preceding nodes in document order and remove duplicates).
 /// </summary>
 public void Create(XmlNavigatorFilter filter) {
     this.filter = filter;
     this.state = IteratorState.NeedCandidateCurrent;
 }
        /// <summary>
        /// Position this iterator to the next following node.  Return false if there are no more following nodes,
        /// or if the end node has been reached.  Return true if the Current property is set to the next node in
        /// the iteration.
        /// </summary>
        public bool MoveNext() {
            switch (this.state) {
                case IteratorState.HaveCurrent:
                    this.state = IteratorState.NeedCurrent;
                    return true;

                case IteratorState.NeedCurrent:
                    // Move to next following node which matches
                    if (!this.filter.MoveToFollowing(this.navCurrent, this.navEnd)) {
                        // No more nodes unless ending node matches
                        if (filter.IsFiltered(this.navEnd)) {
                            this.state = IteratorState.NoNext;
                            return false;
                        }

                        this.navCurrent.MoveTo(this.navEnd);
                        this.state = IteratorState.NoNext;
                    }
                    return true;

                case IteratorState.HaveCurrentNoNext:
                    this.state = IteratorState.NoNext;
                    return true;
            }

            Debug.Assert(this.state == IteratorState.NoNext, "Illegal state: " + this.state);
            return false;
        }
        /// <summary>
        /// Initialize the NodeRangeIterator (no possibility of duplicates).
        /// </summary>
        public void Create(XPathNavigator start, XmlNavigatorFilter filter, XPathNavigator end) {
            // Save start node as current node and save ending node
            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, start);
            this.navEnd = XmlQueryRuntime.SyncToNavigator(this.navEnd, end);
            this.filter = filter;

            if (start.IsSamePosition(end)) {
                // Start is end, so only return node if it is not filtered
                this.state = !filter.IsFiltered(start) ? IteratorState.HaveCurrentNoNext : IteratorState.NoNext;
            }
            else {
                // Return nodes until end is reached
                this.state = !filter.IsFiltered(start) ? IteratorState.HaveCurrent : IteratorState.NeedCurrent;
            }
        }
Beispiel #50
0
        /// <summary>
        /// Swap navCurr with navOther and invert state to reflect the change.
        /// </summary>
        private void Swap()
        {
            XPathNavigator navTemp = _navCurr;
            _navCurr = _navOther;
            _navOther = navTemp;

            if (_state == IteratorState.LeftIsCurrent)
                _state = IteratorState.RightIsCurrent;
            else
                _state = IteratorState.LeftIsCurrent;
        }
 /// <summary>
 /// Initialize the DescendantIterator (merge multiple sets of descendant nodes in document order and remove duplicates).
 /// </summary>
 public void Create(XmlNavigatorFilter filter, bool orSelf) {
     this.filter = filter;
     this.state = IteratorState.NoPrevious;
     this.orSelf = orSelf;
 }
Beispiel #52
0
        /// <summary>
        /// Position this iterator to the next node in the union.
        /// </summary>
        public SetIteratorResult MoveNext(XPathNavigator nestedNavigator)
        {
            int order;

            switch (_state)
            {
                case IteratorState.InitLeft:
                    // Fetched node from left iterator, now get initial node from right iterator
                    _navLeft = nestedNavigator;
                    _state = IteratorState.NeedRight;
                    return SetIteratorResult.InitRightIterator;

                case IteratorState.NeedLeft:
                    _navLeft = nestedNavigator;
                    break;

                case IteratorState.NeedRight:
                    _navRight = nestedNavigator;
                    break;

                case IteratorState.NeedLeftAndRight:
                    // After fetching left node, still need right node
                    _navLeft = nestedNavigator;
                    _state = IteratorState.NeedRight;
                    return SetIteratorResult.NeedRightNode;

                case IteratorState.HaveCurrent:
                    // Just returned left node as current, so fetch new left and right nodes
                    Debug.Assert(nestedNavigator == null, "null is passed to MoveNext after IteratorState.HaveCurrent has been returned.");
                    _state = IteratorState.NeedLeftAndRight;
                    return SetIteratorResult.NeedLeftNode;
            }

            if (_navLeft == null || _navRight == null)
            {
                // No more nodes from either left or right iterator (or both), so iteration is complete
                return SetIteratorResult.NoMoreNodes;
            }

            // Intersect left and right sets
            order = _runtime.ComparePosition(_navLeft, _navRight);

            if (order < 0)
            {
                // If navLeft is positioned to a node that is before navRight, skip left node
                _state = IteratorState.NeedLeft;
                return SetIteratorResult.NeedLeftNode;
            }
            else if (order > 0)
            {
                // If navLeft is positioned to a node that is after navRight, so skip right node
                _state = IteratorState.NeedRight;
                return SetIteratorResult.NeedRightNode;
            }

            // Otherwise, navLeft is positioned to the same node as navRight, so found one item in the intersection
            _state = IteratorState.HaveCurrent;
            return SetIteratorResult.HaveCurrentNode;
        }