Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / XmlSortKey.cs / 1 / XmlSortKey.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Globalization; namespace System.Xml.Xsl.Runtime { ////// Base internal class for all sort keys. /// Inherits from IComparable, so that Array.Sort can perform comparison. /// internal abstract class XmlSortKey : IComparable { private int priority; // Original input ordering used to ensure that sort is stable private XmlSortKey nextKey; // Next sort key if there are multiple keys (null otherwise) ////// Get or set this key's index, relative to other keys involved in a sort. This priority will /// break ties. If the priority is not set, then the sort will not be stable. /// public int Priority { //get { return this.priority; } set { // All linked keys have same priority XmlSortKey key = this; while (key != null) { key.priority = value; key = key.nextKey; } } } ////// Sometimes a key is composed of multiple parts. For example: (LastName, FirstName). Multi-part /// keys are linked together in a list. This method recursively adds a new key part to the end of the list. /// Returns the first (primary) key in the list. /// public XmlSortKey AddSortKey(XmlSortKey sortKey) { if (this.nextKey != null) { // Add to end of list--this is not it this.nextKey.AddSortKey(sortKey); } else { // This is the end of the list this.nextKey = sortKey; } return this; } ////// When two keys are compared and found to be equal, the tie must be broken. If there is a secondary key, /// then use that to break the tie. Otherwise, use the input ordering to break the tie. Since every key /// has a unique index, this is guaranteed to always break the tie. /// protected int BreakSortingTie(XmlSortKey that) { if (this.nextKey != null) { // There are multiple keys, so break tie using next key Debug.Assert(this.nextKey != null && that.nextKey != null); return this.nextKey.CompareTo(that.nextKey); } Debug.Assert(this.priority != that.priority); return (this.priority < that.priority) ? -1 : 1; } ////// Compare a non-empty key (this) to an empty key (obj). The empty sequence always sorts either before all /// other values, or after all other values. /// protected int CompareToEmpty(object obj) { XmlEmptySortKey that = obj as XmlEmptySortKey; Debug.Assert(that != null && !(this is XmlEmptySortKey)); return that.IsEmptyGreatest ? -1 : 1; } ////// Base internal class is abstract and doesn't actually implement CompareTo; derived classes must do this. /// public abstract int CompareTo(object that); } ////// Sort key for the empty sequence. Empty sequence always compares sorts either before all other values, /// or after all other values. /// internal class XmlEmptySortKey : XmlSortKey { private bool isEmptyGreatest; public XmlEmptySortKey(XmlCollation collation) { // Greatest, Ascending: isEmptyGreatest = true // Greatest, Descending: isEmptyGreatest = false // Least, Ascending: isEmptyGreatest = false // Least, Descending: isEmptyGreatest = true this.isEmptyGreatest = collation.EmptyGreatest != collation.DescendingOrder; } public bool IsEmptyGreatest { get { return this.isEmptyGreatest; } } public override int CompareTo(object obj) { XmlEmptySortKey that = obj as XmlEmptySortKey; if (that == null) { // Empty compared to non-empty Debug.Assert(obj is XmlSortKey); return -(obj as XmlSortKey).CompareTo(this); } // Empty compared to empty return BreakSortingTie(that); } } ////// Sort key for xs:decimal values. /// internal class XmlDecimalSortKey : XmlSortKey { private decimal decVal; public XmlDecimalSortKey(decimal value, XmlCollation collation) { // Invert decimal if sorting in descending order this.decVal = collation.DescendingOrder ? -value : value; } public override int CompareTo(object obj) { XmlDecimalSortKey that = obj as XmlDecimalSortKey; int cmp; if (that == null) return CompareToEmpty(obj); cmp = Decimal.Compare(this.decVal, that.decVal); if (cmp == 0) return BreakSortingTie(that); return cmp; } } ////// Sort key for xs:integer values. /// internal class XmlIntegerSortKey : XmlSortKey { private long longVal; public XmlIntegerSortKey(long value, XmlCollation collation) { // Invert long if sorting in descending order this.longVal = collation.DescendingOrder ? ~value : value; } public override int CompareTo(object obj) { XmlIntegerSortKey that = obj as XmlIntegerSortKey; if (that == null) return CompareToEmpty(obj); if (this.longVal == that.longVal) return BreakSortingTie(that); return (this.longVal < that.longVal) ? -1 : 1; } } ////// Sort key for xs:int values. /// internal class XmlIntSortKey : XmlSortKey { private int intVal; public XmlIntSortKey(int value, XmlCollation collation) { // Invert integer if sorting in descending order this.intVal = collation.DescendingOrder ? ~value : value; } public override int CompareTo(object obj) { XmlIntSortKey that = obj as XmlIntSortKey; if (that == null) return CompareToEmpty(obj); if (this.intVal == that.intVal) return BreakSortingTie(that); return (this.intVal < that.intVal) ? -1 : 1; } } ////// Sort key for xs:string values. Strings are sorted according to a byte-wise sort key calculated by caller. /// internal class XmlStringSortKey : XmlSortKey { private SortKey sortKey; private byte[] sortKeyBytes; private bool descendingOrder; public XmlStringSortKey(SortKey sortKey, bool descendingOrder) { this.sortKey = sortKey; this.descendingOrder = descendingOrder; } public XmlStringSortKey(byte[] sortKey, bool descendingOrder) { this.sortKeyBytes = sortKey; this.descendingOrder = descendingOrder; } public override int CompareTo(object obj) { XmlStringSortKey that = obj as XmlStringSortKey; int idx, cntCmp, result; if (that == null) return CompareToEmpty(obj); // Compare either using SortKey.Compare or byte arrays if (this.sortKey != null) { Debug.Assert(that.sortKey != null, "Both keys must have non-null sortKey field"); result = SortKey.Compare(this.sortKey, that.sortKey); } else { Debug.Assert(this.sortKeyBytes != null && that.sortKeyBytes != null, "Both keys must have non-null sortKeyBytes field"); cntCmp = (this.sortKeyBytes.Length < that.sortKeyBytes.Length) ? this.sortKeyBytes.Length : that.sortKeyBytes.Length; for (idx = 0; idx < cntCmp; idx++) { if (this.sortKeyBytes[idx] < that.sortKeyBytes[idx]) { result = -1; goto Done; } if (this.sortKeyBytes[idx] > that.sortKeyBytes[idx]) { result = 1; goto Done; } } // So far, keys are equal, so now test length of each key if (this.sortKeyBytes.Length < that.sortKeyBytes.Length) result = -1; else if (this.sortKeyBytes.Length > that.sortKeyBytes.Length) result = 1; else result = 0; } Done: // Use document order to break sorting tie if (result == 0) return BreakSortingTie(that); return this.descendingOrder ? -result : result; } } ////// Sort key for Double values. /// internal class XmlDoubleSortKey : XmlSortKey { private double dblVal; private bool isNaN; public XmlDoubleSortKey(double value, XmlCollation collation) { if (Double.IsNaN(value)) { // Treat NaN as if it were the empty sequence this.isNaN = true; // Greatest, Ascending: isEmptyGreatest = true // Greatest, Descending: isEmptyGreatest = false // Least, Ascending: isEmptyGreatest = false // Least, Descending: isEmptyGreatest = true this.dblVal = (collation.EmptyGreatest != collation.DescendingOrder) ? Double.PositiveInfinity : Double.NegativeInfinity; } else { this.dblVal = collation.DescendingOrder ? -value : value; } } public override int CompareTo(object obj) { XmlDoubleSortKey that = obj as XmlDoubleSortKey; if (that == null) { // Compare to empty sequence if (this.isNaN) return BreakSortingTie(obj as XmlSortKey); return CompareToEmpty(obj); } if (this.dblVal == that.dblVal) { if (this.isNaN) { // NaN sorts equal to NaN if (that.isNaN) return BreakSortingTie(that); // NaN sorts before or after all non-NaN values Debug.Assert(this.dblVal == Double.NegativeInfinity || this.dblVal == Double.PositiveInfinity); return (this.dblVal == Double.NegativeInfinity) ? -1 : 1; } else if (that.isNaN) { // NaN sorts before or after all non-NaN values Debug.Assert(that.dblVal == Double.NegativeInfinity || that.dblVal == Double.PositiveInfinity); return (that.dblVal == Double.NegativeInfinity) ? 1 : -1; } return BreakSortingTie(that); } return (this.dblVal < that.dblVal) ? -1 : 1; } } ////// Sort key for DateTime values (just convert DateTime to ticks and use Long sort key). /// internal class XmlDateTimeSortKey : XmlIntegerSortKey { public XmlDateTimeSortKey(DateTime value, XmlCollation collation) : base(value.Ticks, collation) { } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Globalization; namespace System.Xml.Xsl.Runtime { ////// Base internal class for all sort keys. /// Inherits from IComparable, so that Array.Sort can perform comparison. /// internal abstract class XmlSortKey : IComparable { private int priority; // Original input ordering used to ensure that sort is stable private XmlSortKey nextKey; // Next sort key if there are multiple keys (null otherwise) ////// Get or set this key's index, relative to other keys involved in a sort. This priority will /// break ties. If the priority is not set, then the sort will not be stable. /// public int Priority { //get { return this.priority; } set { // All linked keys have same priority XmlSortKey key = this; while (key != null) { key.priority = value; key = key.nextKey; } } } ////// Sometimes a key is composed of multiple parts. For example: (LastName, FirstName). Multi-part /// keys are linked together in a list. This method recursively adds a new key part to the end of the list. /// Returns the first (primary) key in the list. /// public XmlSortKey AddSortKey(XmlSortKey sortKey) { if (this.nextKey != null) { // Add to end of list--this is not it this.nextKey.AddSortKey(sortKey); } else { // This is the end of the list this.nextKey = sortKey; } return this; } ////// When two keys are compared and found to be equal, the tie must be broken. If there is a secondary key, /// then use that to break the tie. Otherwise, use the input ordering to break the tie. Since every key /// has a unique index, this is guaranteed to always break the tie. /// protected int BreakSortingTie(XmlSortKey that) { if (this.nextKey != null) { // There are multiple keys, so break tie using next key Debug.Assert(this.nextKey != null && that.nextKey != null); return this.nextKey.CompareTo(that.nextKey); } Debug.Assert(this.priority != that.priority); return (this.priority < that.priority) ? -1 : 1; } ////// Compare a non-empty key (this) to an empty key (obj). The empty sequence always sorts either before all /// other values, or after all other values. /// protected int CompareToEmpty(object obj) { XmlEmptySortKey that = obj as XmlEmptySortKey; Debug.Assert(that != null && !(this is XmlEmptySortKey)); return that.IsEmptyGreatest ? -1 : 1; } ////// Base internal class is abstract and doesn't actually implement CompareTo; derived classes must do this. /// public abstract int CompareTo(object that); } ////// Sort key for the empty sequence. Empty sequence always compares sorts either before all other values, /// or after all other values. /// internal class XmlEmptySortKey : XmlSortKey { private bool isEmptyGreatest; public XmlEmptySortKey(XmlCollation collation) { // Greatest, Ascending: isEmptyGreatest = true // Greatest, Descending: isEmptyGreatest = false // Least, Ascending: isEmptyGreatest = false // Least, Descending: isEmptyGreatest = true this.isEmptyGreatest = collation.EmptyGreatest != collation.DescendingOrder; } public bool IsEmptyGreatest { get { return this.isEmptyGreatest; } } public override int CompareTo(object obj) { XmlEmptySortKey that = obj as XmlEmptySortKey; if (that == null) { // Empty compared to non-empty Debug.Assert(obj is XmlSortKey); return -(obj as XmlSortKey).CompareTo(this); } // Empty compared to empty return BreakSortingTie(that); } } ////// Sort key for xs:decimal values. /// internal class XmlDecimalSortKey : XmlSortKey { private decimal decVal; public XmlDecimalSortKey(decimal value, XmlCollation collation) { // Invert decimal if sorting in descending order this.decVal = collation.DescendingOrder ? -value : value; } public override int CompareTo(object obj) { XmlDecimalSortKey that = obj as XmlDecimalSortKey; int cmp; if (that == null) return CompareToEmpty(obj); cmp = Decimal.Compare(this.decVal, that.decVal); if (cmp == 0) return BreakSortingTie(that); return cmp; } } ////// Sort key for xs:integer values. /// internal class XmlIntegerSortKey : XmlSortKey { private long longVal; public XmlIntegerSortKey(long value, XmlCollation collation) { // Invert long if sorting in descending order this.longVal = collation.DescendingOrder ? ~value : value; } public override int CompareTo(object obj) { XmlIntegerSortKey that = obj as XmlIntegerSortKey; if (that == null) return CompareToEmpty(obj); if (this.longVal == that.longVal) return BreakSortingTie(that); return (this.longVal < that.longVal) ? -1 : 1; } } ////// Sort key for xs:int values. /// internal class XmlIntSortKey : XmlSortKey { private int intVal; public XmlIntSortKey(int value, XmlCollation collation) { // Invert integer if sorting in descending order this.intVal = collation.DescendingOrder ? ~value : value; } public override int CompareTo(object obj) { XmlIntSortKey that = obj as XmlIntSortKey; if (that == null) return CompareToEmpty(obj); if (this.intVal == that.intVal) return BreakSortingTie(that); return (this.intVal < that.intVal) ? -1 : 1; } } ////// Sort key for xs:string values. Strings are sorted according to a byte-wise sort key calculated by caller. /// internal class XmlStringSortKey : XmlSortKey { private SortKey sortKey; private byte[] sortKeyBytes; private bool descendingOrder; public XmlStringSortKey(SortKey sortKey, bool descendingOrder) { this.sortKey = sortKey; this.descendingOrder = descendingOrder; } public XmlStringSortKey(byte[] sortKey, bool descendingOrder) { this.sortKeyBytes = sortKey; this.descendingOrder = descendingOrder; } public override int CompareTo(object obj) { XmlStringSortKey that = obj as XmlStringSortKey; int idx, cntCmp, result; if (that == null) return CompareToEmpty(obj); // Compare either using SortKey.Compare or byte arrays if (this.sortKey != null) { Debug.Assert(that.sortKey != null, "Both keys must have non-null sortKey field"); result = SortKey.Compare(this.sortKey, that.sortKey); } else { Debug.Assert(this.sortKeyBytes != null && that.sortKeyBytes != null, "Both keys must have non-null sortKeyBytes field"); cntCmp = (this.sortKeyBytes.Length < that.sortKeyBytes.Length) ? this.sortKeyBytes.Length : that.sortKeyBytes.Length; for (idx = 0; idx < cntCmp; idx++) { if (this.sortKeyBytes[idx] < that.sortKeyBytes[idx]) { result = -1; goto Done; } if (this.sortKeyBytes[idx] > that.sortKeyBytes[idx]) { result = 1; goto Done; } } // So far, keys are equal, so now test length of each key if (this.sortKeyBytes.Length < that.sortKeyBytes.Length) result = -1; else if (this.sortKeyBytes.Length > that.sortKeyBytes.Length) result = 1; else result = 0; } Done: // Use document order to break sorting tie if (result == 0) return BreakSortingTie(that); return this.descendingOrder ? -result : result; } } ////// Sort key for Double values. /// internal class XmlDoubleSortKey : XmlSortKey { private double dblVal; private bool isNaN; public XmlDoubleSortKey(double value, XmlCollation collation) { if (Double.IsNaN(value)) { // Treat NaN as if it were the empty sequence this.isNaN = true; // Greatest, Ascending: isEmptyGreatest = true // Greatest, Descending: isEmptyGreatest = false // Least, Ascending: isEmptyGreatest = false // Least, Descending: isEmptyGreatest = true this.dblVal = (collation.EmptyGreatest != collation.DescendingOrder) ? Double.PositiveInfinity : Double.NegativeInfinity; } else { this.dblVal = collation.DescendingOrder ? -value : value; } } public override int CompareTo(object obj) { XmlDoubleSortKey that = obj as XmlDoubleSortKey; if (that == null) { // Compare to empty sequence if (this.isNaN) return BreakSortingTie(obj as XmlSortKey); return CompareToEmpty(obj); } if (this.dblVal == that.dblVal) { if (this.isNaN) { // NaN sorts equal to NaN if (that.isNaN) return BreakSortingTie(that); // NaN sorts before or after all non-NaN values Debug.Assert(this.dblVal == Double.NegativeInfinity || this.dblVal == Double.PositiveInfinity); return (this.dblVal == Double.NegativeInfinity) ? -1 : 1; } else if (that.isNaN) { // NaN sorts before or after all non-NaN values Debug.Assert(that.dblVal == Double.NegativeInfinity || that.dblVal == Double.PositiveInfinity); return (that.dblVal == Double.NegativeInfinity) ? 1 : -1; } return BreakSortingTie(that); } return (this.dblVal < that.dblVal) ? -1 : 1; } } ////// Sort key for DateTime values (just convert DateTime to ticks and use Long sort key). /// internal class XmlDateTimeSortKey : XmlIntegerSortKey { public XmlDateTimeSortKey(DateTime value, XmlCollation collation) : base(value.Ticks, collation) { } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MailHeaderInfo.cs
- TemplateContent.cs
- ControlParameter.cs
- BitmapCodecInfoInternal.cs
- GcHandle.cs
- SafeNativeMethods.cs
- DbConnectionPoolOptions.cs
- SoapFault.cs
- ClientSideProviderDescription.cs
- ConfigurationProperty.cs
- AnnotationObservableCollection.cs
- XPathAxisIterator.cs
- SoapAttributeAttribute.cs
- AdornerDecorator.cs
- MimeMapping.cs
- AnnotationResourceChangedEventArgs.cs
- TabletCollection.cs
- BrowserDefinition.cs
- SqlFunctionAttribute.cs
- Pool.cs
- WindowsStartMenu.cs
- ExpressionParser.cs
- ListControlConvertEventArgs.cs
- HealthMonitoringSectionHelper.cs
- Int64AnimationBase.cs
- ScopeCollection.cs
- ValidatingPropertiesEventArgs.cs
- ParamArrayAttribute.cs
- IDReferencePropertyAttribute.cs
- SurrogateChar.cs
- EmptyElement.cs
- OneOfTypeConst.cs
- ProcessModelSection.cs
- RuntimeDelegateArgument.cs
- ElementFactory.cs
- GridProviderWrapper.cs
- DecoderNLS.cs
- EmptyCollection.cs
- CaseExpr.cs
- BindingMemberInfo.cs
- Menu.cs
- cookiecollection.cs
- PrintController.cs
- HttpRequestCacheValidator.cs
- RIPEMD160Managed.cs
- BoolExpressionVisitors.cs
- BooleanAnimationBase.cs
- cookieexception.cs
- CharEntityEncoderFallback.cs
- RowBinding.cs
- SpeakCompletedEventArgs.cs
- DesigntimeLicenseContext.cs
- RuleProcessor.cs
- Control.cs
- PhysicalOps.cs
- AcceleratedTokenAuthenticator.cs
- HybridDictionary.cs
- ObjectQueryExecutionPlan.cs
- ConfigurationLockCollection.cs
- DockAndAnchorLayout.cs
- Graph.cs
- DispatcherExceptionFilterEventArgs.cs
- NumberFunctions.cs
- SqlDataSourceFilteringEventArgs.cs
- DateTimeConstantAttribute.cs
- Security.cs
- DataKey.cs
- BamlLocalizationDictionary.cs
- TransactedBatchContext.cs
- CachedCompositeFamily.cs
- SiteMapNodeCollection.cs
- FieldMetadata.cs
- DbLambda.cs
- QueryOperationResponseOfT.cs
- ProviderConnectionPointCollection.cs
- RelationshipNavigation.cs
- MetaForeignKeyColumn.cs
- GeneralTransform3DCollection.cs
- ControlCollection.cs
- RegexMatch.cs
- TablePattern.cs
- CellParaClient.cs
- PowerModeChangedEventArgs.cs
- Subtree.cs
- FrameworkObject.cs
- DataGridCaption.cs
- SiteMapNodeItemEventArgs.cs
- StylusPointCollection.cs
- HatchBrush.cs
- SweepDirectionValidation.cs
- CellLabel.cs
- BinaryReader.cs
- QilScopedVisitor.cs
- StateRuntime.cs
- TreeViewItemAutomationPeer.cs
- MessageFilterException.cs
- TrailingSpaceComparer.cs
- QilScopedVisitor.cs
- XamlStream.cs
- WorkflowApplicationEventArgs.cs