EncodingTable.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Globalization / EncodingTable.cs / 1305376 / EncodingTable.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
namespace System.Globalization
{ 
    using System; 
    using System.Text;
    using System.Collections; 
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Runtime.Versioning; 
    using System.Threading;
    using System.Diagnostics.Contracts; 
    // 
    // Data table for encoding classes.  Used by System.Text.Encoding.
    // This class contains two hashtables to allow System.Text.Encoding 
    // to retrieve the data item either by codepage value or by webName.
    //

    // Only statics, does not need to be marked with the serializable attribute 
    internal static class EncodingTable
    { 
 
        //This number is the size of the table in native.  The value is retrieved by
        //calling the native GetNumEncodingItems(). 
        private static int lastEncodingItem = GetNumEncodingItems() - 1;

        //This number is the size of the code page table.  Its generated when we walk the table the first time.
        private static int lastCodePageItem; 

        // 
        // This points to a native data table which maps an encoding name to the correct code page. 
        //
        unsafe internal static InternalEncodingDataItem *encodingDataPtr = GetEncodingData(); 
        //
        // This points to a native data table which stores the properties for the code page, and
        // the table is indexed by code page.
        // 
        unsafe internal static InternalCodePageDataItem *codePageDataPtr = GetCodePageData();
        // 
        // This caches the mapping of an encoding name to a code page. 
        //
        private static Hashtable hashByName = Hashtable.Synchronized(new Hashtable(StringComparer.OrdinalIgnoreCase)); 
        //
        // THe caches the data item which is indexed by the code page value.
        //
        private static Hashtable hashByCodePage = Hashtable.Synchronized(new Hashtable()); 

        [System.Security.SecuritySafeCritical] // static constructors should be safe to call 
        static EncodingTable() 
        {
        } 

        // Find the data item by binary searching the table that we have in native.
        // nativeCompareOrdinalWC is an internal-only function.
        [System.Security.SecuritySafeCritical]  // auto-generated 
        unsafe private static int internalGetCodePageFromName(String name) {
            int left  = 0; 
            int right = lastEncodingItem; 
            int index;
            int result; 

            //Binary search the array until we have only a couple of elements left and then
            //just walk those elements.
            while ((right - left)>3) { 
                index = ((right - left)/2) + left;
 
                result = String.nativeCompareOrdinalIgnoreCaseWC(name, encodingDataPtr[index].webName); 

                if (result == 0) { 
                    //We found the item, return the associated codepage.
                    return (encodingDataPtr[index].codePage);
                } else if (result<0) {
                    //The name that we're looking for is less than our current index. 
                    right = index;
                } else { 
                    //The name that we're looking for is greater than our current index 
                    left = index;
                } 
            }

            //Walk the remaining elements (it'll be 3 or fewer).
            for (; left<=right; left++) { 
                if (String.nativeCompareOrdinalIgnoreCaseWC(name, encodingDataPtr[left].webName) == 0) {
                    return (encodingDataPtr[left].codePage); 
                } 
            }
            // The encoding name is not valid. 
            throw new ArgumentException(
                String.Format(
                    CultureInfo.CurrentCulture,
                    Environment.GetResourceString("Argument_EncodingNotSupported"), name), "name"); 
        }
 
        // Return a list of all EncodingInfo objects describing all of our encodings 
        [System.Security.SecuritySafeCritical]  // auto-generated
        internal static unsafe EncodingInfo[] GetEncodings() 
        {
            if (lastCodePageItem == 0)
            {
                int count; 
                for (count = 0; codePageDataPtr[count].codePage != 0; count++)
                { 
                    // Count them 
                }
                lastCodePageItem = count; 
            }

            EncodingInfo[] arrayEncodingInfo = new EncodingInfo[lastCodePageItem];
 
            int i;
            for (i = 0; i < lastCodePageItem; i++) 
            { 
                arrayEncodingInfo[i] = new EncodingInfo(codePageDataPtr[i].codePage, new String(codePageDataPtr[i].webName),
                    Environment.GetResourceString("Globalization.cp_" + codePageDataPtr[i].codePage)); 
            }

            return arrayEncodingInfo;
        } 

        /*=================================GetCodePageFromName========================== 
        **Action: Given a encoding name, return the correct code page number for this encoding. 
        **Returns: The code page for the encoding.
        **Arguments: 
        **  name    the name of the encoding
        **Exceptions:
        **  ArgumentNullException if name is null.
        **  internalGetCodePageFromName will throw ArgumentException if name is not a valid encoding name. 
        ============================================================================*/
 
        internal static int GetCodePageFromName(String name) 
        {
            if (name==null) { 
                throw new ArgumentNullException("name");
            }
            Contract.EndContractBlock();
 
            Object codePageObj;
 
            // 
            // The name is case-insensitive, but ToLower isn't free.  Check for
            // the code page in the given capitalization first. 
            //
            codePageObj = hashByName[name];

            if (codePageObj!=null) { 
                return ((int)codePageObj);
            } 
 
            //Okay, we didn't find it in the hash table, try looking it up in the
            //unmanaged data. 
            int codePage = internalGetCodePageFromName(name);

            hashByName[name] = codePage;
 
            return codePage;
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        unsafe internal static CodePageDataItem GetCodePageDataItem(int codepage) { 
            CodePageDataItem dataItem;

            // We synchronize around dictionary gets/sets. There's still a possibility that two threads
            // will create a CodePageDataItem and the second will clobber the first in the dictionary. 
            // However, that's acceptable because the contents are correct and we make no guarantees
            // other than that. 
 
            //Look up the item in the hashtable.
            dataItem = (CodePageDataItem)hashByCodePage[codepage]; 

            //If we found it, return it.
            if (dataItem!=null) {
                return dataItem; 
            }
 
 
            //If we didn't find it, try looking it up now.
            //If we find it, add it to the hashtable. 
            //This is a linear search, but we probably won't be doing it very often.
            //
            int i = 0;
            int data; 
            while ((data = codePageDataPtr[i].codePage) != 0) {
                if (data == codepage) { 
                    dataItem = new CodePageDataItem(i); 
                    hashByCodePage[codepage] = dataItem;
                    return (dataItem); 
                }
                i++;
            }
 
            //Nope, we didn't find it.
            return null; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]  // Returns a pointer to a process-wide instance
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private unsafe static extern InternalEncodingDataItem *GetEncodingData();
 
        //
        // Return the number of encoding data items. 
        // 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern int GetNumEncodingItems();

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]  // Returns a pointer to a process-wide instance
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private unsafe static extern InternalCodePageDataItem* GetCodePageData(); 

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.Machine)]
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal unsafe static extern byte* nativeCreateOpenFileMapping(
            String inSectionName, int inBytesToAllocate, out IntPtr mappedFileHandle); 
    }
 
    /*=================================InternalEncodingDataItem========================== 
    **Action: This is used to map a encoding name to a correct code page number. By doing this,
    ** we can get the properties of this encoding via the InternalCodePageDataItem. 
    **
    ** We use this structure to access native data exposed by the native side.
    ============================================================================*/
 
    [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
    internal unsafe struct InternalEncodingDataItem { 
        internal char *webName; 
        internal int   codePage;
    } 

    /*=================================InternalCodePageDataItem==========================
    **Action: This is used to access the properties related to a code page.
    ** We use this structure to access native data exposed by the native side. 
    ============================================================================*/
 
    [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] 
    internal unsafe struct InternalCodePageDataItem {
        internal int   codePage; 
        internal int   uiFamilyCodePage;
        internal char *webName;
        internal char *headerName;
        internal char *bodyName; 
        internal uint  flags;
    } 
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

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