RangeContentEnumerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / Documents / RangeContentEnumerator.cs / 1 / RangeContentEnumerator.cs

                            #pragma warning disable 1634, 1691 // To enable presharp warning disables (#pragma suppress) below. 

//----------------------------------------------------------------------------
//
//  
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
// 
//
// Description: IEnumerator for TextRange and TextElement content. 
//
//
// History:
//  05/27/2003 : benwest - Created 
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using MS.Internal;
using System.Text;
using MS.Utility;
using System.Windows.Controls; 

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings 
 
namespace System.Windows.Documents
{ 
    internal class RangeContentEnumerator : IEnumerator
    {
        //-----------------------------------------------------
        // 
        //  Constructors
        // 
        //----------------------------------------------------- 

        #region Constructors 

        // Creates an enumerator instance.
        // Null start/end creates an empty enumerator.
        internal RangeContentEnumerator(TextPointer start, TextPointer end) 
        {
            Invariant.Assert(start != null && end != null || start == null && end == null, "If start is null end should be null!"); 
 
            _start = start;
            _end = end; 

            // Remember what generation the backing store was in when we started,
            // so we can throw if this enumerator is accessed after content has
            // changed. 
            if (_start != null)
            { 
                _generation = _start.TextContainer.Generation; 
            }
        } 

        #endregion Constructors

        //------------------------------------------------------ 
        //
        //  Public Methods 
        // 
        //-----------------------------------------------------
 
        #region Public Methods

        /// 
        /// Return the current object this enumerator is pointing to.  This is 
        /// generally a FrameworkElement, TextElement, an embedded
        /// object, or Text content. 
        ///  
        public object Current
        { 
            get
            {
                int runLength;
                int offset; 

                if (_navigator == null) 
                { 
                    // Disable presharp 6503: Property get methods should not throw exceptions.
                    // We must throw here -- it's part of the IEnumerator contract. 
                    #pragma warning suppress 6503
                    throw new InvalidOperationException(SR.Get(SRID.EnumeratorNotStarted));
                }
 
                // Check _currentCache before looking at _navigator.  For the
                // last item in the enumeration, _navigator == _end, but 
                // that's ok, the previous get_Current call (which sets _currentCache 
                // non-null) put it there.
                if (_currentCache != null) 
                {
                    return _currentCache;
                }
 
                if (_navigator.CompareTo(_end) >= 0)
                { 
                    #pragma warning suppress 6503 // IEnumerator.Current is documented to throw this exception 
                    throw new InvalidOperationException(SR.Get(SRID.EnumeratorReachedEnd));
                } 

                // Throw if the tree has been modified since this enumerator was created.
                if (_generation != _start.TextContainer.Generation)
                { 
                    #pragma warning suppress 6503 // IEnumerator.Current is documented to throw this exception
                    throw new InvalidOperationException(SR.Get(SRID.EnumeratorVersionChanged)); 
                } 

                switch (_navigator.GetPointerContext(LogicalDirection.Forward)) 
                {
                    case TextPointerContext.Text:
                        offset = 0;
 
                        // Merge all successive text runs into a single value.
                        do 
                        { 
                            runLength = _navigator.GetTextRunLength(LogicalDirection.Forward);
                            EnsureBufferCapacity(offset + runLength); 
                            _navigator.GetTextInRun(LogicalDirection.Forward, _buffer, offset, runLength);
                            offset += runLength;
                            _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        } 
                        while (_navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text);
 
                        _currentCache = new string(_buffer, 0, offset); 

                        // _navigator is at next content. 
                        break;

                    case TextPointerContext.EmbeddedElement:
                        _currentCache = _navigator.GetAdjacentElement(LogicalDirection.Forward); 

                        // Position _navigator at next content. 
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward); 
                        break;
 
                    case TextPointerContext.ElementStart:
                        // Return the element, and advance past its entire content.
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        _currentCache = _navigator.Parent; 

                        // Position _navigator at next content. 
                        _navigator.MoveToElementEdge(ElementEdge.AfterEnd); 
                        break;
 
                    default:
                        Invariant.Assert(false, "Unexpected run type!");
                        _currentCache = null; // We should never get here.
                        break; 
                }
 
                return _currentCache; 
            }
        } 

