Esempio n. 1
0
        internal override Opcode Eval(ProcessingContext context)
        {
            StackFrame             topFrame = context.TopSequenceArg;
            SeekableXPathNavigator node     = null;

            Value[] sequences = context.Sequences;

            for (int i = topFrame.basePtr; i <= topFrame.endPtr; ++i)
            {
                // Each NodeSequence will generate a new one, but only if the source FilterSequence isn't empty
                // If the source FilterSequence is empty, release it and replace it with an empty sequence
                NodeSequence sourceSeq      = sequences[i].Sequence;
                int          sourceSeqCount = sourceSeq.Count;
                if (sourceSeqCount == 0)
                {
                    context.ReplaceSequenceAt(i, NodeSequence.Empty);
                    context.ReleaseSequence(sourceSeq);
                }
                else
                {
                    NodeSequenceItem[] items = sourceSeq.Items;
                    if (sourceSeq.CanReuse(context))
                    {
                        node = items[0].GetNavigator();
                        sourceSeq.Clear();
                        sourceSeq.StartNodeset();

                        this.criteria.Select(node, sourceSeq);

                        sourceSeq.StopNodeset();
                    }
                    else
                    {
                        NodeSequence newSeq = null;
                        for (int item = 0; item < sourceSeqCount; ++item)
                        {
                            node = items[item].GetNavigator();
                            Fx.Assert(null != node, "");
                            if (null == newSeq)
                            {
                                newSeq = context.CreateSequence();
                            }
                            newSeq.StartNodeset();
                            this.criteria.Select(node, newSeq);
                            newSeq.StopNodeset();
                        }
                        context.ReplaceSequenceAt(i, (null != newSeq) ? newSeq : NodeSequence.Empty);
                        context.ReleaseSequence(sourceSeq);
                    }
                }
            }

            return(this.next);
        }
Esempio n. 2
0
        internal override Opcode Eval(ProcessingContext context)
        {
            StackFrame             topSequenceArg = context.TopSequenceArg;
            SeekableXPathNavigator contextNode    = null;

            Value[] sequences = context.Sequences;
            for (int i = topSequenceArg.basePtr; i <= topSequenceArg.endPtr; i++)
            {
                NodeSequence sequence = sequences[i].Sequence;
                int          count    = sequence.Count;
                if (count == 0)
                {
                    context.ReplaceSequenceAt(i, NodeSequence.Empty);
                    context.ReleaseSequence(sequence);
                }
                else
                {
                    NodeSequenceItem[] items = sequence.Items;
                    if (sequence.CanReuse(context))
                    {
                        contextNode = items[0].GetNavigator();
                        sequence.Clear();
                        sequence.StartNodeset();
                        this.criteria.Select(contextNode, sequence);
                        sequence.StopNodeset();
                    }
                    else
                    {
                        NodeSequence destSequence = null;
                        for (int j = 0; j < count; j++)
                        {
                            contextNode = items[j].GetNavigator();
                            if (destSequence == null)
                            {
                                destSequence = context.CreateSequence();
                            }
                            destSequence.StartNodeset();
                            this.criteria.Select(contextNode, destSequence);
                            destSequence.StopNodeset();
                        }
                        context.ReplaceSequenceAt(i, (destSequence != null) ? destSequence : NodeSequence.Empty);
                        context.ReleaseSequence(sequence);
                    }
                }
            }
            return(base.next);
        }