Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Actions / ExpandoClass.cs / 1305376 / ExpandoClass.cs
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Microsoft Public License. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Microsoft Public License, please send an email to
* dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Microsoft Public License.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Dynamic.Utils;
using System.Text;
namespace System.Dynamic {
///
/// Represents a dynamically assigned class. Expando objects which share the same
/// members will share the same class. Classes are dynamically assigned as the
/// expando object gains members.
///
internal class ExpandoClass {
private readonly string[] _keys; // list of names associated with each element in the data array, sorted
private readonly int _hashCode; // pre-calculated hash code of all the keys the class contains
private Dictionary> _transitions; // cached transitions
private const int EmptyHashCode = 6551; // hash code of the empty ExpandoClass.
internal static ExpandoClass Empty = new ExpandoClass(); // The empty Expando class - all Expando objects start off w/ this class.
///
/// Constructs the empty ExpandoClass. This is the class used when an
/// empty Expando object is initially constructed.
///
internal ExpandoClass() {
_hashCode = EmptyHashCode;
_keys = new string[0];
}
///
/// Constructs a new ExpandoClass that can hold onto the specified keys. The
/// keys must be sorted ordinally. The hash code must be precalculated for
/// the keys.
///
internal ExpandoClass(string[] keys, int hashCode) {
_hashCode = hashCode;
_keys = keys;
}
///
/// Finds or creates a new ExpandoClass given the existing set of keys
/// in this ExpandoClass plus the new key to be added. Members in an
/// ExpandoClass are always stored case sensitively.
///
internal ExpandoClass FindNewClass(string newKey) {
// just XOR the newKey hash code
int hashCode = _hashCode ^ newKey.GetHashCode();
lock (this) {
List infos = GetTransitionList(hashCode);
for (int i = 0; i < infos.Count; i++) {
ExpandoClass klass = infos[i].Target as ExpandoClass;
if (klass == null) {
infos.RemoveAt(i);
i--;
continue;
}
if (string.Equals(klass._keys[klass._keys.Length - 1], newKey, StringComparison.Ordinal)) {
// the new key is the key we added in this transition
return klass;
}
}
// no applicable transition, create a new one
string[] keys = new string[_keys.Length + 1];
Array.Copy(_keys, keys, _keys.Length);
keys[_keys.Length] = newKey;
ExpandoClass ec = new ExpandoClass(keys, hashCode);
infos.Add(new WeakReference(ec));
return ec;
}
}
///
/// Gets the lists of transitions that are valid from this ExpandoClass
/// to an ExpandoClass whos keys hash to the apporopriate hash code.
///
private List GetTransitionList(int hashCode) {
if (_transitions == null) {
_transitions = new Dictionary>();
}
List infos;
if (!_transitions.TryGetValue(hashCode, out infos)) {
_transitions[hashCode] = infos = new List();
}
return infos;
}
///
/// Gets the index at which the value should be stored for the specified name.
///
internal int GetValueIndex(string name, bool caseInsensitive, ExpandoObject obj) {
if (caseInsensitive) {
return GetValueIndexCaseInsensitive(name, obj);
} else {
return GetValueIndexCaseSensitive(name);
}
}
///
/// Gets the index at which the value should be stored for the specified name
/// case sensitively. Returns the index even if the member is marked as deleted.
///
internal int GetValueIndexCaseSensitive(string name) {
for (int i = 0; i < _keys.Length; i++) {
if (string.Equals(
_keys[i],
name,
StringComparison.Ordinal)) {
return i;
}
}
return ExpandoObject.NoMatch;
}
///
/// Gets the index at which the value should be stored for the specified name,
/// the method is only used in the case-insensitive case.
///
/// the name of the member
/// The ExpandoObject associated with the class
/// that is used to check if a member has been deleted.
///
/// the exact match if there is one
/// if there is exactly one member with case insensitive match, return it
/// otherwise we throw AmbiguousMatchException.
///
private int GetValueIndexCaseInsensitive(string name, ExpandoObject obj) {
int caseInsensitiveMatch = ExpandoObject.NoMatch; //the location of the case-insensitive matching member
lock (obj.LockObject) {
for (int i = _keys.Length - 1; i >= 0; i--) {
if (string.Equals(
_keys[i],
name,
StringComparison.OrdinalIgnoreCase)) {
//if the matching member is deleted, continue searching
if (!obj.IsDeletedMember(i)) {
if (caseInsensitiveMatch == ExpandoObject.NoMatch) {
caseInsensitiveMatch = i;
} else {
//Ambigous match, stop searching
return ExpandoObject.AmbiguousMatchFound;
}
}
}
}
}
//There is exactly one member with case insensitive match.
return caseInsensitiveMatch;
}
///
/// Gets the names of the keys that can be stored in the Expando class. The
/// list is sorted ordinally.
///
internal string[] Keys {
get {
return _keys;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Microsoft Public License. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Microsoft Public License, please send an email to
* dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Microsoft Public License.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Dynamic.Utils;
using System.Text;
namespace System.Dynamic {
///
/// Represents a dynamically assigned class. Expando objects which share the same
/// members will share the same class. Classes are dynamically assigned as the
/// expando object gains members.
///
internal class ExpandoClass {
private readonly string[] _keys; // list of names associated with each element in the data array, sorted
private readonly int _hashCode; // pre-calculated hash code of all the keys the class contains
private Dictionary> _transitions; // cached transitions
private const int EmptyHashCode = 6551; // hash code of the empty ExpandoClass.
internal static ExpandoClass Empty = new ExpandoClass(); // The empty Expando class - all Expando objects start off w/ this class.
///
/// Constructs the empty ExpandoClass. This is the class used when an
/// empty Expando object is initially constructed.
///
internal ExpandoClass() {
_hashCode = EmptyHashCode;
_keys = new string[0];
}
///
/// Constructs a new ExpandoClass that can hold onto the specified keys. The
/// keys must be sorted ordinally. The hash code must be precalculated for
/// the keys.
///
internal ExpandoClass(string[] keys, int hashCode) {
_hashCode = hashCode;
_keys = keys;
}
///
/// Finds or creates a new ExpandoClass given the existing set of keys
/// in this ExpandoClass plus the new key to be added. Members in an
/// ExpandoClass are always stored case sensitively.
///
internal ExpandoClass FindNewClass(string newKey) {
// just XOR the newKey hash code
int hashCode = _hashCode ^ newKey.GetHashCode();
lock (this) {
List infos = GetTransitionList(hashCode);
for (int i = 0; i < infos.Count; i++) {
ExpandoClass klass = infos[i].Target as ExpandoClass;
if (klass == null) {
infos.RemoveAt(i);
i--;
continue;
}
if (string.Equals(klass._keys[klass._keys.Length - 1], newKey, StringComparison.Ordinal)) {
// the new key is the key we added in this transition
return klass;
}
}
// no applicable transition, create a new one
string[] keys = new string[_keys.Length + 1];
Array.Copy(_keys, keys, _keys.Length);
keys[_keys.Length] = newKey;
ExpandoClass ec = new ExpandoClass(keys, hashCode);
infos.Add(new WeakReference(ec));
return ec;
}
}
///
/// Gets the lists of transitions that are valid from this ExpandoClass
/// to an ExpandoClass whos keys hash to the apporopriate hash code.
///
private List GetTransitionList(int hashCode) {
if (_transitions == null) {
_transitions = new Dictionary>();
}
List infos;
if (!_transitions.TryGetValue(hashCode, out infos)) {
_transitions[hashCode] = infos = new List();
}
return infos;
}
///
/// Gets the index at which the value should be stored for the specified name.
///
internal int GetValueIndex(string name, bool caseInsensitive, ExpandoObject obj) {
if (caseInsensitive) {
return GetValueIndexCaseInsensitive(name, obj);
} else {
return GetValueIndexCaseSensitive(name);
}
}
///
/// Gets the index at which the value should be stored for the specified name
/// case sensitively. Returns the index even if the member is marked as deleted.
///
internal int GetValueIndexCaseSensitive(string name) {
for (int i = 0; i < _keys.Length; i++) {
if (string.Equals(
_keys[i],
name,
StringComparison.Ordinal)) {
return i;
}
}
return ExpandoObject.NoMatch;
}
///
/// Gets the index at which the value should be stored for the specified name,
/// the method is only used in the case-insensitive case.
///
/// the name of the member
/// The ExpandoObject associated with the class
/// that is used to check if a member has been deleted.
///
/// the exact match if there is one
/// if there is exactly one member with case insensitive match, return it
/// otherwise we throw AmbiguousMatchException.
///
private int GetValueIndexCaseInsensitive(string name, ExpandoObject obj) {
int caseInsensitiveMatch = ExpandoObject.NoMatch; //the location of the case-insensitive matching member
lock (obj.LockObject) {
for (int i = _keys.Length - 1; i >= 0; i--) {
if (string.Equals(
_keys[i],
name,
StringComparison.OrdinalIgnoreCase)) {
//if the matching member is deleted, continue searching
if (!obj.IsDeletedMember(i)) {
if (caseInsensitiveMatch == ExpandoObject.NoMatch) {
caseInsensitiveMatch = i;
} else {
//Ambigous match, stop searching
return ExpandoObject.AmbiguousMatchFound;
}
}
}
}
}
//There is exactly one member with case insensitive match.
return caseInsensitiveMatch;
}
///
/// Gets the names of the keys that can be stored in the Expando class. The
/// list is sorted ordinally.
///
internal string[] Keys {
get {
return _keys;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- JapaneseLunisolarCalendar.cs
- WaveHeader.cs
- CodeMethodInvokeExpression.cs
- OdbcTransaction.cs
- FixedSOMPageConstructor.cs
- WebConfigurationHost.cs
- latinshape.cs
- MimeTypePropertyAttribute.cs
- DBAsyncResult.cs
- XappLauncher.cs
- FilteredAttributeCollection.cs
- ConstNode.cs
- TrackingServices.cs
- XmlIlTypeHelper.cs
- CollectionBase.cs
- DebugHandleTracker.cs
- XsltArgumentList.cs
- BrowserDefinition.cs
- ActivityIdHeader.cs
- WindowsListViewGroup.cs
- HandledMouseEvent.cs
- StreamGeometry.cs
- EventLogException.cs
- WmpBitmapDecoder.cs
- SByteStorage.cs
- DataObjectAttribute.cs
- RawAppCommandInputReport.cs
- TreeViewImageKeyConverter.cs
- AccessViolationException.cs
- PipelineModuleStepContainer.cs
- EventRouteFactory.cs
- HiddenFieldPageStatePersister.cs
- SafeUserTokenHandle.cs
- WebControlParameterProxy.cs
- GeometryHitTestResult.cs
- PkcsMisc.cs
- SecureStringHasher.cs
- ListControlDataBindingHandler.cs
- MetadataAssemblyHelper.cs
- DesignerToolboxInfo.cs
- ApplicationFileCodeDomTreeGenerator.cs
- MouseGestureConverter.cs
- Dispatcher.cs
- PropertyToken.cs
- CompModSwitches.cs
- CustomTypeDescriptor.cs
- RectangleF.cs
- OracleDateTime.cs
- CustomAttributeSerializer.cs
- Util.cs
- WebRequestModulesSection.cs
- UserValidatedEventArgs.cs
- ServiceMemoryGates.cs
- ResourceLoader.cs
- SafePointer.cs
- ComboBox.cs
- TextAdaptor.cs
- SafeRightsManagementHandle.cs
- TextEditorTables.cs
- EncryptedPackageFilter.cs
- SemaphoreFullException.cs
- RegularExpressionValidator.cs
- InternalConfigEventArgs.cs
- _IPv4Address.cs
- sqlpipe.cs
- UnsafeNativeMethods.cs
- ProfileGroupSettings.cs
- HtmlTernaryTree.cs
- PolyQuadraticBezierSegment.cs
- DtrList.cs
- GridItemPatternIdentifiers.cs
- NavigationProgressEventArgs.cs
- NameNode.cs
- SerTrace.cs
- PerformanceCounterCategory.cs
- Rotation3DAnimation.cs
- BufferedMessageData.cs
- SqlGatherProducedAliases.cs
- RawStylusInputCustomDataList.cs
- Point4D.cs
- Registry.cs
- XsdDateTime.cs
- XmlSchemaAppInfo.cs
- ContentValidator.cs
- ClearTypeHintValidation.cs
- EqualityComparer.cs
- ImageInfo.cs
- HttpRawResponse.cs
- ArraySubsetEnumerator.cs
- HttpDebugHandler.cs
- InvokerUtil.cs
- ResourceDefaultValueAttribute.cs
- SqlCommand.cs
- XmlILStorageConverter.cs
- BrushConverter.cs
- SqlExpander.cs
- CodeDomConfigurationHandler.cs
- SpeechUI.cs
- InputScope.cs
- Native.cs