Files
acceptance-tests
data
debian
docs
external
ikvm-native
libgc
llvm
m4
man
mcs
build
class
Accessibility
Commons.Xml.Relaxng
Cscompmgd
CustomMarshalers
Facades
I18N
IBM.Data.DB2
ICSharpCode.SharpZipLib
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Tasks
Microsoft.Build.Utilities
Microsoft.CSharp
Microsoft.NuGet.Build.Tasks
Microsoft.VisualC
Microsoft.Web.Infrastructure
MicrosoftAjaxLibrary
Mono.Btls.Interface
Mono.C5
Mono.CSharp
Mono.Cairo
Mono.Cecil
Mono.Cecil.Mdb
Mono.CodeContracts
Mono.CompilerServices.SymbolWriter
Mono.Data.Sqlite
Mono.Data.Tds
Mono.Debugger.Soft
Mono.Http
Mono.Management
Mono.Messaging
Mono.Messaging.RabbitMQ
Mono.Options
Mono.Parallel
Mono.Posix
Mono.Profiler.Log
Mono.Runtime.Tests
Mono.Security
Mono.Security.Win32
Mono.Simd
Mono.Tasklets
Mono.WebBrowser
Mono.XBuild.Tasks
Novell.Directory.Ldap
PEAPI
RabbitMQ.Client
SMDiagnostics
System
System.ComponentModel.Composition.4.5
System.ComponentModel.DataAnnotations
System.Configuration
System.Configuration.Install
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.Entity
System.Data.Linq
System.Data.OracleClient
System.Data.Services
System.Data.Services.Client
System.Deployment
System.Design
System.DirectoryServices
System.DirectoryServices.Protocols
System.Drawing
System.Drawing.Design
System.Dynamic
System.EnterpriseServices
System.IO.Compression
System.IO.Compression.FileSystem
System.IdentityModel
System.IdentityModel.Selectors
System.Json
System.Json.Microsoft
System.Management
System.Messaging
System.Net
System.Net.Http
System.Net.Http.Formatting
System.Net.Http.WebRequest
System.Net.Http.WinHttpHandler
System.Numerics
System.Numerics.Vectors
System.Reactive.Core
System.Reactive.Debugger
System.Reactive.Experimental
System.Reactive.Interfaces
System.Reactive.Linq
System.Reactive.Observable.Aliases
System.Reactive.PlatformServices
System.Reactive.Providers
System.Reactive.Runtime.Remoting
System.Reactive.Windows.Forms
System.Reactive.Windows.Threading
System.Reflection.Context
System.Runtime.Caching
System.Runtime.CompilerServices.Unsafe
System.Runtime.DurableInstancing
System.Runtime.Remoting
System.Runtime.Serialization
System.Runtime.Serialization.Formatters.Soap
System.Security
System.ServiceModel
System.ServiceModel.Activation
System.ServiceModel.Discovery
System.ServiceModel.Internals
System.ServiceModel.Routing
System.ServiceModel.Web
System.ServiceProcess
System.Threading.Tasks.Dataflow
System.Transactions
System.Web
System.Web.Abstractions
System.Web.ApplicationServices
System.Web.DynamicData
System.Web.Extensions
System.Web.Extensions.Design
System.Web.Http
System.Web.Http.SelfHost
System.Web.Http.WebHost
System.Web.Mobile
System.Web.Mvc3
System.Web.Razor
System.Web.RegularExpressions
System.Web.Routing
System.Web.Services
System.Web.WebPages
System.Web.WebPages.Deployment
System.Web.WebPages.Razor
System.Windows
System.Windows.Forms
System.Windows.Forms.DataVisualization
System.Workflow.Activities
System.Workflow.ComponentModel
System.Workflow.Runtime
System.XML
System.Xaml
System.Xml.Linq
System.Xml.Serialization
SystemWebTestShim
WebMatrix.Data
WindowsBase
aot-compiler
corlib
dlr
doc
legacy
lib
monodoc
notes
reference-assemblies
referencesource
SMDiagnostics
System
System.Activities
System.Activities.Core.Presentation
System.Activities.DurableInstancing
System.Activities.Presentation
System.ComponentModel.DataAnnotations
System.Configuration
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.Entity
System.Data.Entity.Design
System.Data.Linq
System.Data.SqlXml
System.IdentityModel
System.IdentityModel.Selectors
System.Net
System.Numerics
System.Runtime.Caching
System.Runtime.DurableInstancing
System.Runtime.Serialization
System.ServiceModel
InternalApis
Serialization
System
Collections
ServiceModel
Activation
Administration
Channels
ComIntegration
Configuration
Description
Diagnostics
Dispatcher
ActionMessageFilter.cs
ActionMessageFilterTable.cs
AndMessageFilter.cs
AndMessageFilterTable.cs
AsyncMethodInvoker.cs
AuthenticationBehavior.cs
AuthorizationBehavior.cs
BufferedReceiveBinder.cs
ChannelDispatcher.cs
ChannelDispatcherBase.cs
ChannelDispatcherCollection.cs
ChannelHandler.cs
ClientOperation.cs
ClientRuntime.cs
CodeGenerator.cs
ConcurrencyBehavior.cs
DataContractSerializerFaultFormatter.cs
DataContractSerializerOperationFormatter.cs
DataContractSerializerServiceBehavior.cs
DispatchOperation.cs
DispatchOperationRuntime.cs
DispatchRuntime.cs
DuplexChannelBinder.cs
EndpointAddressMessageFilter.cs
EndpointAddressMessageFilterTable.cs
EndpointAddressProcessor.cs
EndpointDispatcher.cs
EndpointDispatcherTable.cs
EndpointFilterProvider.cs
ErrorBehavior.cs
ErrorHandlerFaultInfo.cs
ErrorHandlingAcceptor.cs
ErrorhandlingReceiver.cs
ExceptionHandler.cs
FaultContractInfo.cs
FaultFormatter.cs
FilterInvalidBodyAccessException.cs
FlowThrottle.cs
HeaderFilter.cs
ICallContextInitializer.cs
IChannelBinder.cs
IChannelInitializer.cs
IClientFaultFormatter.cs
IClientMessageFormatter.cs
IClientMessageInspector.cs
IClientOperationSelector.cs
IDispatchFaultFormatter.cs
IDispatchMessageFormatter.cs
IDispatchMessageInspector.cs
IDispatchOperationSelector.cs
IErrorHandler.cs
IInputSessionShutdown.cs
IInstanceContextInitializer.cs
IInstanceContextProvider.cs
IInstanceProvider.cs
IInstanceTransaction.cs
IInteractiveChannelInitializer.cs
IInvokeReceivedNotification.cs
IListenerBinder.cs
IManualConcurrencyOperationInvoker.cs
IMessageFilterTable.cs
IOperationInvoker.cs
IParameterInspector.cs
IResumeMessageRpc.cs
ImmutableClientRuntime.cs
ImmutableCommunicationTimeouts.cs
ImmutableDispatchRuntime.cs
InputChannelBinder.cs
InstanceBehavior.cs
InstanceContextIdleCallback.cs
InstanceContextManager.cs
InvalidBodyAccessException.cs
InvokerUtil.cs
ListenerBinder.cs
ListenerHandler.cs
MatchAllMessageFilter.cs
MatchNoneMessageFilter.cs
MatchSingleFxEngineOpcode.cs
MessageFilter.cs
MessageFilterException.cs
MessageFilterTable.cs
MessageOperationFormatter.cs
MessageQuery.cs
MessageQueryCollection.cs
MessageQueryTable.cs
MessageRpc.cs
MultipleFilterMatchesException.cs
MultipleReceiveBinder.cs
NavigatorInvalidBodyAccessException.cs
NetDispatcherFaultException.cs
OperationFormatter.cs
OperationInvokerBehavior.cs
OperationSelectorBehavior.cs
OutputChannelBinder.cs
PartialTrustValidationBehavior.cs
PeerValidationBehavior.cs
PerCallInstanceContextProvider.cs
PerSessionInstanceContextProvider.cs
PrefixEndpointAddressMessageFilter.cs
PrefixEndpointAddressMessageFilterTable.cs
PrimitiveOperationFormatter.cs
ProxyOperationRuntime.cs
ProxyRpc.cs
QueryBranchOp.cs
QueryCoreOp.cs
QueryException.cs
QueryFunctions.cs
QueryIntervalOp.cs
QueryMatcher.cs
QueryMath.cs
QueryModel.cs
QueryNode.cs
QueryOpcode.cs
QueryPrefixOp.cs
QueryProcessor.cs
QueryRelOp.cs
QueryResultOp.cs
QuerySafeNavigator.cs
QuerySelectOp.cs
QuerySetOp.cs
QueryStack.cs
QuerySubExprEliminator.cs
QueryTreeBuilder.cs
QueryUtil.cs
QueryValue.cs
QuotaThrottle.cs
ReceiveContextAcknowledgementMode.cs
ReceiveContextRPCFacet.cs
ReplyChannelBinder.cs
RequestChannelBinder.cs
SecurityImpersonationBehavior.cs
SecurityValidationBehavior.cs
SeekableMessageNavigator.cs
SeekableXPathNavigator.cs
ServiceThrottle.cs
SharedRuntimeState.cs
SingletonInstanceContextProvider.cs
StreamFormatter.cs
SyncMethodInvoker.cs
SynchronizedChannelCollection.cs
TaskExtensions.cs
TaskMethodInvoker.cs
TerminatingOperationBehavior.cs
ThreadBehavior.cs
ThreadSafeMessageFilterTable.cs
TransactedBatchContext.cs
TransactionBehavior.cs
TransactionValidationBehavior.cs
UniqueContractNameValidationBehavior.cs
XPathCompiler.cs
XPathExpr.cs
XPathLexer.cs
XPathMessageContext.cs
XPathMessageFilter.cs
XPathMessageFilterTable.cs
XPathMessageQueryCollection.cs
XPathNavigatorException.cs
XPathParser.cs
XPathResult.cs
XmlSerializerFaultFormatter.cs
XmlSerializerObjectSerializer.cs
XmlSerializerOperationFormatter.cs
MsmqIntegration
PeerResolvers
Security
Syndication
Transactions
XamlIntegration
ActionMismatchAddressingException.cs
ActionNotSupportedException.cs
AddressAccessDeniedException.cs
AddressAlreadyInUseException.cs
AddressFilterMode.cs
AppContextDefaultValues.Default.cs
AuditLevel.cs
AuditLogLocation.cs
BasicHttpBinding.cs
BasicHttpContextBinding.cs
BasicHttpMessageCredentialType.cs
BasicHttpMessageSecurity.cs
BasicHttpSecurity.cs
BasicHttpSecurityMode.cs
BasicHttpsBinding.cs
BasicHttpsSecurity.cs
BasicHttpsSecurityMode.cs
CacheSetting.cs
CallbackBehaviorAttribute.cs
ChannelFactory.cs
ChannelFactoryRefCache.cs
ChannelTerminatedException.cs
ClientBase.cs
CommunicationException.cs
CommunicationObjectAbortedException.cs
CommunicationObjectFaultedException.cs
CommunicationState.cs
ConcurrencyMode.cs
ConfigurationEndpointTrait.cs
DXD.cs
DataContractFormatAttribute.cs
DeadLetterQueue.cs
DeliveryRequirementsAttribute.cs
DnsEndpointIdentity.cs
DuplexChannelFactory.cs
DuplexClientBase.cs
EmptyArray.cs
EndpointAddress.cs
EndpointAddress10.cs
EndpointAddressAugust2004.cs
EndpointIdentity.cs
EndpointNotFoundException.cs
EndpointTrait.cs
EnvelopeVersion.cs
ExceptionDetail.cs
ExceptionMapper.cs
ExtensionCollection.cs
FaultCode.cs
FaultCodeConstants.cs
FaultContractAttribute.cs
FaultException.cs
FaultImportOptions.cs
FaultReason.cs
FaultReasonText.cs
FederatedMessageSecurityOverHttp.cs
GeneralEndpointIdentity.cs
HostnameComparisonMode.cs
HttpBindingBase.cs
HttpClientCredentialType.cs
HttpProxyCredentialType.cs
HttpTransportSecurity.cs
IChannelBaseProxy.cs
IClientChannel.cs
ICommunicationObject.cs
IContextChannel.cs
IContextSessionProvider.cs
IDefaultCommunicationTimeouts.cs
IDuplexContextChannel.cs
IExtensibleObject.cs
IExtension.cs
IExtensionCollection.cs
IOnlineStatus.cs
IOperationContractAttributeProvider.cs
IServiceChannel.cs
ImpersonationOption.cs
InstanceContext.cs
InstanceContextMode.cs
InvalidMessageContractException.cs
KeyedByTypeCollection.cs
LocalAppContextSwitches.cs
MessageBodyMemberAttribute.cs
MessageContractAttribute.cs
MessageContractMemberAttribute.cs
MessageCredentialType.cs
MessageHeaderArrayAttribute.cs
MessageHeaderAttribute.cs
MessageHeaderException.cs
MessageHeaderT.cs
MessageParameterAttribute.cs
MessagePropertyAttribute.cs
MessageSecurityOverHttp.cs
MessageSecurityOverMsmq.cs
MessageSecurityOverTcp.cs
MessageSecurityVersion.cs
MostlySingletonList.cs
MsmqAuthenticationMode.cs
MsmqBindingBase.cs
MsmqEncryptionAlgorithm.cs
MsmqException.cs
MsmqPoisonMessageException.cs
MsmqSecureHashAlgorithm.cs
MsmqTransportSecurity.cs
MustUnderstandSoapException.cs
NamedPipeTransportSecurity.cs
NetHttpBinding.cs
NetHttpMessageEncoding.cs
NetHttpMessageEncodingHelper.cs
NetHttpsBinding.cs
NetMsmqBinding.cs
NetMsmqSecurity.cs
NetMsmqSecurityMode.cs
NetNamedPipeBinding.cs
NetNamedPipeSecurity.cs
NetNamedPipeSecurityMode.cs
NetPeerTcpBinding.cs
NetTcpBinding.cs
NetTcpContextBinding.cs
NetTcpSecurity.cs
NonDualMessageSecurityOverHttp.cs
OSEnvironmentHelper.cs
OSVersion.cs
OperationBehaviorAttribute.cs
OperationContext.cs
OperationContextScope.cs
OperationContractAttribute.cs
OperationFormatStyle.cs
OperationFormatUse.cs
PeerHopCountAttribute.cs
PeerMessageOrigination.cs
PeerMessagePropagation.cs
PeerMessagePropagationFilter.cs
PeerNode.cs
PeerNodeAddress.cs
PeerResolver.cs
PeerSecuritySettings.cs
PeerTransportCredentialType.cs
PeerTransportSecuritySettings.cs
PoisonMessageException.cs
Pool.cs
ProgrammaticEndpointTrait.cs
ProtocolException.cs
QueueTransferProtocol.cs
QueuedDeliveryRequirementsMode.cs
QuotaExceededException.cs
ReceiveContextEnabledAttribute.cs
ReceiveErrorHandling.cs
ReleaseInstanceMode.cs
ReliableMessagingVersion.cs
ReliableSession.cs
RsaEndpointIdentity.cs
SecurityMode.cs
ServerTooBusyException.cs
ServiceActivationException.cs
ServiceAuthenticationManager.cs
ServiceAuthorizationManager.cs
ServiceBehaviorAttribute.cs
ServiceChannelManager.cs
ServiceConfiguration.cs
ServiceContractAttribute.cs
ServiceDefaults.cs
ServiceEndpointTrait.cs
ServiceHost.cs
ServiceKnownTypeAttribute.cs
ServiceModelAppSettings.cs
ServiceModelAttributeTargets.cs
ServiceModelDictionary.cs
ServiceModelStrings.cs
ServiceModelStringsVersion1.cs
ServiceSecurityContext.cs
SessionMode.cs
SpnEndpointIdentity.cs
StringUtil.cs
SynchronizedCollection.cs
SynchronizedDisposablePool.cs
SynchronizedKeyedCollection.cs
SynchronizedReadOnlyCollection.cs
TcpClientCredentialType.cs
TcpTransportSecurity.cs
ThreadTrace.cs
TimeSpanHelper.cs
TransactionFlowAttribute.cs
TransactionFlowOption.cs
TransactionProtocol.cs
TransferMode.cs
UnifiedSecurityMode.cs
UnknownMessageReceivedEventArgs.cs
UpnEndpointIdentity.cs
UriSchemeKeyedCollection.cs
WS2007FederationHttpBinding.cs
WS2007HttpBinding.cs
WSAddressing10ProblemHeaderQNameFault.cs
WSDualHttpBinding.cs
WSDualHttpSecurity.cs
WSDualHttpSecurityMode.cs
WSFederationHttpBinding.cs
WSFederationHttpSecurity.cs
WSFederationHttpSecurityMode.cs
WSHttpBinding.cs
WSHttpBindingBase.cs
WSHttpContextBinding.cs
WSHttpSecurity.cs
WSMessageEncoding.cs
WrappedDispatcherException.cs
X509CertificateEndpointIdentity.cs
XD.cs.REMOVED.git-id
XPathMessageQuery.cs
XmlBuffer.cs
XmlSerializerFormatAttribute.cs
XmlUtil.cs
UriTemplate.cs
UriTemplateCompoundPathSegment.cs
UriTemplateEquivalenceComparer.cs
UriTemplateHelpers.cs
UriTemplateLiteralPathSegment.cs
UriTemplateLiteralQueryValue.cs
UriTemplateMatch.cs
UriTemplateMatchException.cs
UriTemplatePartType.cs
UriTemplatePathPartiallyEquivalentSet.cs
UriTemplatePathSegment.cs
UriTemplateQueryValue.cs
UriTemplateTable.cs
UriTemplateTableMatchCandidate.cs
UriTemplateTrieIntraNodeLocation.cs
UriTemplateTrieLocation.cs
UriTemplateTrieNode.cs
UriTemplateVariablePathSegment.cs
UriTemplateVariableQueryValue.cs
AssemblyInfo.cs
System.ServiceModel.txt.REMOVED.git-id
TD.Designer.cs.REMOVED.git-id
System.ServiceModel.Activation
System.ServiceModel.Activities
System.ServiceModel.Channels
System.ServiceModel.Discovery
System.ServiceModel.Internals
System.ServiceModel.Routing
System.ServiceModel.WasHosting
System.ServiceModel.Web
System.Web
System.Web.ApplicationServices
System.Web.DataVisualization
System.Web.DynamicData
System.Web.Entity
System.Web.Entity.Design
System.Web.Extensions
System.Web.Mobile
System.Web.Routing
System.Web.Services
System.Workflow.Activities
System.Workflow.ComponentModel
System.Workflow.Runtime
System.WorkflowServices
System.Xaml.Hosting
System.Xml
System.Xml.Linq
XamlBuildTask
mscorlib
LICENSE.txt
PATENTS.TXT
README.Mono.md
README.md
test-helpers
LICENSE
Makefile
Open.snk
README
ecma.pub
mono.pub
mono.snk
msfinal.pub
reactive.pub
silverlight.pub
winfx.pub
winfx3.pub
docs
errors
ilasm
jay
mcs
nunit24
packages
tests
tools
AUTHORS
COPYING
INSTALL.txt
Makefile
MonoIcon.png
README
ScalableMonoIcon.svg
mkinstalldirs
mono
msvc
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h

