CharacterBuffer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Shared / MS / Internal / CharacterBuffer.cs / 1 / CharacterBuffer.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// 
// Description: Definition of readonly character memory buffer
// 
// 
// History:
//  03/31/2003 : [....] - Created 
//  12/01/2004 : [....] - Moved to wcp\shared and made CharacterBuffer implement IList
//
//---------------------------------------------------------------------------
 
using System;
using System.Windows; 
using System.Collections; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions; 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 
 
namespace MS.Internal
{ 
    /// 
    /// Abstraction of a readonly character buffer
    /// 
    internal abstract class CharacterBuffer : IList 
    {
        ///  
        /// Get fixed address of the character buffer 
        /// 
        public abstract unsafe char* GetCharacterPointer(); 


        /// 
        /// Add character buffer's content to a StringBuilder 
        /// 
        /// string builder to add content to 
        /// character offset to first character to append 
        /// number of character appending
        /// string builder 
        public abstract void AppendToStringBuilder(
            StringBuilder   stringBuilder,
            int             characterOffset,
            int             length 
            );
 
        #region IList Members 

        public int IndexOf(char item) 
        {
            for (int i = 0; i < Count; ++i)
            {
                if (item == this[i]) 
                    return i;
            } 
            return -1; 
        }
 
        public void Insert(int index, char item)
        {
            // CharacterBuffer is read only.
            throw new NotSupportedException(); 
        }
 
        public abstract char this[int index] 
        {
            get; 
            set;
        }

        public void RemoveAt(int index) 
        {
            // CharacterBuffer is read only. 
            throw new NotSupportedException(); 
        }
 
        #endregion

        #region ICollection Members
 
        public void Add(char item)
        { 
            // CharacterBuffer is read only. 
            throw new NotSupportedException();
        } 

        public void Clear()
        {
            // CharacterBuffer is read only. 
            throw new NotSupportedException();
        } 
 
        public bool Contains(char item)
        { 
            return IndexOf(item) != -1;
        }

        public void CopyTo(char[] array, int arrayIndex) 
        {
            for (int i = 0; i < Count; ++i) 
            { 
                array[arrayIndex + i] = this[i];
            } 
        }

        public abstract int Count
        { 
            get;
        } 
 
        public bool IsReadOnly
        { 
            get { return true; }
        }

        public bool Remove(char item) 
        {
            // CharacterBuffer is read only. 
            throw new NotSupportedException(); 
        }
 
        #endregion

        #region IEnumerable Members
 
        IEnumerator IEnumerable.GetEnumerator()
        { 
            for (int i = 0; i < Count; ++i) 
                yield return this[i];
        } 

        #endregion

        #region IEnumerable Members 

        IEnumerator IEnumerable.GetEnumerator() 
        { 
            return ((IEnumerable)this).GetEnumerator();
        } 

        #endregion
    }
 

 
    ///  
    /// Character memory buffer implemented by managed character array
    ///  
    internal sealed class CharArrayCharacterBuffer : CharacterBuffer
    {
        private char[]      _characterArray;
 

        ///  
        /// Creating a character memory buffer from character array 
        /// 
        /// character array 
        public CharArrayCharacterBuffer(
            char[]  characterArray
            )
        { 
            if (characterArray == null)
            { 
                throw new ArgumentNullException("characterArray"); 
            }
 
            _characterArray = characterArray;
        }

 
        /// 
        /// Read a character from buffer at the specified character index 
        ///  
        public override char this[int characterOffset]
        { 
            get { return _characterArray[characterOffset]; }
            set { throw new NotSupportedException(); }
        }
 

        ///  
        /// Buffer character length 
        /// 
        public override int Count 
        {
            get { return _characterArray.Length; }
        }
 

        ///  
        /// Get fixed address of the character buffer 
        /// 
        ///  
        ///    Critical:This code manipulates a pointer and returns it
        /// 
        [SecurityCritical]
        public override unsafe char* GetCharacterPointer() 
        {
            // Even though we could allocate GCHandle for this purpose, we would need 
            // to manage how to release them appropriately. It is even worse if we 
            // consider performance implication of doing so. In typical UI scenario,
            // there are so many string objects running around in GC heap. Getting 
            // GCHandle for every one of them is very expensive and demote GC's ability
            // to compact its heap.
            return null;
        } 

 
        ///  
        /// Add character buffer's content to a StringBuilder
        ///  
        /// string builder to add content to
        /// index to first character in the buffer to append
        /// number of character appending
        public override void AppendToStringBuilder( 
            StringBuilder   stringBuilder,
            int             characterOffset, 
            int             characterLength 
            )
        { 
            Debug.Assert(characterOffset >= 0 && characterOffset < _characterArray.Length, "Invalid character index");

            if (    characterLength < 0
                ||  characterOffset + characterLength > _characterArray.Length) 
            {
                characterLength = _characterArray.Length - characterOffset; 
            } 

            stringBuilder.Append(_characterArray, characterOffset, characterLength); 
        }
    }

 

    ///  
    /// Character buffer implemented by string 
    /// 
    internal sealed class StringCharacterBuffer : CharacterBuffer 
    {
        private string      _string;

 
        /// 
        /// Creating a character buffer from string 
        ///  
        /// character string
        public StringCharacterBuffer( 
            string  characterString
            )
        {
            if (characterString == null) 
            {
                throw new ArgumentNullException("characterString"); 
            } 

            _string = characterString; 
        }


