Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / XmlSortKey.cs / 1305376 / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ManagedFilter.cs
- ConnectionConsumerAttribute.cs
- ContentPathSegment.cs
- CriticalHandle.cs
- ClaimComparer.cs
- Exception.cs
- PublisherIdentityPermission.cs
- ExpressionLexer.cs
- FunctionGenerator.cs
- TraceHandler.cs
- EntityUtil.cs
- QilGeneratorEnv.cs
- SkewTransform.cs
- PartitionResolver.cs
- OleDbMetaDataFactory.cs
- DoubleAnimationClockResource.cs
- FragmentQueryProcessor.cs
- DataContractSerializer.cs
- FlowDocumentScrollViewer.cs
- MenuAdapter.cs
- SqlCrossApplyToCrossJoin.cs
- PipelineModuleStepContainer.cs
- CodeCastExpression.cs
- TreeNodeStyleCollection.cs
- ObjectDisposedException.cs
- WriteableBitmap.cs
- MSAAEventDispatcher.cs
- Brush.cs
- DropTarget.cs
- PrintingPermissionAttribute.cs
- ServiceDescription.cs
- SafeFileMapViewHandle.cs
- CategoryNameCollection.cs
- CustomSignedXml.cs
- DbProviderFactory.cs
- StreamWriter.cs
- MimeMultiPart.cs
- RoutedCommand.cs
- TabControlEvent.cs
- XPathDescendantIterator.cs
- PageCatalogPart.cs
- UrlAuthFailedErrorFormatter.cs
- SqlUnionizer.cs
- Crypto.cs
- DBSqlParserTableCollection.cs
- HelpProvider.cs
- UntrustedRecipientException.cs
- Dynamic.cs
- OpCodes.cs
- ItemContainerPattern.cs
- DocumentViewerConstants.cs
- CfgParser.cs
- Parameter.cs
- Encoder.cs
- LocalizationComments.cs
- SessionParameter.cs
- CodeMemberMethod.cs
- ForceCopyBuildProvider.cs
- ReflectionPermission.cs
- ExpressionCopier.cs
- EventHandlersDesigner.cs
- VisualTreeUtils.cs
- ExceptionWrapper.cs
- AuthenticationModuleElementCollection.cs
- SqlNamer.cs
- SelectionItemPattern.cs
- DataDocumentXPathNavigator.cs
- M3DUtil.cs
- BooleanFacetDescriptionElement.cs
- ValueType.cs
- ExternalCalls.cs
- TextServicesProperty.cs
- BuildManager.cs
- ConstructorExpr.cs
- Symbol.cs
- Frame.cs
- SimpleWorkerRequest.cs
- KerberosSecurityTokenProvider.cs
- SharedDp.cs
- SafeHGlobalHandleCritical.cs
- ThicknessAnimationBase.cs
- RIPEMD160Managed.cs
- NumberFormatInfo.cs
- ResourcePool.cs
- SqlRemoveConstantOrderBy.cs
- Scene3D.cs
- UnsafeNativeMethods.cs
- SrgsSemanticInterpretationTag.cs
- Parser.cs
- DataBinder.cs
- FormViewUpdateEventArgs.cs
- ActiveXHelper.cs
- ColumnTypeConverter.cs
- ObjectView.cs
- Relationship.cs
- DataGridViewColumnConverter.cs
- CommandEventArgs.cs
- PictureBox.cs
- MinimizableAttributeTypeConverter.cs
- XmlEncApr2001.cs