        /// 
        /// Advance the enumerator to the next object in the range.  Return true if content
        /// was found. 
        /// 
        public bool MoveNext() 
        { 
            // Throw if the tree has been modified since this enumerator was created.
            if (_start != null && _generation != _start.TextContainer.Generation) 
            {
                throw new InvalidOperationException(SR.Get(SRID.EnumeratorVersionChanged));
            }
 
            if (_start == null || _start.CompareTo(_end) == 0)
                return false; 
 
            if (_navigator != null && _navigator.CompareTo(_end) >= 0)
            { 
                return false;
            }

            if (_navigator == null) 
            {
                _navigator = new TextPointer(_start); 
            } 
            else if (_currentCache == null) // If we have a cache, _navigator is already positioned at the next item.
            { 
                switch (_navigator.GetPointerContext(LogicalDirection.Forward))
                {
                    case TextPointerContext.Text:
 
                        // Skip all successive text runs as a single value.
                        do 
                        { 
                            _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        } 
                        while (_navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text && _navigator.CompareTo(_end) < 0);

                        break;
 
                    case TextPointerContext.EmbeddedElement:
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward); 
                        break; 

                    case TextPointerContext.ElementStart: 
                        // Return the element, and advance past its entire content.
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        _navigator.MoveToPosition(((TextElement)_navigator.Parent).ElementEnd);
                        break; 

                    default: 
                        Invariant.Assert(false, "Unexpected run type!"); 
                        break;
                } 
            }

            _currentCache = null;
 
            return (_navigator.CompareTo(_end) < 0);
        } 
 
        /// 
        /// Reset the enumerator to the start of the range. 
        /// 
        public void Reset()
        {
            // Throw if the tree has been modified since this enumerator was created. 
            if (_start != null && _generation != _start.TextContainer.Generation)
            { 
                throw new InvalidOperationException(SR.Get(SRID.EnumeratorVersionChanged)); 
            }
 
            _navigator = null;
        }

        #endregion Public Methods 

        //------------------------------------------------------ 
        // 
        //  Public Properties
        // 
        //------------------------------------------------------

        #region Public Properties
 
        #endregion Public Properties
 
        //----------------------------------------------------- 
        //
        //  Public Events 
        //
        //------------------------------------------------------

        #region Public Events 

        #endregion Public Events 
 
        //-----------------------------------------------------
        // 
        //  Protected Methods
        //
        //-----------------------------------------------------
 
        #region Protected Methods
 
        #endregion Protected Events 

        //----------------------------------------------------- 
        //
        //  Internal Methods
        //
        //------------------------------------------------------ 

        #region Internal Methods 
 
        #endregion Internal methods
 
        //-----------------------------------------------------
        //
        //  Internal Properties
        // 
        //------------------------------------------------------
 
        #region Internal Properties 

        #endregion Internal Properties 

        //------------------------------------------------------
        //
        //  Internal Events 
        //
        //----------------------------------------------------- 
 
        #region Internal Events
 
        #endregion Internal Events

        //------------------------------------------------------
        // 
        //  Private Methods
        // 
        //----------------------------------------------------- 

        #region Private Methods 

        private void EnsureBufferCapacity(int size)
        {
            char [] newBuffer; 

            if (_buffer == null) 
            { 
                _buffer = new char[size];
            } 
            else if (_buffer.Length < size)
            {
                newBuffer = new char[Math.Max(2*_buffer.Length, size)];
                _buffer.CopyTo(newBuffer, 0); 
                _buffer = newBuffer;
            } 
        } 

        #endregion Private methods 

        //-----------------------------------------------------
        //
        //  Private Properties 
        //
        //----------------------------------------------------- 
 
        #region Private Properties
 
        #endregion Private Properties

        //------------------------------------------------------
        // 
        //  Private Fields
        // 
        //----------------------------------------------------- 

        #region Private Fields 

        // Edges of the span to enumerator over.
        private readonly TextPointer _start;
        private readonly TextPointer _end; 

        // Backing store generation when this enumerator was created. 
        private readonly uint _generation; 

        // Current position in the enumeration. 
        private TextPointer _navigator;

        // Calculated content at the current position.
        private object _currentCache; 

        // Buffer to text content retrieval. 
        private char [] _buffer; 

        #endregion Private Fields 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
