Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Xml / System / Xml / XPath / Internal / SortQuery.cs / 1 / SortQuery.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace MS.Internal.Xml.XPath {
using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
internal sealed class SortQuery : Query {
private List results;
private XPathSortComparer comparer;
private Query qyInput;
public SortQuery(Query qyInput) {
Debug.Assert(qyInput != null, "Sort Query needs an input query tree to work on");
this.results = new List();
this.comparer = new XPathSortComparer();
this.qyInput = qyInput;
count = 0;
}
private SortQuery(SortQuery other) : base(other) {
this.results = new List(other.results);
this.comparer = other.comparer.Clone();
this.qyInput = Clone(other.qyInput);
count = 0;
}
public override void Reset() { count = 0; }
public override void SetXsltContext(XsltContext xsltContext) {
qyInput.SetXsltContext(xsltContext);
if (
qyInput.StaticType != XPathResultType.NodeSet &&
qyInput.StaticType != XPathResultType.Any
) {
throw XPathException.Create(Res.Xp_NodeSetExpected);
}
}
private void BuildResultsList() {
Int32 numSorts = this.comparer.NumSorts;
Debug.Assert(numSorts > 0, "Why was the sort query created?");
XPathNavigator eNext;
while ((eNext = qyInput.Advance()) != null) {
SortKey key = new SortKey(numSorts, /*originalPosition:*/this.results.Count, eNext.Clone());
for (Int32 j = 0; j < numSorts; j++) {
key[j] = this.comparer.Expression(j).Evaluate(qyInput);
}
results.Add(key);
}
results.Sort(this.comparer);
}
public override object Evaluate(XPathNodeIterator context) {
qyInput.Evaluate(context);
this.results.Clear();
BuildResultsList();
count = 0;
return this;
}
public override XPathNavigator Advance() {
Debug.Assert(0 <= count && count <= results.Count);
if (count < this.results.Count) {
return this.results[count++].Node;
}
return null;
}
public override XPathNavigator Current {
get {
Debug.Assert(0 <= count && count <= results.Count);
if (count == 0) {
return null;
}
return results[count - 1].Node;
}
}
internal void AddSort(Query evalQuery, IComparer comparer) {
this.comparer.AddSort(evalQuery, comparer);
}
public override XPathNodeIterator Clone() { return new SortQuery(this); }
public override XPathResultType StaticType { get { return XPathResultType.NodeSet; } }
public override int CurrentPosition { get { return count; } }
public override int Count { get { return results.Count; } }
public override QueryProps Properties { get { return QueryProps.Cached | QueryProps.Position | QueryProps.Count; } }
public override void PrintQuery(XmlWriter w) {
w.WriteStartElement(this.GetType().Name);
qyInput.PrintQuery(w);
w.WriteElementString("XPathSortComparer", "... PrintTree() not implemented ...");
w.WriteEndElement();
}
} // class SortQuery
internal sealed class SortKey {
private Int32 numKeys;
private object[] keys;
private int originalPosition;
private XPathNavigator node;
public SortKey(int numKeys, int originalPosition, XPathNavigator node) {
this.numKeys = numKeys;
this.keys = new object[numKeys];
this.originalPosition = originalPosition;
this.node = node;
}
public object this[int index] {
get { return this.keys[index]; }
set { this.keys[index] = value; }
}
public int NumKeys { get { return this.numKeys; } }
public int OriginalPosition { get { return this.originalPosition; } }
public XPathNavigator Node { get { return this.node; } }
} // class SortKey
internal sealed class XPathSortComparer : IComparer {
private const int minSize = 3;
private Query[] expressions;
private IComparer[] comparers;
private int numSorts;
public XPathSortComparer(int size) {
if (size <= 0) size = minSize;
this.expressions = new Query[ size];
this.comparers = new IComparer[size];
}
public XPathSortComparer() : this (minSize) {}
public void AddSort(Query evalQuery, IComparer comparer) {
Debug.Assert(this.expressions.Length == this.comparers.Length);
Debug.Assert(0 < this.expressions.Length);
Debug.Assert(0 <= numSorts && numSorts <= this.expressions.Length);
// Ajust array sizes if needed.
if (numSorts == this.expressions.Length) {
Query[] newExpressions = new Query[ numSorts * 2];
IComparer[] newComparers = new IComparer[numSorts * 2];
for (int i = 0; i < numSorts; i ++) {
newExpressions[i] = this.expressions[i];
newComparers [i] = this.comparers[i];
}
this.expressions = newExpressions;
this.comparers = newComparers;
}
Debug.Assert(numSorts < this.expressions.Length);
// Fixup expression to handle node-set return type:
if (evalQuery.StaticType == XPathResultType.NodeSet || evalQuery.StaticType == XPathResultType.Any) {
evalQuery = new StringFunctions(Function.FunctionType.FuncString, new Query[] { evalQuery });
}
this.expressions[numSorts] = evalQuery;
this.comparers[ numSorts] = comparer;
numSorts ++;
}
public int NumSorts { get { return numSorts; } }
public Query Expression(int i) {
return this.expressions[i];
}
int IComparer.Compare(SortKey x, SortKey y) {
Debug.Assert(x != null && y != null, "Oops!! what happened?");
int result = 0;
for (int i = 0; i < x.NumKeys; i++) {
result = this.comparers[i].Compare(x[i], y[i]);
if (result != 0) {
return result;
}
}
// if after all comparisions, the two sort keys are still equal, preserve the doc order
return x.OriginalPosition - y.OriginalPosition;
}
internal XPathSortComparer Clone() {
XPathSortComparer clone = new XPathSortComparer(this.numSorts);
for (int i = 0; i < this.numSorts; i ++) {
clone.comparers[i] = this.comparers[i];
clone.expressions[i] = (Query)this.expressions[i].Clone(); // Expressions should be cloned because Query should be cloned
}
clone.numSorts = this.numSorts;
return clone;
}
} // class XPathSortComparer
} // namespace
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
namespace MS.Internal.Xml.XPath {
using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
internal sealed class SortQuery : Query {
private List results;
private XPathSortComparer comparer;
private Query qyInput;
public SortQuery(Query qyInput) {
Debug.Assert(qyInput != null, "Sort Query needs an input query tree to work on");
this.results = new List();
this.comparer = new XPathSortComparer();
this.qyInput = qyInput;
count = 0;
}
private SortQuery(SortQuery other) : base(other) {
this.results = new List(other.results);
this.comparer = other.comparer.Clone();
this.qyInput = Clone(other.qyInput);
count = 0;
}
public override void Reset() { count = 0; }
public override void SetXsltContext(XsltContext xsltContext) {
qyInput.SetXsltContext(xsltContext);
if (
qyInput.StaticType != XPathResultType.NodeSet &&
qyInput.StaticType != XPathResultType.Any
) {
throw XPathException.Create(Res.Xp_NodeSetExpected);
}
}
private void BuildResultsList() {
Int32 numSorts = this.comparer.NumSorts;
Debug.Assert(numSorts > 0, "Why was the sort query created?");
XPathNavigator eNext;
while ((eNext = qyInput.Advance()) != null) {
SortKey key = new SortKey(numSorts, /*originalPosition:*/this.results.Count, eNext.Clone());
for (Int32 j = 0; j < numSorts; j++) {
key[j] = this.comparer.Expression(j).Evaluate(qyInput);
}
results.Add(key);
}
results.Sort(this.comparer);
}
public override object Evaluate(XPathNodeIterator context) {
qyInput.Evaluate(context);
this.results.Clear();
BuildResultsList();
count = 0;
return this;
}
public override XPathNavigator Advance() {
Debug.Assert(0 <= count && count <= results.Count);
if (count < this.results.Count) {
return this.results[count++].Node;
}
return null;
}
public override XPathNavigator Current {
get {
Debug.Assert(0 <= count && count <= results.Count);
if (count == 0) {
return null;
}
return results[count - 1].Node;
}
}
internal void AddSort(Query evalQuery, IComparer comparer) {
this.comparer.AddSort(evalQuery, comparer);
}
public override XPathNodeIterator Clone() { return new SortQuery(this); }
public override XPathResultType StaticType { get { return XPathResultType.NodeSet; } }
public override int CurrentPosition { get { return count; } }
public override int Count { get { return results.Count; } }
public override QueryProps Properties { get { return QueryProps.Cached | QueryProps.Position | QueryProps.Count; } }
public override void PrintQuery(XmlWriter w) {
w.WriteStartElement(this.GetType().Name);
qyInput.PrintQuery(w);
w.WriteElementString("XPathSortComparer", "... PrintTree() not implemented ...");
w.WriteEndElement();
}
} // class SortQuery
internal sealed class SortKey {
private Int32 numKeys;
private object[] keys;
private int originalPosition;
private XPathNavigator node;
public SortKey(int numKeys, int originalPosition, XPathNavigator node) {
this.numKeys = numKeys;
this.keys = new object[numKeys];
this.originalPosition = originalPosition;
this.node = node;
}
public object this[int index] {
get { return this.keys[index]; }
set { this.keys[index] = value; }
}
public int NumKeys { get { return this.numKeys; } }
public int OriginalPosition { get { return this.originalPosition; } }
public XPathNavigator Node { get { return this.node; } }
} // class SortKey
internal sealed class XPathSortComparer : IComparer {
private const int minSize = 3;
private Query[] expressions;
private IComparer[] comparers;
private int numSorts;
public XPathSortComparer(int size) {
if (size <= 0) size = minSize;
this.expressions = new Query[ size];
this.comparers = new IComparer[size];
}
public XPathSortComparer() : this (minSize) {}
public void AddSort(Query evalQuery, IComparer comparer) {
Debug.Assert(this.expressions.Length == this.comparers.Length);
Debug.Assert(0 < this.expressions.Length);
Debug.Assert(0 <= numSorts && numSorts <= this.expressions.Length);
// Ajust array sizes if needed.
if (numSorts == this.expressions.Length) {
Query[] newExpressions = new Query[ numSorts * 2];
IComparer[] newComparers = new IComparer[numSorts * 2];
for (int i = 0; i < numSorts; i ++) {
newExpressions[i] = this.expressions[i];
newComparers [i] = this.comparers[i];
}
this.expressions = newExpressions;
this.comparers = newComparers;
}
Debug.Assert(numSorts < this.expressions.Length);
// Fixup expression to handle node-set return type:
if (evalQuery.StaticType == XPathResultType.NodeSet || evalQuery.StaticType == XPathResultType.Any) {
evalQuery = new StringFunctions(Function.FunctionType.FuncString, new Query[] { evalQuery });
}
this.expressions[numSorts] = evalQuery;
this.comparers[ numSorts] = comparer;
numSorts ++;
}
public int NumSorts { get { return numSorts; } }
public Query Expression(int i) {
return this.expressions[i];
}
int IComparer.Compare(SortKey x, SortKey y) {
Debug.Assert(x != null && y != null, "Oops!! what happened?");
int result = 0;
for (int i = 0; i < x.NumKeys; i++) {
result = this.comparers[i].Compare(x[i], y[i]);
if (result != 0) {
return result;
}
}
// if after all comparisions, the two sort keys are still equal, preserve the doc order
return x.OriginalPosition - y.OriginalPosition;
}
internal XPathSortComparer Clone() {
XPathSortComparer clone = new XPathSortComparer(this.numSorts);
for (int i = 0; i < this.numSorts; i ++) {
clone.comparers[i] = this.comparers[i];
clone.expressions[i] = (Query)this.expressions[i].Clone(); // Expressions should be cloned because Query should be cloned
}
clone.numSorts = this.numSorts;
return clone;
}
} // class XPathSortComparer
} // namespace
// 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
- DeflateStream.cs
- DataGridViewDataErrorEventArgs.cs
- Assembly.cs
- WebEncodingValidatorAttribute.cs
- LogicalExpr.cs
- DefaultHttpHandler.cs
- _RequestLifetimeSetter.cs
- Line.cs
- BulletDecorator.cs
- HtmlMeta.cs
- NonVisualControlAttribute.cs
- Translator.cs
- COSERVERINFO.cs
- XmlEntityReference.cs
- Missing.cs
- ParameterCollection.cs
- WebPartConnectionCollection.cs
- ColumnCollection.cs
- Deflater.cs
- httpserverutility.cs
- LoadRetryStrategyFactory.cs
- ProxyElement.cs
- UserControlParser.cs
- TextParaLineResult.cs
- ApplicationBuildProvider.cs
- AutoResizedEvent.cs
- CommandBinding.cs
- DictionaryMarkupSerializer.cs
- CompressedStack.cs
- TextProperties.cs
- EnterpriseServicesHelper.cs
- Viewport3DVisual.cs
- Models.cs
- WorkflowRuntimeServicesBehavior.cs
- MethodAccessException.cs
- AddInDeploymentState.cs
- StackOverflowException.cs
- ListViewItem.cs
- SmiContextFactory.cs
- ToolStripMenuItemDesigner.cs
- GroupItemAutomationPeer.cs
- Vector3dCollection.cs
- EntityType.cs
- WebRequest.cs
- DataGridViewColumnStateChangedEventArgs.cs
- DataPointer.cs
- XmlAttributeAttribute.cs
- TypeSystem.cs
- NullableFloatSumAggregationOperator.cs
- StaticResourceExtension.cs
- InternalDuplexBindingElement.cs
- LinqDataSourceView.cs
- PageBuildProvider.cs
- MemoryMappedFile.cs
- MsmqTransportBindingElement.cs
- AnnotationStore.cs
- ArgumentException.cs
- AccessibleObject.cs
- FontFamilyIdentifier.cs
- IChannel.cs
- SqlReorderer.cs
- ObjectSpanRewriter.cs
- Serializer.cs
- QueryStringHandler.cs
- RegexCaptureCollection.cs
- ListView.cs
- StretchValidation.cs
- DesignerRegionCollection.cs
- WebPartCancelEventArgs.cs
- JobCollate.cs
- PrimarySelectionGlyph.cs
- CacheHelper.cs
- SchemaEntity.cs
- BroadcastEventHelper.cs
- PasswordPropertyTextAttribute.cs
- SessionMode.cs
- MachineKeySection.cs
- DataListItemCollection.cs
- PropertyBuilder.cs
- UrlAuthorizationModule.cs
- ToolStripItemImageRenderEventArgs.cs
- TypeInitializationException.cs
- DataGridViewDataErrorEventArgs.cs
- ScaleTransform.cs
- DataGridCommandEventArgs.cs
- TextChange.cs
- SizeChangedEventArgs.cs
- GroupDescription.cs
- ScrollBar.cs
- ApplicationFileCodeDomTreeGenerator.cs
- StorageComplexTypeMapping.cs
- Activity.cs
- Not.cs
- ImageConverter.cs
- IteratorFilter.cs
- XmlSchemaImport.cs
- NavigationHelper.cs
- QilNode.cs
- SiteOfOriginPart.cs
- HostedTcpTransportManager.cs