669 lines
24 KiB
C#
Raw Normal View History

//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Runtime;
using System.Xml.XPath;
/// <summary>
/// This structure contains the criteria used to select a set of nodes from a context node
///
/// Selectors select nodes with particular a relationship to a context node. Candidate nodes are first identified by
/// traversing away from the context node along an axis of traversal. The attribute axis, for example, identifies all
/// attributes of a given context node as candidates for selection.
///
/// The candidate nodeset identified by axis traversal is then refined by applying node tests.
/// A nodeType test constructs a new nodeset by selecting only those nodes of a given type from source candidate set
/// A qname test further refines this nodeset by selecting only those that match a given qname
/// </summary>
class NodeSelectCriteria
{
protected QueryAxis axis;
protected NodeQName qname;
protected NodeQNameType qnameType;
protected QueryNodeType type;
internal NodeSelectCriteria(QueryAxisType axis, NodeQName qname, QueryNodeType nodeType)
{
this.axis = QueryDataModel.GetAxis(axis);
this.qname = qname;
this.qnameType = qname.GetQNameType();
this.type = nodeType;
}
internal QueryAxis Axis
{
get
{
return this.axis;
}
}
internal bool IsCompressable
{
get
{
// PERF, Microsoft, weaken guard?
return QueryAxisType.Self == this.axis.Type || QueryAxisType.Child == this.axis.Type;
//return ((QueryAxisType.Self == this.axis.Type) || ((this.axis.Type != QueryAxisType.DescendantOrSelf || this.axis.Type != QueryAxisType.Descendant)&& 0 != ((QueryNodeType.Element | QueryNodeType.Root) & this.type)));
}
}
internal NodeQName QName
{
get
{
return this.qname;
}
}
internal QueryNodeType Type
{
get
{
return this.type;
}
}
#if NO
internal static NodeSelectCriteria Create(QueryAxisType axis, NodeQName qname, QueryNodeType nodeType)
{
return new NodeSelectCriteria(axis, qname, nodeType);
}
#endif
public bool Equals(NodeSelectCriteria criteria)
{
return (this.axis.Type == criteria.axis.Type && this.type == criteria.type && this.qname.Equals(criteria.qname));
}
#if NO
internal bool Match(SeekableXPathNavigator node)
{
return (this.MatchType(node) && this.MatchQName(node));
}
#endif
internal bool MatchType(SeekableXPathNavigator node)
{
QueryNodeType nodeType;
switch (node.NodeType)
{
default:
return false;
case XPathNodeType.Root:
nodeType = QueryNodeType.Root;
break;
case XPathNodeType.Attribute:
nodeType = QueryNodeType.Attribute;
break;
case XPathNodeType.Element:
nodeType = QueryNodeType.Element;
break;
case XPathNodeType.Comment:
nodeType = QueryNodeType.Comment;
break;
case XPathNodeType.Text:
case XPathNodeType.Whitespace:
case XPathNodeType.SignificantWhitespace:
nodeType = QueryNodeType.Text;
break;
case XPathNodeType.ProcessingInstruction:
nodeType = QueryNodeType.Processing;
break;
}
return (nodeType == (this.type & nodeType));
}
internal bool MatchQName(SeekableXPathNavigator node)
{
// Is this a standard qname test.. with known names and namespaces
switch (this.qnameType & NodeQNameType.Standard)
{
default:
break;
case NodeQNameType.Name:
// Selection criteria did not specify a namespace. Then, if the node supplies a namespace, we know
// that the criteria cannot possibly match
return (0 == node.NamespaceURI.Length && this.qname.EqualsName(node.LocalName));
case NodeQNameType.Standard:
string str = node.LocalName;
if (this.qname.name.Length == str.Length && this.qname.name == str)
{
str = node.NamespaceURI;
return (this.qname.ns.Length == str.Length && this.qname.ns == str);
}
return false;
}
if (NodeQNameType.Empty == this.qnameType)
{
return true;
}
// Maybe a wildcard
switch (this.qnameType & NodeQNameType.Wildcard)
{
default:
break;
case NodeQNameType.NameWildcard:
return this.qname.EqualsNamespace(node.NamespaceURI);
case NodeQNameType.Wildcard:
return true;
}
return false;
}
internal void Select(SeekableXPathNavigator contextNode, NodeSequence destSequence)
{
switch (this.type)
{
default:
if (QueryAxisType.Self == this.axis.Type)
{
if (this.MatchType(contextNode) && this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
}
}
else if (QueryAxisType.Descendant == this.axis.Type)
{
SelectDescendants(contextNode, destSequence);
}
else if (QueryAxisType.DescendantOrSelf == this.axis.Type)
{
destSequence.Add(contextNode);
SelectDescendants(contextNode, destSequence);
}
else if (QueryAxisType.Child == this.axis.Type)
{
// Select children of arbitrary type off the context node
if (contextNode.MoveToFirstChild())
{
do
{
// Select the node if its type and qname matches
if (this.MatchType(contextNode) && this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
}
}
while (contextNode.MoveToNext());
}
}
else if (QueryAxisType.Attribute == this.axis.Type)
{
if (contextNode.MoveToFirstAttribute())
{
do
{
// Select the node if its type and qname matches
if (this.MatchType(contextNode) && this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
// you can't have multiple instances of an attibute with the same qname
// Stop once one was found
// UNLESS WE HAVE A WILDCARD OFCOURSE!
if (0 == (this.qnameType & NodeQNameType.Wildcard))
{
break;
}
}
}
while (contextNode.MoveToNextAttribute());
}
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new QueryProcessingException(QueryProcessingError.Unexpected));
}
break;
case QueryNodeType.Attribute:
// Select attributes off the context Node
if (contextNode.MoveToFirstAttribute())
{
do
{
if (this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
// you can't have multiple instances of an attibute with the same qname
// Stop once one was found
// UNLESS WE HAVE A WILDCARD OFCOURSE!
if (0 == (this.qnameType & NodeQNameType.Wildcard))
{
break;
}
}
}
while (contextNode.MoveToNextAttribute());
}
break;
case QueryNodeType.ChildNodes:
if (QueryAxisType.Descendant == this.axis.Type)
{
// Select descendants of arbitrary type off the context node
SelectDescendants(contextNode, destSequence);
}
else
{
// Select children of arbitrary type off the context node
if (contextNode.MoveToFirstChild())
{
do
{
// Select the node if its type and qname matches
if (this.MatchType(contextNode) && this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
}
}
while (contextNode.MoveToNext());
}
}
break;
case QueryNodeType.Element:
if (QueryAxisType.Descendant == this.axis.Type)
{
// Select descendants of arbitrary type off the context node
SelectDescendants(contextNode, destSequence);
}
else if (QueryAxisType.DescendantOrSelf == this.axis.Type)
{
destSequence.Add(contextNode);
SelectDescendants(contextNode, destSequence);
}
else if (contextNode.MoveToFirstChild())
{
do
{
// Children could have non element nodes in line
// Select the node if it is an element and the qname matches
if (XPathNodeType.Element == contextNode.NodeType && this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
}
}
while (contextNode.MoveToNext());
}
break;
case QueryNodeType.Root:
contextNode.MoveToRoot();
destSequence.Add(contextNode);
break;
case QueryNodeType.Text:
// Select child text nodes
if (contextNode.MoveToFirstChild())
{
do
{
// Select the node if its type matches
// Can't just do a comparison to XPathNodeType.Text since whitespace nodes
// count as text
if (this.MatchType(contextNode))
{
destSequence.Add(contextNode);
}
}
while (contextNode.MoveToNext());
}
break;
}
}
internal Opcode Select(SeekableXPathNavigator contextNode, NodeSequence destSequence, SelectOpcode next)
{
Opcode returnOpcode = next.Next;
switch (this.type)
{
default:
if (QueryAxisType.Self == this.axis.Type)
{
if (this.MatchType(contextNode) && this.MatchQName(contextNode))
{
long position = contextNode.CurrentPosition;
returnOpcode = next.Eval(destSequence, contextNode);
contextNode.CurrentPosition = position;
}
}
else
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new QueryProcessingException(QueryProcessingError.Unexpected));
}
break;
case QueryNodeType.ChildNodes:
// Select children of arbitrary type off the context node
if (contextNode.MoveToFirstChild())
{
do
{
// Select the node if its type and qname matches
if (this.MatchType(contextNode) && this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
}
}
while (contextNode.MoveToNext());
}
break;
case QueryNodeType.Element:
// Select child elements
if (contextNode.MoveToFirstChild())
{
do
{
// Children could have non element nodes in line
// Select the node if it is an element and the qname matches
if (XPathNodeType.Element == contextNode.NodeType && this.MatchQName(contextNode))
{
long position = contextNode.CurrentPosition;
returnOpcode = next.Eval(destSequence, contextNode);
contextNode.CurrentPosition = position;
}
} while (contextNode.MoveToNext());
}
break;
case QueryNodeType.Root:
contextNode.MoveToRoot();
returnOpcode = next.Eval(destSequence, contextNode);
break;
}
return returnOpcode;
}
void SelectDescendants(SeekableXPathNavigator contextNode, NodeSequence destSequence)
{
int level = 1;
if (!contextNode.MoveToFirstChild())
{
return;
}
while (level > 0)
{
// Don't need type check. All child nodes allowed.
if (this.MatchQName(contextNode))
{
destSequence.Add(contextNode);
}
if (contextNode.MoveToFirstChild())
{
++level;
}
else if (contextNode.MoveToNext())
{
}
else
{
while (level > 0)
{
contextNode.MoveToParent();
--level;
if (contextNode.MoveToNext())
{
break;
}
}
}
}
}
#if DEBUG_FILTER
public override string ToString()
{
return string.Format("{0}, {1}:{2}", this.type, this.qname.ns, this.qname.name);
}
#endif
}
// General purpose selector
// Pops all parameters from the value stack
internal class SelectOpcode : Opcode
{
protected NodeSelectCriteria criteria;
internal SelectOpcode(NodeSelectCriteria criteria)
: this(OpcodeID.Select, criteria)
{
}
internal SelectOpcode(OpcodeID id, NodeSelectCriteria criteria)
: this(id, criteria, OpcodeFlags.None)
{
}
internal SelectOpcode(OpcodeID id, NodeSelectCriteria criteria, OpcodeFlags flags)
: base(id)
{
this.criteria = criteria;
this.flags |= (flags | OpcodeFlags.Select);
if (criteria.IsCompressable && (0 == (this.flags & OpcodeFlags.InitialSelect)))
{
this.flags |= OpcodeFlags.CompressableSelect;
}
}
internal NodeSelectCriteria Criteria
{
get
{
return this.criteria;
}
}
internal override bool Equals(Opcode op)
{
if (base.Equals(op))
{
return this.criteria.Equals(((SelectOpcode)op).criteria);
}
return false;
}
internal override Opcode Eval(ProcessingContext context)
{
StackFrame topFrame = context.TopSequenceArg;
SeekableXPathNavigator node = null;
Value[] sequences = context.Sequences;
for (int i = topFrame.basePtr; i <= topFrame.endPtr; ++i)
{
// Each NodeSequence will generate a new one, but only if the source FilterSequence isn't empty
// If the source FilterSequence is empty, release it and replace it with an empty sequence
NodeSequence sourceSeq = sequences[i].Sequence;
int sourceSeqCount = sourceSeq.Count;
if (sourceSeqCount == 0)
{
context.ReplaceSequenceAt(i, NodeSequence.Empty);
context.ReleaseSequence(sourceSeq);
}
else
{
NodeSequenceItem[] items = sourceSeq.Items;
if (sourceSeq.CanReuse(context))
{
node = items[0].GetNavigator();
sourceSeq.Clear();
sourceSeq.StartNodeset();
this.criteria.Select(node, sourceSeq);
sourceSeq.StopNodeset();
}
else
{
NodeSequence newSeq = null;
for (int item = 0; item < sourceSeqCount; ++item)
{
node = items[item].GetNavigator();
Fx.Assert(null != node, "");
if (null == newSeq)
{
newSeq = context.CreateSequence();
}
newSeq.StartNodeset();
this.criteria.Select(node, newSeq);
newSeq.StopNodeset();
}
context.ReplaceSequenceAt(i, (null != newSeq) ? newSeq : NodeSequence.Empty);
context.ReleaseSequence(sourceSeq);
}
}
}
return this.next;
}
internal override Opcode Eval(NodeSequence sequence, SeekableXPathNavigator node)
{
if (this.next == null || 0 == (this.next.Flags & OpcodeFlags.CompressableSelect))
{
// The next opcode is not a compressible select. Complete the select operation and return the next opcode
sequence.StartNodeset();
this.criteria.Select(node, sequence);
sequence.StopNodeset();
return this.next;
}
return this.criteria.Select(node, sequence, (SelectOpcode)this.next);
}
#if DEBUG_FILTER
public override string ToString()
{
return string.Format("{0} {1}", base.ToString(), this.criteria.ToString());
}
#endif
}
internal class InitialSelectOpcode : SelectOpcode
{
internal InitialSelectOpcode(NodeSelectCriteria criteria)
: base(OpcodeID.InitialSelect, criteria, OpcodeFlags.InitialSelect)
{
}
internal override Opcode Eval(ProcessingContext context)
{
StackFrame topFrame = context.TopSequenceArg;
Value[] sequences = context.Sequences;
bool wasInUse = context.SequenceStackInUse;
context.PushSequenceFrame();
for (int i = topFrame.basePtr; i <= topFrame.endPtr; ++i)
{
NodeSequence sourceSeq = sequences[i].Sequence;
int count = sourceSeq.Count;
if (count == 0)
{
// Empty sequence.
// Since there are no nodes in the sequence, we will track this sequence also
// using an empty sequence
if (!wasInUse)
context.PushSequence(NodeSequence.Empty);
}
else
{
NodeSequenceItem[] items = sourceSeq.Items;
for (int item = 0; item < sourceSeq.Count; ++item)
{
SeekableXPathNavigator node = items[item].GetNavigator();
Fx.Assert(null != node, "");
NodeSequence newSeq = context.CreateSequence();
newSeq.StartNodeset();
this.criteria.Select(node, newSeq);
newSeq.StopNodeset();
context.PushSequence(newSeq);
}
}
}
return this.next;
}
}
internal class SelectRootOpcode : Opcode
{
internal SelectRootOpcode()
: base(OpcodeID.SelectRoot)
{
}
internal override Opcode Eval(ProcessingContext context)
{
// The query processor object also serves as the query document root
int iterationCount = context.IterationCount;
Opcode returnOpcode = this.next;
// A root is always an initial step
context.PushSequenceFrame();
NodeSequence seq = context.CreateSequence();
if (this.next != null && 0 != (this.next.Flags & OpcodeFlags.CompressableSelect))
{
SeekableXPathNavigator node = context.Processor.ContextNode;
node.MoveToRoot();
returnOpcode = this.next.Eval(seq, node);
while (returnOpcode != null && 0 != (returnOpcode.Flags & OpcodeFlags.CompressableSelect))
{
returnOpcode = returnOpcode.Next;
}
}
else
{
// Roots do not have any qnames..
seq.StartNodeset();
SeekableXPathNavigator node = context.Processor.ContextNode;
node.MoveToRoot();
seq.Add(node);
seq.StopNodeset();
}
if (seq.Count == 0)
{
context.ReleaseSequence(seq);
seq = NodeSequence.Empty;
}
for (int i = 0; i < iterationCount; ++i)
{
context.PushSequence(seq);
}
if (iterationCount > 1)
seq.refCount += iterationCount - 1;
return returnOpcode;
}
}
}