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
- TextCompositionManager.cs
- TextBreakpoint.cs
- ApplicationGesture.cs
- NonceToken.cs
- HtmlElementEventArgs.cs
- BaseDataList.cs
- SchemaNames.cs
- Task.cs
- CodeCastExpression.cs
- UpdatePanelTrigger.cs
- ColorTransformHelper.cs
- CheckBoxAutomationPeer.cs
- Win32MouseDevice.cs
- RuleSettingsCollection.cs
- SettingsSavedEventArgs.cs
- SqlDataSourceSelectingEventArgs.cs
- FileSystemEventArgs.cs
- WebBrowserNavigatingEventHandler.cs
- CalendarDateChangedEventArgs.cs
- Message.cs
- RegularExpressionValidator.cs
- NetworkStream.cs
- Label.cs
- CellRelation.cs
- DBCommand.cs
- DrawingImage.cs
- XhtmlBasicPageAdapter.cs
- HeaderLabel.cs
- PageClientProxyGenerator.cs
- PrintPreviewControl.cs
- CacheEntry.cs
- XhtmlCssHandler.cs
- ToolStripScrollButton.cs
- ModifyActivitiesPropertyDescriptor.cs
- FactoryId.cs
- GridLengthConverter.cs
- ToolStripLocationCancelEventArgs.cs
- DefaultShape.cs
- DataTableNameHandler.cs
- GridViewRow.cs
- SelectedCellsCollection.cs
- DSGeneratorProblem.cs
- IPAddressCollection.cs
- TypeConverterHelper.cs
- AppDomainProtocolHandler.cs
- MetadataUtilsSmi.cs
- ViewManager.cs
- ObjectStateEntryOriginalDbUpdatableDataRecord.cs
- TrimSurroundingWhitespaceAttribute.cs
- MarshalDirectiveException.cs
- CollaborationHelperFunctions.cs
- CodeDirectiveCollection.cs
- LoginViewDesigner.cs
- EllipseGeometry.cs
- HttpCacheVary.cs
- ThreadSafeList.cs
- EntityTransaction.cs
- SettingsSection.cs
- MonthChangedEventArgs.cs
- DocumentSchemaValidator.cs
- BulletDecorator.cs
- PropertyValueUIItem.cs
- TextServicesDisplayAttribute.cs
- WpfWebRequestHelper.cs
- CountAggregationOperator.cs
- CurrencyManager.cs
- CommandPlan.cs
- TypeUtil.cs
- CleanUpVirtualizedItemEventArgs.cs
- AtlasWeb.Designer.cs
- ClientSponsor.cs
- SHA256Managed.cs
- FrameworkContentElement.cs
- FloaterBaseParagraph.cs
- WmlValidationSummaryAdapter.cs
- ConfigViewGenerator.cs
- WebHttpBehavior.cs
- WasAdminWrapper.cs
- TargetControlTypeAttribute.cs
- WebScriptMetadataMessageEncoderFactory.cs
- QilPatternFactory.cs
- XmlSerializableWriter.cs
- DataPager.cs
- StylusTip.cs
- PerformanceCounterPermissionEntryCollection.cs
- LogLogRecord.cs
- SpecialNameAttribute.cs
- ScriptRef.cs
- LogSwitch.cs
- KnownTypeHelper.cs
- FixedSOMSemanticBox.cs
- MruCache.cs
- WsatTransactionInfo.cs
- SafeRightsManagementQueryHandle.cs
- BitmapEffectCollection.cs
- TextElementEditingBehaviorAttribute.cs
- TreeViewItem.cs
- MappedMetaModel.cs
- CharStorage.cs
- RichTextBox.cs