Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / EndpointAddressMessageFilterTable.cs / 1 / EndpointAddressMessageFilterTable.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Dispatcher { using System; using System.ServiceModel.Channels; using System.ServiceModel; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.ServiceModel.Security; using System.Xml; using QName = System.ServiceModel.Dispatcher.EndpointAddressProcessor.QName; using HeaderBit = System.ServiceModel.Dispatcher.EndpointAddressProcessor.HeaderBit; using System.ServiceModel.Diagnostics; internal class EndpointAddressMessageFilterTable: IMessageFilterTable { protected Dictionary filters; protected Dictionary candidates; WeakReference processorPool; int size; int nextBit; Dictionary headerLookup; Dictionary toHostLookup; Dictionary toNoHostLookup; internal class ProcessorPool { EndpointAddressProcessor processor; internal ProcessorPool() { } internal EndpointAddressProcessor Pop() { EndpointAddressProcessor p = this.processor; if (null != p) { this.processor = (EndpointAddressProcessor)p.next; p.next = null; return p; } return null; } internal void Push(EndpointAddressProcessor p) { p.next = this.processor; this.processor = p; } } public EndpointAddressMessageFilterTable() { this.processorPool = new WeakReference(null); this.size = 0; this.nextBit = 0; this.filters = new Dictionary (); this.candidates = new Dictionary (); this.headerLookup = new Dictionary (); InitializeLookupTables(); } protected virtual void InitializeLookupTables() { this.toHostLookup = new Dictionary (EndpointAddressMessageFilter.HostUriComparer.Value); this.toNoHostLookup = new Dictionary (EndpointAddressMessageFilter.NoHostUriComparer.Value); } public TFilterData this[MessageFilter filter] { get { return this.filters[filter]; } set { if(this.filters.ContainsKey(filter)) { this.filters[filter] = value; this.candidates[filter].data = value; } else { this.Add(filter, value); } } } public int Count { get { return this.filters.Count; } } public bool IsReadOnly { get { return false; } } public ICollection Keys { get { return this.filters.Keys; } } public ICollection Values { get { return this.filters.Values; } } public virtual void Add(MessageFilter filter, TFilterData data) { if (filter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter"); } Add((EndpointAddressMessageFilter)filter, data); } public virtual void Add(EndpointAddressMessageFilter filter, TFilterData data) { if (filter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter"); } this.filters.Add(filter, data); // Create the candidate byte[] mask = BuildMask(filter.HeaderLookup); Candidate can = new Candidate(filter, data, mask, filter.HeaderLookup); this.candidates.Add(filter, can); CandidateSet cset; #pragma warning suppress 56506 // [....], EndpointAddressMessageFilter.Address can never be null Uri soapToAddress = filter.Address.Uri; if(filter.IncludeHostNameInComparison) { if (!this.toHostLookup.TryGetValue(soapToAddress, out cset)) { cset = new CandidateSet(); this.toHostLookup.Add(soapToAddress, cset); } } else { if (!this.toNoHostLookup.TryGetValue(soapToAddress, out cset)) { cset = new CandidateSet(); this.toNoHostLookup.Add(soapToAddress, cset); } } cset.candidates.Add(can); IncrementQNameCount(cset, filter.Address); } protected void IncrementQNameCount(CandidateSet cset, EndpointAddress address) { // Update the QName ref count QName qname; int cnt; #pragma warning suppress 56506 // [....], EndpointAddressMessageFilter.Address can never be null for (int i = 0; i < address.Headers.Count; ++i) { AddressHeader parameter = address.Headers[i]; qname.name = parameter.Name; qname.ns = parameter.Namespace; if (cset.qnames.TryGetValue(qname, out cnt)) { cset.qnames[qname] = cnt + 1; } else { cset.qnames.Add(qname, 1); } } } public void Add(KeyValuePair item) { Add(item.Key, item.Value); } protected byte[] BuildMask(Dictionary headerLookup) { HeaderBit[] bits; byte[] mask = null; foreach(KeyValuePair item in headerLookup) { if(this.headerLookup.TryGetValue(item.Key, out bits)) { if(bits.Length < item.Value.Length) { int old = bits.Length; Array.Resize(ref bits, item.Value.Length); for(int i = old; i < item.Value.Length; ++i) { bits[i] = new HeaderBit(this.nextBit++); } this.headerLookup[item.Key] = bits; } } else { bits = new HeaderBit[item.Value.Length]; for(int i = 0; i < item.Value.Length; ++i) { bits[i] = new HeaderBit(this.nextBit++); } this.headerLookup.Add(item.Key, bits); } for(int i = 0; i < item.Value.Length; ++i) { bits[i].AddToMask(ref mask); } } if(this.nextBit == 0) { this.size = 0; } else { this.size = (this.nextBit-1) / 8 + 1; } return mask; } public void Clear() { this.size = 0; this.nextBit = 0; this.filters.Clear(); this.candidates.Clear(); this.headerLookup.Clear(); ClearLookupTables(); } protected virtual void ClearLookupTables() { if (this.toHostLookup != null) { this.toHostLookup.Clear(); } if (this.toNoHostLookup != null) { this.toNoHostLookup.Clear(); } } public bool Contains(KeyValuePair item) { return ((ICollection >)this.filters).Contains(item); } public bool ContainsKey(MessageFilter filter) { if (filter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter"); } return this.filters.ContainsKey(filter); } public void CopyTo(KeyValuePair [] array, int arrayIndex) { ((ICollection >)this.filters).CopyTo(array, arrayIndex); } EndpointAddressProcessor CreateProcessor(int length) { EndpointAddressProcessor p = null; lock (this.processorPool) { ProcessorPool pool = this.processorPool.Target as ProcessorPool; if (null != pool) { p = pool.Pop(); } } if (null != p) { p.Clear(length); return p; } return new EndpointAddressProcessor(length); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public IEnumerator > GetEnumerator() { return this.filters.GetEnumerator(); } internal virtual bool TryMatchCandidateSet(Uri to, bool includeHostNameInComparison, out CandidateSet cset) { if (includeHostNameInComparison) { return this.toHostLookup.TryGetValue(to, out cset); } else { return this.toNoHostLookup.TryGetValue(to, out cset); } } Candidate InnerMatch(Message message) { Uri to = message.Headers.To; if (to == null) { return null; } CandidateSet cset = null; Candidate can = null; if (TryMatchCandidateSet(to, true/*includeHostNameInComparison*/, out cset)) { can = GetSingleMatch(cset, message); } if (TryMatchCandidateSet(to, false/*includeHostNameInComparison*/, out cset)) { Candidate c = GetSingleMatch(cset, message); if(c != null) { if(can != null) { Collection matches = new Collection (); matches.Add(can.filter); matches.Add(c.filter); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches)); } can = c; } } return can; } Candidate GetSingleMatch(CandidateSet cset, Message message) { int candiCount = cset.candidates.Count; if(cset.qnames.Count == 0) { if(candiCount == 0) { return null; } else if(candiCount == 1) { return cset.candidates[0]; } else { Collection matches = new Collection (); for(int i = 0; i < candiCount; ++i) { matches.Add(cset.candidates[i].filter); } throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches), message); } } EndpointAddressProcessor context = CreateProcessor(this.size); context.ProcessHeaders(message, cset.qnames, this.headerLookup); Candidate can = null; List candis = cset.candidates; for(int i = 0; i < candiCount; ++i) { if(context.TestMask(candis[i].mask)) { if(can != null) { Collection matches = new Collection (); matches.Add(can.filter); matches.Add(candis[i].filter); throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, matches), message); } can = candis[i]; } } ReleaseProcessor(context); return can; } void InnerMatchData(Message message, ICollection results) { Uri to = message.Headers.To; if (to != null) { CandidateSet cset; if (TryMatchCandidateSet(to, true /*includeHostNameInComparison*/, out cset)) { InnerMatchData(message, results, cset); } if (TryMatchCandidateSet(to, false /*includeHostNameInComparison*/, out cset)) { InnerMatchData(message, results, cset); } } } void InnerMatchData(Message message, ICollection results, CandidateSet cset) { EndpointAddressProcessor context = CreateProcessor(this.size); context.ProcessHeaders(message, cset.qnames, this.headerLookup); List candis = cset.candidates; for (int i = 0; i < candis.Count; ++i) { if (context.TestMask(candis[i].mask)) { results.Add(candis[i].data); } } ReleaseProcessor(context); } protected void InnerMatchFilters(Message message, ICollection results) { Uri to = message.Headers.To; if (to != null) { CandidateSet cset; if (TryMatchCandidateSet(to, true/*includeHostNameInComparison*/, out cset)) { InnerMatchFilters(message, results, cset); } if (TryMatchCandidateSet(to, false/*includeHostNameInComparison*/, out cset)) { InnerMatchFilters(message, results, cset); } } } void InnerMatchFilters(Message message, ICollection results, CandidateSet cset) { EndpointAddressProcessor context = CreateProcessor(this.size); context.ProcessHeaders(message, cset.qnames, this.headerLookup); List candis = cset.candidates; for (int i = 0; i < candis.Count; ++i) { if (context.TestMask(candis[i].mask)) { results.Add(candis[i].filter); } } ReleaseProcessor(context); } public bool GetMatchingValue(Message message, out TFilterData data) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); } Candidate can = InnerMatch(message); if(can == null) { data = default(TFilterData); return false; } data = can.data; return true; } public bool GetMatchingValue(MessageBuffer messageBuffer, out TFilterData data) { if (messageBuffer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer"); } Message msg = messageBuffer.CreateMessage(); Candidate can = null; try { can = InnerMatch(msg); } finally { msg.Close(); } if(can == null) { data = default(TFilterData); return false; } data = can.data; return true; } public bool GetMatchingValues(Message message, ICollection results) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); } if (results == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results"); } int count = results.Count; InnerMatchData(message, results); return count != results.Count; } public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection results) { if (messageBuffer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer"); } if (results == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results"); } Message msg = messageBuffer.CreateMessage(); try { int count = results.Count; InnerMatchData(msg, results); return count != results.Count; } finally { msg.Close(); } } public bool GetMatchingFilter(Message message, out MessageFilter filter) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); } Candidate can = InnerMatch(message); if(can != null) { filter = can.filter; return true; } filter = null; return false; } public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter) { if (messageBuffer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer"); } Message msg = messageBuffer.CreateMessage(); Candidate can = null; try { can = InnerMatch(msg); } finally { msg.Close(); } if(can != null) { filter = can.filter; return true; } filter = null; return false; } public bool GetMatchingFilters(Message message, ICollection results) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message"); } if (results == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results"); } int count = results.Count; InnerMatchFilters(message, results); return count != results.Count; } public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection results) { if (messageBuffer == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageBuffer"); } if (results == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results"); } Message msg = messageBuffer.CreateMessage(); try { int count = results.Count; InnerMatchFilters(msg, results); return count != results.Count; } finally { msg.Close(); } } protected void RebuildMasks() { this.nextBit = 0; this.size = 0; // Clear out all the bits. this.headerLookup.Clear(); // Rebuild the masks foreach(Candidate can in this.candidates.Values) { can.mask = BuildMask(can.headerLookup); } } void ReleaseProcessor(EndpointAddressProcessor processor) { lock (this.processorPool) { ProcessorPool pool = this.processorPool.Target as ProcessorPool; if (null == pool) { pool = new ProcessorPool(); this.processorPool.Target = pool; } pool.Push(processor); } } public virtual bool Remove(MessageFilter filter) { if (filter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter"); } EndpointAddressMessageFilter saFilter = filter as EndpointAddressMessageFilter; if(saFilter != null) { return Remove(saFilter); } return false; } public virtual bool Remove(EndpointAddressMessageFilter filter) { if (filter == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter"); } if(!this.filters.Remove(filter)) { return false; } Candidate can = this.candidates[filter]; #pragma warning suppress 56506 // [....], EndpointAddressMessageFilter.Address can never be null Uri soapToAddress = filter.Address.Uri; CandidateSet cset = null; if(filter.IncludeHostNameInComparison) { cset = this.toHostLookup[soapToAddress]; } else { cset = this.toNoHostLookup[soapToAddress]; } this.candidates.Remove(filter); if(cset.candidates.Count == 1) { if(filter.IncludeHostNameInComparison) { this.toHostLookup.Remove(soapToAddress); } else { this.toNoHostLookup.Remove(soapToAddress); } } else { DecrementQNameCount(cset, filter.Address); // Remove Candidate cset.candidates.Remove(can); } RebuildMasks(); return true; } protected void DecrementQNameCount(CandidateSet cset, EndpointAddress address) { // Adjust QName counts QName qname; #pragma warning suppress 56506 // [....], EndpointAddress.Headers can never be null for (int i = 0; i < address.Headers.Count; ++i) { AddressHeader parameter = address.Headers[i]; qname.name = parameter.Name; qname.ns = parameter.Namespace; int cnt = cset.qnames[qname]; if (cnt == 1) { cset.qnames.Remove(qname); } else { cset.qnames[qname] = cnt - 1; } } } public bool Remove(KeyValuePair item) { if(((ICollection >)this.filters).Contains(item)) { return Remove(item.Key); } return false; } internal class Candidate { internal MessageFilter filter; internal TFilterData data; internal byte[] mask; internal Dictionary headerLookup; internal Candidate(MessageFilter filter, TFilterData data, byte[] mask, Dictionary headerLookup) { this.filter = filter; this.data = data; this.mask = mask; this.headerLookup = headerLookup; } } internal class CandidateSet { internal Dictionary qnames; internal List candidates; internal CandidateSet() { this.qnames = new Dictionary (EndpointAddressProcessor.QNameComparer); this.candidates = new List (); } } public bool TryGetValue(MessageFilter filter, out TFilterData data) { return this.filters.TryGetValue(filter, out data); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WsdlWriter.cs
- XmlTextWriter.cs
- DrawingCollection.cs
- XmlTextAttribute.cs
- Light.cs
- listitem.cs
- SafeRegistryHandle.cs
- Application.cs
- DbUpdateCommandTree.cs
- RemotingConfigParser.cs
- BamlRecordReader.cs
- DescendantBaseQuery.cs
- MaterializeFromAtom.cs
- SocketInformation.cs
- TypeLoader.cs
- InvalidPropValue.cs
- XmlNamespaceMapping.cs
- EncoderReplacementFallback.cs
- SQLDecimal.cs
- RsaKeyGen.cs
- DropShadowBitmapEffect.cs
- StylusPointPropertyUnit.cs
- DateTimeOffsetStorage.cs
- RegexCode.cs
- LinqDataSourceUpdateEventArgs.cs
- VerticalAlignConverter.cs
- LabelLiteral.cs
- TemplateXamlTreeBuilder.cs
- codemethodreferenceexpression.cs
- InstanceDescriptor.cs
- SqlProvider.cs
- DataObjectAttribute.cs
- RequestSecurityTokenForGetBrowserToken.cs
- InputLanguageManager.cs
- EqualityComparer.cs
- ToolboxItemImageConverter.cs
- AppDomainGrammarProxy.cs
- WebPartManager.cs
- Triangle.cs
- DropDownList.cs
- NumberFormatter.cs
- Adorner.cs
- WebServiceClientProxyGenerator.cs
- CacheAxisQuery.cs
- CodeDefaultValueExpression.cs
- HttpConfigurationContext.cs
- Light.cs
- EventItfInfo.cs
- OrderedDictionary.cs
- ActivityExecutionWorkItem.cs
- StringComparer.cs
- SamlAssertionKeyIdentifierClause.cs
- TreeChangeInfo.cs
- RequestTimeoutManager.cs
- PersistChildrenAttribute.cs
- RegexRunner.cs
- SchemaElementDecl.cs
- HttpListenerRequestUriBuilder.cs
- PerformanceCountersElement.cs
- TransactedBatchContext.cs
- AmbientProperties.cs
- TraceHandler.cs
- CompensationHandlingFilter.cs
- safex509handles.cs
- Int64AnimationUsingKeyFrames.cs
- OrderingInfo.cs
- PropertyGridCommands.cs
- RootAction.cs
- PasswordTextContainer.cs
- TreeNode.cs
- NotifyParentPropertyAttribute.cs
- ListViewHitTestInfo.cs
- SpeakCompletedEventArgs.cs
- UserControlBuildProvider.cs
- AssemblyAttributes.cs
- Image.cs
- JsonSerializer.cs
- ToolboxComponentsCreatingEventArgs.cs
- CryptoConfig.cs
- ValidationPropertyAttribute.cs
- ContainerParagraph.cs
- ObjectList.cs
- TypeRestriction.cs
- HttpContext.cs
- StrongNameIdentityPermission.cs
- InkCanvasFeedbackAdorner.cs
- ParallelEnumerableWrapper.cs
- CollectionViewGroup.cs
- DataGridLinkButton.cs
- DetailsViewModeEventArgs.cs
- Grid.cs
- BinaryReader.cs
- WebPartConnectionsDisconnectVerb.cs
- LoadedEvent.cs
- SectionVisual.cs
- ReferenceConverter.cs
- ExpanderAutomationPeer.cs
- ConfigXmlAttribute.cs
- TableAdapterManagerNameHandler.cs
- WebServicesSection.cs