Metadata.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 / fx / src / AddIn / AddIn / System / Addin / MiniReflection / MetadataReader / Metadata.cs / 1305376 / Metadata.cs

                            using System; 
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.IO; 
using System.Diagnostics.Contracts;
 
namespace System.AddIn.MiniReflection.MetadataReader 
{
    [Serializable] 
    internal struct MetadataToken
    {
        public MDTables.Tables Table;
        public UInt32 Index;   // 1 to N, not 0 to N-1. 

        public MetadataToken(MDTables.Tables table, UInt32 index) 
        { 
            System.Diagnostics.Contracts.Contract.Requires((index & 0xFF000000U) == 0);
 
            Table = table;
            Index = index;
        }
 
        public override String ToString()
        { 
            return String.Format(CultureInfo.InvariantCulture, "Table {0} ({1}), entry {2}", MDTables.Names[(Int32)Table], (UInt32)Table, Index); 
        }
 
        public String ToMDToken()
        {
            return String.Format(CultureInfo.InvariantCulture, "{0:x2}{1:x6}", (UInt32)Table, Index);
        } 
    }
 
 
    internal sealed class MDTables
    { 
        internal static readonly String[] Names = new String[(Int32)Tables.MaxTable + 1];
        internal static readonly Boolean[] IsDefined = new Boolean[(Int32)Tables.MaxTable + 1];
        private static readonly UTF8Encoding Encoder = new UTF8Encoding(false, true);
 
        // Per-Instance data
        internal BinaryReader B; 
        private StreamDesc stringStream, blobStream; 

        private UInt32[] lengths;   // Indexed by table, gives length of row in bytes 
        private UInt32[] tableAt;   // Indexed by table, gives location in file
        private UInt32[] NRows;     // Indexed by table, gives number of rows
        private UInt32 stringIndex, blobIndex, GUIDIndex; // Bytes required to reference these items
 