        ///  
        /// Read a character from buffer at the specified character index
        ///  
        public override char this[int characterOffset] 
        {
            get { return _string[characterOffset]; } 
            set { throw new NotSupportedException(); }
        }

 
        /// 
        /// Buffer character length 
        ///  
        public override int Count
        { 
            get { return _string.Length; }
        }

 
        /// 
        /// Get fixed address of the character buffer 
        ///  
        /// 
        ///    Critical:This code manipulates a pointer and returns it 
        /// 
        [SecurityCritical]
        public override unsafe char* GetCharacterPointer()
        { 
            // Even though we could allocate GCHandle for this purpose, we would need
            // to manage how to release them appropriately. It is even worse if we 
            // consider performance implication of doing so. In typical UI scenario, 
            // there are so many string objects running around in GC heap. Getting
            // GCHandle for every one of them is very expensive and demote GC's ability 
            // to compact its heap.
            return null;
        }
 

        ///  
        /// Add character buffer's content to a StringBuilder 
        /// 
        /// string builder to add content to 
        /// index to first character in the buffer to append
        /// number of character appending
        public override void AppendToStringBuilder(
            StringBuilder   stringBuilder, 
            int             characterOffset,
            int             characterLength 
            ) 
        {
            Debug.Assert(characterOffset >= 0 && characterOffset < _string.Length, "Invalid character index"); 

            if (    characterLength < 0
                ||  characterOffset + characterLength > _string.Length)
            { 
                characterLength = _string.Length - characterOffset;
            } 
 
            stringBuilder.Append(_string, characterOffset, characterLength);
        } 
    }


 
    /// 
    /// Character buffer implemented as unsafe pointer to character string 
    ///  
    internal sealed unsafe class UnsafeStringCharacterBuffer : CharacterBuffer
    { 
        /// 
        ///     Critical: This code is unsafe since it holds a pointer
        ///     EnforcementCritical
        ///  
        [SecurityCritical]
        private char*   _unsafeString; 
 
        /// 
        ///     Critical: Length is critical to avoid buffer overrun. 
        /// 
        [SecurityCritical]
        private int     _length;
 

        ///  
        /// Creating a character buffer from an unsafe pointer to character string 
        /// 
        /// unsafe pointer to character string 
        /// number of valid characters referenced by the unsafe pointer
        /// 
        ///     Critical: This code is unsafe since it manipulates a pointer, it constructs an object with
        ///     length data from user 
        /// 
        [SecurityCritical] 
        public UnsafeStringCharacterBuffer( 
            char*   characterString,
            int     length 
            )
        {
            if (characterString == null)
            { 
                throw new ArgumentNullException("characterString");
            } 
 
            if (length <= 0)
            { 
                throw new ArgumentOutOfRangeException("length", SR.Get(SRID.ParameterValueMustBeGreaterThanZero));
            }

            _unsafeString = characterString; 
            _length = length;
        } 
 

        ///  
        /// Read a character from buffer at the specified character index
        /// 
        /// 
        ///     Critical: This code is unsafe since it manipulates a pointer 
        ///     Safe: Info is safe to expose and method does bound check
        ///  
        public override char this[int characterOffset] 
        {
            [SecurityCritical, SecurityTreatAsSafe] 
            get {
                if (characterOffset >= _length || characterOffset < 0)
                    throw new ArgumentOutOfRangeException("characterOffset", SR.Get(SRID.ParameterMustBeBetween,0,_length));
                return _unsafeString[characterOffset]; 
            }
            [SecurityCritical, SecurityTreatAsSafe] 
            set { throw new NotSupportedException(); } 
        }
 

        /// 
        /// Buffer character length
        ///  
        /// 
        /// Critical: Lenght is critical data when dealing with unsafe pointer. 
        /// Safe: This value is safe to give out. 
        /// 
        public override int Count 
        {
            [SecurityCritical, SecurityTreatAsSafe]
            get { return _length; }
        } 

 
        ///  
        /// Get fixed address of the character buffer
        ///  
        /// 
        /// Critical:This returns the pointer
        /// 
        [SecurityCritical] 
        public override unsafe char* GetCharacterPointer()
        { 
            return _unsafeString; 
        }
 

        /// 
        /// Add character buffer's content to a StringBuilder
        ///  
        /// string builder to add content to
        /// index to first character in the buffer to append 
        /// number of character appending 
        /// 
        ///    Critical: This returns the string in a string builder object, critical because it accesses the pointer 
        ///              and returns its contents embedded in the stringbuilder passed in.
        ///    Safe:     This method does proper bound check.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        public override  void AppendToStringBuilder(
            StringBuilder   stringBuilder, 
            int             characterOffset, 
            int             characterLength
            ) 
        {

            if (characterOffset >= _length || characterOffset < 0)
            { 
                throw new ArgumentOutOfRangeException("characterOffset", SR.Get(SRID.ParameterMustBeBetween,0,_length));
            } 
 
            if (characterLength < 0 || characterOffset + characterLength > _length)
            { 
                throw new ArgumentOutOfRangeException("characterLength", SR.Get(SRID.ParameterMustBeBetween,0, _length - characterOffset));
            }

            stringBuilder.Append(new string(_unsafeString, characterOffset, characterLength)); 
        }
    } 
} 


// 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