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
- XmlDataSourceDesigner.cs
- NonParentingControl.cs
- ProcessModuleCollection.cs
- DataGridViewLayoutData.cs
- StandardCommands.cs
- RectangleF.cs
- OleDbMetaDataFactory.cs
- PropertyValueUIItem.cs
- PartitionerQueryOperator.cs
- CacheHelper.cs
- HtmlPhoneCallAdapter.cs
- ellipse.cs
- ObjectDataSourceChooseMethodsPanel.cs
- CapabilitiesState.cs
- SemaphoreFullException.cs
- WebEventTraceProvider.cs
- HtmlTableRow.cs
- ValidatorCollection.cs
- ServiceHandle.cs
- FacetChecker.cs
- ContourSegment.cs
- GeometryCollection.cs
- SessionEndingCancelEventArgs.cs
- DocumentGrid.cs
- UnsafeNativeMethods.cs
- StringFormat.cs
- HttpContext.cs
- NestedContainer.cs
- SiteMapProvider.cs
- MarshalByRefObject.cs
- WindowsFormsSectionHandler.cs
- CapabilitiesAssignment.cs
- SoapMessage.cs
- CatalogPart.cs
- TemplateBuilder.cs
- TagPrefixCollection.cs
- RightsManagementEncryptedStream.cs
- OleStrCAMarshaler.cs
- MsmqAuthenticationMode.cs
- storepermissionattribute.cs
- HtmlInputButton.cs
- ViewStateException.cs
- RowsCopiedEventArgs.cs
- RadioButtonStandardAdapter.cs
- SoapHeaderException.cs
- RenamedEventArgs.cs
- SwitchExpression.cs
- OutputCacheSettingsSection.cs
- XPathDocumentNavigator.cs
- InvalidAsynchronousStateException.cs
- ActivationWorker.cs
- RequestQueryParser.cs
- OleDbError.cs
- COM2ExtendedTypeConverter.cs
- BackgroundWorker.cs
- BuildDependencySet.cs
- PeerNameResolver.cs
- TableLayoutStyleCollection.cs
- EntityTypeEmitter.cs
- ProofTokenCryptoHandle.cs
- CodeArrayCreateExpression.cs
- ToolboxItemAttribute.cs
- GlobalizationAssembly.cs
- Identity.cs
- ListBase.cs
- CultureTableRecord.cs
- ToolStripRenderer.cs
- DocumentAutomationPeer.cs
- DesignerAttribute.cs
- ResourceDescriptionAttribute.cs
- DataControlFieldCell.cs
- CodePageEncoding.cs
- DeflateStream.cs
- PrefixQName.cs
- DataGridItemEventArgs.cs
- UIElement3D.cs
- TdsEnums.cs
- Statements.cs
- FrameworkElementAutomationPeer.cs
- WSDualHttpBinding.cs
- Int16AnimationUsingKeyFrames.cs
- InternalControlCollection.cs
- ToolStripItemCollection.cs
- Formatter.cs
- LoginUtil.cs
- SemanticKeyElement.cs
- TableAutomationPeer.cs
- UnsafeNativeMethods.cs
- DataGridViewSortCompareEventArgs.cs
- BaseConfigurationRecord.cs
- TreeViewDataItemAutomationPeer.cs
- HtmlInputControl.cs
- Exceptions.cs
- X509ServiceCertificateAuthenticationElement.cs
- HttpHostedTransportConfiguration.cs
- GridLengthConverter.cs
- StringStorage.cs
- PolicyLevel.cs
- NotFiniteNumberException.cs
- WebBrowsableAttribute.cs