#pragma warning disable 1634, 1691 // To enable presharp warning disables (#pragma suppress) below. 

//----------------------------------------------------------------------------
//
//  
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
// 
//
// Description: IEnumerator for TextRange and TextElement content. 
//
//
// History:
//  05/27/2003 : benwest - Created 
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using MS.Internal;
using System.Text;
using MS.Utility;
using System.Windows.Controls; 

#pragma warning disable 1634, 1691  // suppressing PreSharp warnings 
 
namespace System.Windows.Documents
{ 
    internal class RangeContentEnumerator : IEnumerator
    {
        //-----------------------------------------------------
        // 
        //  Constructors
        // 
        //----------------------------------------------------- 

        #region Constructors 

        // Creates an enumerator instance.
        // Null start/end creates an empty enumerator.
        internal RangeContentEnumerator(TextPointer start, TextPointer end) 
        {
            Invariant.Assert(start != null && end != null || start == null && end == null, "If start is null end should be null!"); 
 
            _start = start;
            _end = end; 

            // Remember what generation the backing store was in when we started,
            // so we can throw if this enumerator is accessed after content has
            // changed. 
            if (_start != null)
            { 
                _generation = _start.TextContainer.Generation; 
            }
        } 

        #endregion Constructors

        //------------------------------------------------------ 
        //
        //  Public Methods 
        // 
        //-----------------------------------------------------
 
        #region Public Methods

        /// 
        /// Return the current object this enumerator is pointing to.  This is 
        /// generally a FrameworkElement, TextElement, an embedded
        /// object, or Text content. 
        ///  
        public object Current
        { 
            get
            {
                int runLength;
                int offset; 

                if (_navigator == null) 
                { 
                    // Disable presharp 6503: Property get methods should not throw exceptions.
                    // We must throw here -- it's part of the IEnumerator contract. 
                    #pragma warning suppress 6503
                    throw new InvalidOperationException(SR.Get(SRID.EnumeratorNotStarted));
                }
 
                // Check _currentCache before looking at _navigator.  For the
                // last item in the enumeration, _navigator == _end, but 
                // that's ok, the previous get_Current call (which sets _currentCache 
                // non-null) put it there.
                if (_currentCache != null) 
                {
                    return _currentCache;
                }
 
                if (_navigator.CompareTo(_end) >= 0)
                { 
                    #pragma warning suppress 6503 // IEnumerator.Current is documented to throw this exception 
                    throw new InvalidOperationException(SR.Get(SRID.EnumeratorReachedEnd));
                } 

                // Throw if the tree has been modified since this enumerator was created.
                if (_generation != _start.TextContainer.Generation)
                { 
                    #pragma warning suppress 6503 // IEnumerator.Current is documented to throw this exception
                    throw new InvalidOperationException(SR.Get(SRID.EnumeratorVersionChanged)); 
                } 

                switch (_navigator.GetPointerContext(LogicalDirection.Forward)) 
                {
                    case TextPointerContext.Text:
                        offset = 0;
 
                        // Merge all successive text runs into a single value.
                        do 
                        { 
                            runLength = _navigator.GetTextRunLength(LogicalDirection.Forward);
                            EnsureBufferCapacity(offset + runLength); 
                            _navigator.GetTextInRun(LogicalDirection.Forward, _buffer, offset, runLength);
                            offset += runLength;
                            _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        } 
                        while (_navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text);
 
                        _currentCache = new string(_buffer, 0, offset); 

                        // _navigator is at next content. 
                        break;

                    case TextPointerContext.EmbeddedElement:
                        _currentCache = _navigator.GetAdjacentElement(LogicalDirection.Forward); 

                        // Position _navigator at next content. 
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward); 
                        break;
 
                    case TextPointerContext.ElementStart:
                        // Return the element, and advance past its entire content.
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        _currentCache = _navigator.Parent; 

                        // Position _navigator at next content. 
                        _navigator.MoveToElementEdge(ElementEdge.AfterEnd); 
                        break;
 
                    default:
                        Invariant.Assert(false, "Unexpected run type!");
                        _currentCache = null; // We should never get here.
                        break; 
                }
 
                return _currentCache; 
            }
        } 

