The NameTable Object

CCI Metadata

The first step for many CCI Metadata applications is to create a Microsoft.Cci.NameTable object. NameTable is a container for a table of key-value pairs, and is used by the host and other members of the CCI Metadata library to speed up string-comparison. Each value is a string and the associated key is a unique integer. NameTable thus allows you to test string equality by comparing two integers, instead of using the much more expensive character-by-character comparison.

A newly created NameTable object is empty. You add appropriate strings for your application, such as assembly or method names, by passing each string to the NameTable.GetNameFor method. GetNameFor creates a unique key for the string, stores the data, and returns the key-value pair as a Microsoft.Cci.IName interface. If the string is already in the table, GetNameFor simply returns the appropriate IName interface, so you can also use the method to look up keys.

The IName Interface

The IName interface represents strings in the CCI environment. It has three read-only properties:
  • Value is the string.
  • UniqueKey is a unique integer that is assigned to the string, and is used for case-sensitive string comparisons. It can also be used as a hash table key.
  • UniqueKeyIgnoringCase is a unique integer that is assigned to the string, and is used for case-insensitive string comparisons. It can also be used as a hash table key.

CCI Metadata methods usually take names as IName interfaces. As a practical matter, when you need a name’s IName interface, pass the string to GetNameFor. You don’t need to know if the string is in the table. In either case, GetNameFor returns the interface and silently takes care of any further details. For example, the following code creates a method definition object for Console.WriteLine. The second GetMethod argument is an IName interface for the method name.
IMethodDefinition writeLine = TypeHelper.GetMethod(systemConsole,
                                                   nameTable.GetNameFor("WriteLine"),
                                                   host.PlatformType.SystemString);

Using the NameTable Object

You must pass the NameTable object to a variety of other CCI methods, which also use the table to improve string comparison performance. For example, the following example calls UnitHelper.FindType to create a NamedTypeDefinition object for the System.Console type. FindType takes a NameTable object as its first parameter and returns an INamedTypeDefinition interface.
INamedTypeDefinition systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console");

The FindType method’s first parameter is actually an INameTable interface. However, this does not mean that the method does not have an opportunity to change the name table. In fact, the purpose of passing in the name table in the example is to allow FindType to split "System.Console" into IName objects for "System" and "Console" respectively and then use those objects to efficiently search for the namespace and type. The reason FindType insists on the INameTable interface rather than the concrete class, is to allow clients to use a different implementation of INameTable.GetNameFor and related properties.

What you pass to FindType is thus a mutable object, despite the general convention documented in Mutable and Immutable Representations. This means that malicious code could use an INameTable interface to allocate memory until the application crashes. However, malicious code has other ways to allocate enough memory to bring down an application domain, so leaking an INameTable interface to untrusted code does create any new security risks.

Last edited Mar 17, 2010 at 3:10 PM by Guy_Smith, version 6

Comments

Qwertie Dec 21, 2009 at 5:35 PM 
This NameTable concept is remarkably similar to the idea of private SymbolPools that I recently described on CodeProject, although I described them as a way to make estensible Enums... and judging by votes, readers hated the idea.