        internal enum Tables 
        { 
            Invalid = -1,
            XModule = 0, 
            TypeRef = 1,
            TypeDef = 2,
            FieldPtr = 3,		// Not public
            FieldDef = 4, 
            MethodPtr  = 5,		// Not public
            MethodDef = 6, 
            ParamPtr = 7,		// Not public 
            ParamDef = 8,
            InterfaceImpl = 9, 
            MemberRef = 10,
            Constant = 11,
            CustomAttribute = 12,
            FieldMarshal = 13, 
            DeclSecurity = 14,
            ClassLayout = 15, 
            FieldLayout = 16, 
            StandAloneSig = 17,
            EventMap = 18, 
            EventPtr = 19,		// Not public
            XEvent = 20,
            PropertyMap = 21,
            PropertyPtr = 22,	// Not public 
            XProperty = 23,
            MethodSemantics = 24, 
            MethodImpl = 25, 
            ModuleRef = 26,
            TypeSpec = 27, 
            ImplMap = 28,
            FieldRVA = 29,
            // Unused 0x1E = 30 Edit&Continue Log
            // Unused 0x1F = 31 Edit&Continue Map 
            XAssembly = 32,
            AssemblyProcessor = 33, 
            AssemblyOS = 34, 
            AssemblyRef = 35,
            AssemblyRefProcessor = 36, 
            AssemblyRefOS = 37,
            File = 38,
            ExportedType = 39,
            ManifestResource = 40, 
            NestedClass = 41,
            GenericParam = 42, 
            GenericMethod = 43, 
            GenericConstraint = 44,
            //From 45 through 63, inclusive, are not used 
            MaxTable = 63
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification="Not possible")] 
        static MDTables()
        { 
            Names[(Int32)Tables.AssemblyOS] = "AssemblyOS"; 
            Names[(Int32)Tables.AssemblyProcessor] = "AssemblyProcessor";
            Names[(Int32)Tables.AssemblyRef] = "AssemblyRef"; 
            Names[(Int32)Tables.AssemblyRefOS] = "AssemblyRefOS";
            Names[(Int32)Tables.AssemblyRefProcessor] = "AssemblyRefProcessor";
            Names[(Int32)Tables.ClassLayout] = "ClassLayout";
            Names[(Int32)Tables.Constant] = "Constant"; 
            Names[(Int32)Tables.CustomAttribute] = "CustomAttribute";
            Names[(Int32)Tables.DeclSecurity] = "DeclSecurity"; 
            Names[(Int32)Tables.EventMap] = "EventMap"; 
            Names[(Int32)Tables.ExportedType] = "ExportedType";
            Names[(Int32)Tables.FieldDef] = "FieldDef"; 
            Names[(Int32)Tables.FieldLayout] = "FieldLayout";
            Names[(Int32)Tables.FieldMarshal] = "FieldMarshal";
            Names[(Int32)Tables.FieldRVA] = "FieldRVA";
            Names[(Int32)Tables.File] = "File"; 
            Names[(Int32)Tables.GenericParam] = "GenericParam";
            Names[(Int32)Tables.GenericMethod] = "GenericMethod"; 
            Names[(Int32)Tables.GenericConstraint] = "GenericConstraint"; 
            Names[(Int32)Tables.ImplMap] = "ImplMap";
            Names[(Int32)Tables.InterfaceImpl] = "InterfaceImpl"; 
            Names[(Int32)Tables.ManifestResource] = "ManifestResource";
            Names[(Int32)Tables.MemberRef] = "MemberRef";
            Names[(Int32)Tables.MethodDef] = "MethodDef";
            Names[(Int32)Tables.MethodImpl] = "MethodImpl"; 
            Names[(Int32)Tables.MethodSemantics] = "MethodSemantics";
            Names[(Int32)Tables.ModuleRef] = "ModuleRef"; 
            Names[(Int32)Tables.NestedClass] = "NestedClass"; 
            Names[(Int32)Tables.ParamDef] = "ParamDef";
            Names[(Int32)Tables.PropertyMap] = "PropertyMap"; 
            Names[(Int32)Tables.StandAloneSig] = "StandAloneSig";
            Names[(Int32)Tables.TypeDef] = "TypeDef";
            Names[(Int32)Tables.TypeRef] = "TypeRef";
            Names[(Int32)Tables.TypeSpec] = "TypeSpec"; 
            Names[(Int32)Tables.XAssembly] = "Assembly";
            Names[(Int32)Tables.XEvent] = "Event"; 
            Names[(Int32)Tables.XModule] = "Module"; 
            Names[(Int32)Tables.XProperty] = "Property";
// Not public 
            Names[(Int32)Tables.FieldPtr] = "FieldPointer";
            Names[(Int32)Tables.MethodPtr] = "MethodPointer";
            Names[(Int32)Tables.ParamPtr] = "ParamPointer";
            Names[(Int32)Tables.EventPtr] = "EventPointer"; 
            Names[(Int32)Tables.PropertyPtr] = "PropertyPointer";
 		 
 
            for (Int32 i = 0; i <= (Int32)Tables.MaxTable; i++)
            { 
                IsDefined[i] = Names[i] != null;
                if (!IsDefined[i])
                    Names[i] = String.Format(CultureInfo.InvariantCulture, "<<{0}>>", i);
            } 
        }
 
        internal enum Encodings 
        {
            TypeDefOrRef, HasConstant, HasCustomAttribute, HasFieldMarshall, 
            HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef,
            MemberForwarded, Implementation, CustomAttributeType,
            ResolutionScope, TypeOrMethodDef,
            //Max = TypeOrMethodDef 
        }
 
        private struct EncodingDesc 
        {
            String Name; 
            internal int TagBits;
            internal Tables[] WhichTables;

            internal EncodingDesc(String N, int T, Tables[] W) 
            {
                Name = N; 
                TagBits = T; 
                WhichTables = W;
            } 
            /*
            public override String ToString()
            {
                return String.Format("Encoding {0} has {1} tag bits for {2} tables", 
                    Name, TagBits, WhichTables.Length);
            } 
             */ 
        }
 
        private static readonly EncodingDesc[] EncodingDescs = new EncodingDesc[]
            // These are ordered to match their definitions in MD\Runtime\Metamodel.h
            {
                new EncodingDesc("TypeDefOrRef", 2, 
                  new Tables[] { Tables.TypeDef, Tables.TypeRef, Tables.TypeSpec }),
                new EncodingDesc("HasConstant", 2, 
                  new Tables[] { Tables.FieldDef, Tables.ParamDef, Tables.XProperty }), 
                new EncodingDesc("HasCustomAttribute", 5,
                  new Tables[] { Tables.MethodDef, Tables.FieldDef, Tables.TypeRef, Tables.TypeDef, 
                      Tables.ParamDef, Tables.InterfaceImpl, Tables.MemberRef, Tables.XModule,
                      Tables.DeclSecurity, Tables.XProperty, Tables.XEvent, Tables.StandAloneSig,
                      Tables.ModuleRef, Tables.TypeSpec, Tables.XAssembly, Tables.AssemblyRef,
                      Tables.File, Tables.ExportedType, Tables.ManifestResource, 
                      // These last three aren't documented, but are allowed
                      Tables.GenericParam, Tables.GenericConstraint, Tables.GenericParam}), 
                new EncodingDesc("HasFieldMarshall", 1, 
                  new Tables[] { Tables.FieldDef, Tables.ParamDef }),
                new EncodingDesc("HasDeclSecurity", 2, 
                  new Tables[] { Tables.TypeDef, Tables.MethodDef, Tables.XAssembly }),
                new EncodingDesc("MemberRefParent", 3,
                  // TypeDef isn't documented, but it's allowed
                  new Tables[] { Tables.TypeDef, Tables.TypeRef, Tables.ModuleRef, Tables.MethodDef, Tables.TypeSpec }), 
                new EncodingDesc("HasSemantics", 1,
                  new Tables[] { Tables.XEvent, Tables.XProperty }), 
                new EncodingDesc("MethodDefOrRef", 1, 
                  new Tables[] { Tables.MethodDef, Tables.MemberRef }),
                new EncodingDesc("MemberForwarded", 1, 
                  new Tables[] { Tables.FieldDef, Tables.MethodDef }),
                new EncodingDesc("Implementation", 2,
                  new Tables[] { Tables.File, Tables.AssemblyRef, Tables.ExportedType }),
                new EncodingDesc("CustomAttributeType", 3, 
                  new Tables[] { Tables.Invalid, Tables.Invalid, Tables.MethodDef, Tables.MemberRef }),
                new EncodingDesc("ResolutionScope", 2, 
                  new Tables[] { Tables.XModule, Tables.ModuleRef, Tables.AssemblyRef, Tables.TypeRef }), 
                new EncodingDesc("TypeOrMethodDef", 1,
                  new Tables[] { Tables.TypeDef, Tables.MethodDef }) 
            };

        internal MDTables(BinaryReader reader, StreamDesc stringSD, StreamDesc blobSD)
        { // Positioned at start of #~ stream 
            stringStream = stringSD;
            blobStream = blobSD; 
            B = reader; 
            B.BaseStream.Seek(4, SeekOrigin.Current);   // Skip reserved
            byte Major = B.ReadByte(); 
            byte Minor = B.ReadByte();
            // Console.WriteLine("Table schema version {0}.{1}", Major, Minor);
            byte HeapSizes = B.ReadByte();
            stringIndex = ((HeapSizes & 0x01) == 0) ? 2U : 4U; 
            GUIDIndex = ((HeapSizes & 0x02) == 0) ? 2U : 4U;
            blobIndex = ((HeapSizes & 0x04) == 0) ? 2U : 4U; 
            B.ReadByte();   // Reserved 
            UInt64 Valid = B.ReadUInt64();
            UInt64 Sorted = B.ReadUInt64(); 
            NRows = new UInt32[(Int32)Tables.MaxTable + 1];
            int NTables = 0;
            UInt64 VBit = 1UL;
            for (int Table = 0; Table <= (int)Tables.MaxTable; Table++, VBit <<= 1) 
            {
                if ((Valid & VBit) != 0) 
                { 
                    NRows[Table] = B.ReadUInt32();
                    if (NRows[Table] == 0) 
                    {
                        //Console.WriteLine("Table {0} is valid with 0 rows", Table);
                    }
                    // Console.WriteLine("Table {0} ({1}) has {2} rows", Names[Table], Table, NRows[Table]); 
                    NTables += 1;
                } 
            } 
            // Console.WriteLine("Found {0} tables", NTables);
            ComputeRowLengths(); 
            /*
            for (int i = 0; i <= (int) Tables.MaxTable; i++)
                Console.WriteLine("Table {0} ({1}) has {2} bytes per row",
                    Names[i], i, lengths[i]); 
             */
            tableAt = new UInt32[(Int32)Tables.MaxTable + 1]; 
            VBit = 1UL; 
            UInt32 Offset = (UInt32)B.BaseStream.Position;
            for (int Table = 0; Table <= (int)Tables.MaxTable; Table++, VBit <<= 1) 
            {
                tableAt[Table] = Offset;
                // Console.WriteLine("Table {2} ({0}) at offset 0x{1:x}", Table, Offset, Names[(UInt32)Table]);
                Offset += lengths[Table] * NRows[Table]; 
                if (((Valid & VBit) != 0) && (NRows[Table] != 0) && (lengths[Table] == 0))
                    throw new BadImageFormatException(String.Format(CultureInfo.CurrentCulture, Res.UnknownMetadataTable, Table)); 
            } 
        }
 
        UInt32 MetadataTokenSize(Encodings Which)
        {
            EncodingDesc E = EncodingDescs[(int) Which];
            int TagBits = E.TagBits; 
            UInt32 MaxRows = 0;
            foreach (Tables Table in E.WhichTables) 
            { 
                if (Table == Tables.Invalid) continue;
                UInt32 N = NRows[(int)Table]; 
                if (N > MaxRows) MaxRows = N;
            }
            return (MaxRows < (1 << (16 - TagBits))) ? 2U : 4U;
        } 

        UInt32 RowSize(Tables Table) 
        { 
            return (NRows[(int) Table] < (1 << 16)) ? 2U : 4U;
        } 

        private void ComputeRowLengths()
        {
            lengths = new UInt32[(Int32)Tables.MaxTable + 1]; 
            lengths[(Int32)Tables.XAssembly] = 4 + 4 * 2 + 4 + blobIndex + 2 * stringIndex;
            lengths[(Int32)Tables.AssemblyOS] = 4 * 3; 
            lengths[(Int32)Tables.AssemblyProcessor] = 4; 
            lengths[(Int32)Tables.AssemblyRef] = 4 * 2 + 4 + 2 * blobIndex + 2 * stringIndex;
            lengths[(Int32)Tables.AssemblyRefOS] = 3 * 4 + RowSize(Tables.AssemblyRef); 
            lengths[(Int32)Tables.AssemblyRefProcessor] = 4 + RowSize(Tables.AssemblyRef);
            lengths[(Int32)Tables.ClassLayout] = 2 + 4 + RowSize(Tables.TypeDef);
            lengths[(Int32)Tables.Constant] = 1 + 1 + MetadataTokenSize(Encodings.HasConstant) + blobIndex;
            lengths[(Int32)Tables.CustomAttribute] = MetadataTokenSize(Encodings.HasCustomAttribute) + 
                MetadataTokenSize(Encodings.CustomAttributeType) + blobIndex;
            lengths[(Int32)Tables.DeclSecurity] = 2 + MetadataTokenSize(Encodings.HasDeclSecurity) + blobIndex; 
            lengths[(Int32)Tables.EventMap] = RowSize(Tables.TypeDef) + RowSize(Tables.XEvent); 
            lengths[(Int32)Tables.XEvent] = 2 + stringIndex + MetadataTokenSize(Encodings.TypeDefOrRef);
            lengths[(Int32)Tables.ExportedType] = 4 + 4 + stringIndex*2 + MetadataTokenSize(Encodings.Implementation); 
            lengths[(Int32)Tables.FieldDef] = 2 + stringIndex + blobIndex;
            lengths[(Int32)Tables.FieldLayout] = 4 + RowSize(Tables.FieldDef);
            lengths[(Int32)Tables.FieldMarshal] = MetadataTokenSize(Encodings.HasFieldMarshall) + blobIndex;
            lengths[(Int32)Tables.FieldRVA] = 4 + RowSize(Tables.FieldDef); 
            lengths[(Int32)Tables.File] = 4 + stringIndex + blobIndex;
            lengths[(Int32)Tables.GenericParam] = 2 + 2 + MetadataTokenSize(Encodings.TypeOrMethodDef) + stringIndex; 
            lengths[(Int32)Tables.GenericMethod] = MetadataTokenSize(Encodings.MethodDefOrRef) + blobIndex; 
            lengths[(Int32)Tables.GenericConstraint] = RowSize(Tables.GenericParam) + MetadataTokenSize(Encodings.TypeDefOrRef);
            lengths[(Int32)Tables.ImplMap] = 2 + MetadataTokenSize(Encodings.MemberForwarded) + stringIndex + 
                RowSize(Tables.ModuleRef);
            lengths[(Int32)Tables.InterfaceImpl] = RowSize(Tables.TypeDef) + MetadataTokenSize(Encodings.TypeDefOrRef);
            lengths[(Int32)Tables.ManifestResource] = 4 + 4 + stringIndex + MetadataTokenSize(Encodings.Implementation);
            lengths[(Int32)Tables.MemberRef] = MetadataTokenSize(Encodings.MemberRefParent) + stringIndex + 
                blobIndex;
            lengths[(Int32)Tables.MethodDef] = 4 + 2 + 2 + stringIndex + 
                blobIndex + RowSize(Tables.ParamDef); 
            lengths[(Int32)Tables.MethodImpl] = RowSize(Tables.TypeDef) + MetadataTokenSize(Encodings.MethodDefOrRef) * 2;
            lengths[(Int32)Tables.MethodSemantics] = 2 + RowSize(Tables.MethodDef) + MetadataTokenSize(Encodings.HasSemantics); 
            lengths[(Int32)Tables.XModule] = 2 + stringIndex + GUIDIndex * 3;
            lengths[(Int32)Tables.ModuleRef] = stringIndex;
            lengths[(Int32)Tables.NestedClass] = RowSize(Tables.TypeDef) * 2;
            lengths[(Int32)Tables.ParamDef] = 2 + 2 + stringIndex; 
            lengths[(Int32)Tables.XProperty] = 2 + stringIndex + blobIndex;
            lengths[(Int32)Tables.PropertyMap] = RowSize(Tables.TypeDef) + RowSize(Tables.XProperty); 
            lengths[(Int32)Tables.StandAloneSig] = blobIndex; 
            lengths[(Int32)Tables.TypeDef] = 4 + stringIndex*2 + MetadataTokenSize(Encodings.TypeDefOrRef) +
                RowSize(Tables.FieldDef) + RowSize(Tables.MethodDef); 
            lengths[(Int32)Tables.TypeRef] = MetadataTokenSize(Encodings.ResolutionScope) + stringIndex*2;
            lengths[(Int32)Tables.TypeSpec] = blobIndex;
// Non-public
		    lengths[(Int32)Tables.FieldPtr] = RowSize(Tables.FieldDef); 
            lengths[(Int32)Tables.MethodPtr] = RowSize(Tables.MethodDef);
            lengths[(Int32)Tables.ParamPtr] = RowSize(Tables.ParamDef); 
            lengths[(Int32)Tables.EventPtr] = RowSize(Tables.XEvent); 
            lengths[(Int32)Tables.PropertyPtr] = RowSize(Tables.XProperty);
            return; 
        }

        // This method is great for iterating over rows, starting at 0.  But metadata tokens start
        // numbering at row 1.  So this can't be used if you've retrieved a token from the metadata! 
        internal void SeekToRowOfTable(Tables T, UInt32 Row)
        { 
            if (Row >= NRows[(Int32) T]) 
                throw new BadImageFormatException(
                    String.Format(CultureInfo.CurrentCulture, Res.InvalidMetadataTokenTooManyRows, 
                                  Row, T, Names[(Int32) T], NRows[(Int32) T]));
            B.BaseStream.Seek(tableAt[(Int32)T]+Row*lengths[(Int32)T], SeekOrigin.Begin);
        }
 
        // Use this method whenever using a MetadataToken, otherwise you'll be off by 1!
        internal void SeekToMDToken(MetadataToken token) 
        { 
            if (token.Index == 0)
                throw new BadImageFormatException(String.Format(CultureInfo.CurrentCulture, Res.NilMetadataToken, token)); 
            SeekToRowOfTable(token.Table, token.Index - 1);
        }

        internal UInt32 ReadStringIndex() 
        {
            if (stringIndex == 2) return (UInt32)B.ReadUInt16(); 
            else return B.ReadUInt32(); 
        }
 
        private String GetString(UInt32 index)
        { // Read a string from the string stream
            stringStream.SeekTo(B, index);
            return ReadNextString(); 
        }
 
        private String ReadNextString() 
        {
            List bytes = new List(); 
            byte next;
            while ((next = B.ReadByte()) != 0)
                bytes.Add(next);
            return Encoder.GetString(bytes.ToArray()); 
        }
 
        /* 
        internal void DumpStringHeap(TextWriter output)
        { 
            stringStream.SeekTo(B, 0);
            long Start = B.BaseStream.Position;
            long End = Start + stringStream.Size - 1;
            output.WriteLine("String heap: {0}(0x{0:x}) bytes", End - Start); 
            for (long i = Start; i < End; i = B.BaseStream.Position)
            { 
                output.WriteLine("0x{0:x}: '{1}'", i - Start, ReadNextString()); 
            }
        } 
         */

        internal byte[] ReadBlob()
        { 
            UInt32 Index = ReadBlobIndex();
            if (Index == 0) return null; 
            UInt32 Position = (UInt32)B.BaseStream.Position; 
            blobStream.SeekTo(B, Index);
            UInt32 NBytes = (UInt32)B.ReadByte(); 
            Byte[] Result = null;
            if ((NBytes & 0x80) != 0)
            {
                if ((NBytes & 0xC0) == 0x80) 
                    NBytes = ((NBytes & 0x7F) << 8) + B.ReadByte();
                else NBytes = ((NBytes & 0x7F) << 24) + 
                    (UInt16)(B.ReadByte() << 16) + 
                    (B.ReadUInt16());
            } 
            if (NBytes != 0)
            {
                Result = new byte[NBytes];
                for (UInt32 i = 0; i < NBytes; i++) 
                    Result[i] = B.ReadByte();
            } 
            B.BaseStream.Seek(Position, SeekOrigin.Begin); 
            return Result;
        } 

        internal String ReadString()
        {
            UInt32 index = ReadStringIndex(); 
            UInt32 position = (UInt32) B.BaseStream.Position;
            String result = GetString(index); 
            B.BaseStream.Seek(position, SeekOrigin.Begin); 
            return result;
        } 

        /*
        internal UInt32 ReadGUIDIndex()
        { 
            if (GUIDIndex == 2)
                return (UInt32)B.ReadUInt16(); 
            else 
                return B.ReadUInt32();
        } 
        */

        internal UInt32 ReadBlobIndex()
        { 
            if (blobIndex == 2)
                return (UInt32)B.ReadUInt16(); 
            else 
                return B.ReadUInt32();
        } 

        internal UInt32 ReadRowIndex(Tables T)
        {
            if (RowSize(T) == 2) 
                return (UInt32)B.ReadUInt16();
            else 
                return B.ReadUInt32(); 
        }
 
        internal UInt32 RowsInTable(Tables T)
        {
            return NRows[(UInt32)T];
        } 

        /* 
        internal UInt32 ReadEncodedInt() 
        {
            byte first = B.ReadByte(); 
            if ((first & 0x80) == 0)
                return first;
            byte second = B.ReadByte();
            if ((first & 0xC0) == 0x80) 
                return ((uint)(first & 0x7F)) << 8 | second;
            else if ((first & 0xE0) == 0xC0) 
            { 
                byte third = B.ReadByte();
                byte fourth = B.ReadByte(); 
                return ((uint)(first & 0x1F) << 24) | ((uint)second) << 16 | ((uint)third) << 8 | (uint)fourth;
            }
            else
                throw new BadImageFormatException(Res.InvalidCompressedInt); 
        }
        */ 
 
        internal MetadataToken ReadMetadataToken(Encodings E)
        { 
            UInt32 Code = (MetadataTokenSize(E) == 2) ? B.ReadUInt16() : B.ReadUInt32();
            MetadataToken Result;
            EncodingDesc Desc = EncodingDescs[(Int32)E];
            Tables[] Ts = Desc.WhichTables; 
            UInt32 Mask = (1U << Desc.TagBits) - 1;
            Result.Table = Ts[Code & Mask]; 
            Result.Index = Code >> Desc.TagBits; 
            if (Result.Table == Tables.Invalid)
                throw new BadImageFormatException(Res.InvalidMetadataTokenNilTable); 
            return Result;
        }
    }
} 

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