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) { Listinfos = 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 ListGetTransitionList(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) { Listinfos = 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 ListGetTransitionList(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
- LassoHelper.cs
- DataServiceExpressionVisitor.cs
- FieldToken.cs
- AsyncStreamReader.cs
- CompletionBookmark.cs
- ObjectListSelectEventArgs.cs
- FindCriteriaApril2005.cs
- DispatcherOperation.cs
- DataGridViewLinkCell.cs
- UnsafeNativeMethods.cs
- LogWriteRestartAreaAsyncResult.cs
- AuthenticationService.cs
- CellTreeSimplifier.cs
- TextServicesPropertyRanges.cs
- ErrorWebPart.cs
- PartitionedStream.cs
- InitializerFacet.cs
- ColumnWidthChangingEvent.cs
- PathFigureCollectionValueSerializer.cs
- FileDialogPermission.cs
- BaseServiceProvider.cs
- DoubleUtil.cs
- BamlResourceSerializer.cs
- TreeViewAutomationPeer.cs
- PenCursorManager.cs
- ReturnEventArgs.cs
- SByteStorage.cs
- MenuEventArgs.cs
- ExpressionPrinter.cs
- LabelLiteral.cs
- OutputCacheModule.cs
- PrintPageEvent.cs
- CustomErrorCollection.cs
- StringArrayConverter.cs
- DataGridItemEventArgs.cs
- DNS.cs
- EntityContainerEntitySetDefiningQuery.cs
- FixedLineResult.cs
- StringConcat.cs
- XmlWhitespace.cs
- EmptyControlCollection.cs
- ArgumentsParser.cs
- PageHandlerFactory.cs
- SoapSchemaExporter.cs
- DefaultIfEmptyQueryOperator.cs
- ArrayListCollectionBase.cs
- ImmutablePropertyDescriptorGridEntry.cs
- WebServiceErrorEvent.cs
- ComponentEvent.cs
- WebPartActionVerb.cs
- CellRelation.cs
- HttpRequest.cs
- KeysConverter.cs
- ResourceAttributes.cs
- InvokeHandlers.cs
- RuleSettings.cs
- ExpressionBuilder.cs
- AssemblyAttributes.cs
- DataGridCaption.cs
- TrustLevel.cs
- DataTableReader.cs
- CounterSampleCalculator.cs
- HwndTarget.cs
- RequestQueue.cs
- SmtpReplyReaderFactory.cs
- TripleDESCryptoServiceProvider.cs
- Crc32.cs
- ToolStripGrip.cs
- Transform3DGroup.cs
- JpegBitmapDecoder.cs
- DurableInstanceContextProvider.cs
- XXXInfos.cs
- BufferedWebEventProvider.cs
- CompensationHandlingFilter.cs
- RuntimeConfigurationRecord.cs
- Lazy.cs
- ApplicationSecurityManager.cs
- ArgumentException.cs
- ChtmlMobileTextWriter.cs
- ProviderCollection.cs
- SafeLocalMemHandle.cs
- BooleanFunctions.cs
- PermissionSetEnumerator.cs
- UriTemplateTrieLocation.cs
- MetadataWorkspace.cs
- oledbmetadatacollectionnames.cs
- FullTextBreakpoint.cs
- BasePropertyDescriptor.cs
- ListItemCollection.cs
- BinaryFormatter.cs
- LogReservationCollection.cs
- SeparatorAutomationPeer.cs
- TrackingServices.cs
- SimpleWebHandlerParser.cs
- FileDetails.cs
- DXD.cs
- ConsoleCancelEventArgs.cs
- FontWeight.cs
- ParsedAttributeCollection.cs
- QueueProcessor.cs