        /// 
        /// Advance the enumerator to the next object in the range.  Return true if content
        /// was found. 
        /// 
        public bool MoveNext() 
        { 
            // Throw if the tree has been modified since this enumerator was created.
            if (_start != null && _generation != _start.TextContainer.Generation) 
            {
                throw new InvalidOperationException(SR.Get(SRID.EnumeratorVersionChanged));
            }
 
            if (_start == null || _start.CompareTo(_end) == 0)
                return false; 
 
            if (_navigator != null && _navigator.CompareTo(_end) >= 0)
            { 
                return false;
            }

            if (_navigator == null) 
            {
                _navigator = new TextPointer(_start); 
            } 
            else if (_currentCache == null) // If we have a cache, _navigator is already positioned at the next item.
            { 
                switch (_navigator.GetPointerContext(LogicalDirection.Forward))
                {
                    case TextPointerContext.Text:
 
                        // Skip all successive text runs as a single value.
                        do 
                        { 
                            _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        } 
                        while (_navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text && _navigator.CompareTo(_end) < 0);

                        break;
 
                    case TextPointerContext.EmbeddedElement:
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward); 
                        break; 

                    case TextPointerContext.ElementStart: 
                        // Return the element, and advance past its entire content.
                        _navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                        _navigator.MoveToPosition(((TextElement)_navigator.Parent).ElementEnd);
                        break; 

                    default: 
                        Invariant.Assert(false, "Unexpected run type!"); 
                        break;
                } 
            }

            _currentCache = null;
 
            return (_navigator.CompareTo(_end) < 0);
        } 
 
        /// 
        /// Reset the enumerator to the start of the range. 
        /// 
        public void Reset()
        {
            // Throw if the tree has been modified since this enumerator was created. 
            if (_start != null && _generation != _start.TextContainer.Generation)
            { 
                throw new InvalidOperationException(SR.Get(SRID.EnumeratorVersionChanged)); 
            }
 
            _navigator = null;
        }

        #endregion Public Methods 

        //------------------------------------------------------ 
        // 
        //  Public Properties
        // 
        //------------------------------------------------------

        #region Public Properties
 
        #endregion Public Properties
 
        //----------------------------------------------------- 
        //
        //  Public Events 
        //
        //------------------------------------------------------

        #region Public Events 

        #endregion Public Events 
 
        //-----------------------------------------------------
        // 
        //  Protected Methods
        //
        //-----------------------------------------------------
 
        #region Protected Methods
 
        #endregion Protected Events 

        //----------------------------------------------------- 
        //
        //  Internal Methods
        //
        //------------------------------------------------------ 

        #region Internal Methods 
 
        #endregion Internal methods
 
        //-----------------------------------------------------
        //
        //  Internal Properties
        // 
        //------------------------------------------------------
 
        #region Internal Properties 

        #endregion Internal Properties 

        //------------------------------------------------------
        //
        //  Internal Events 
        //
        //----------------------------------------------------- 
 
        #region Internal Events
 
        #endregion Internal Events

        //------------------------------------------------------
        // 
        //  Private Methods
        // 
        //----------------------------------------------------- 

        #region Private Methods 

        private void EnsureBufferCapacity(int size)
        {
            char [] newBuffer; 

            if (_buffer == null) 
            { 
                _buffer = new char[size];
            } 
            else if (_buffer.Length < size)
            {
                newBuffer = new char[Math.Max(2*_buffer.Length, size)];
                _buffer.CopyTo(newBuffer, 0); 
                _buffer = newBuffer;
            } 
        } 

        #endregion Private methods 

        //-----------------------------------------------------
        //
        //  Private Properties 
        //
        //----------------------------------------------------- 
 
        #region Private Properties
 
        #endregion Private Properties

        //------------------------------------------------------
        // 
        //  Private Fields
        // 
        //----------------------------------------------------- 

        #region Private Fields 

        // Edges of the span to enumerator over.
        private readonly TextPointer _start;
        private readonly TextPointer _end; 

        // Backing store generation when this enumerator was created. 
        private readonly uint _generation; 

        // Current position in the enumeration. 
        private TextPointer _navigator;

        // Calculated content at the current position.
        private object _currentCache; 

        // Buffer to text content retrieval. 
        private char [] _buffer; 

        #endregion Private Fields 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK