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
- ActivityDesigner.cs
- TextCompositionManager.cs
- BookmarkCallbackWrapper.cs
- User.cs
- FormatVersion.cs
- BoolExpr.cs
- CommonXSendMessage.cs
- TextClipboardData.cs
- SmiXetterAccessMap.cs
- FileSystemInfo.cs
- TrackPointCollection.cs
- OciEnlistContext.cs
- TextEndOfSegment.cs
- SQLSingle.cs
- TraceContextEventArgs.cs
- AnnotationAuthorChangedEventArgs.cs
- SoapInteropTypes.cs
- ApplicationTrust.cs
- SiteOfOriginContainer.cs
- XmlDocumentSurrogate.cs
- ConfigurationStrings.cs
- SystemFonts.cs
- SessionPageStateSection.cs
- BinHexEncoder.cs
- PersonalizablePropertyEntry.cs
- MSAANativeProvider.cs
- SingleAnimationUsingKeyFrames.cs
- LayoutTable.cs
- BindingBase.cs
- DesignerVerb.cs
- CodeTypeMemberCollection.cs
- PenContext.cs
- ImageSourceConverter.cs
- ExpressionNode.cs
- AbsoluteQuery.cs
- COM2Enum.cs
- OdbcDataAdapter.cs
- EventManager.cs
- TraceSource.cs
- RepeatButtonAutomationPeer.cs
- AuthenticationModuleElement.cs
- OdbcError.cs
- CurrentChangingEventArgs.cs
- ScrollBar.cs
- Guid.cs
- PipeSecurity.cs
- WpfMemberInvoker.cs
- DesignBindingPropertyDescriptor.cs
- namescope.cs
- ContainerParaClient.cs
- Base64Decoder.cs
- Stylesheet.cs
- BridgeDataReader.cs
- DetailsViewCommandEventArgs.cs
- TextRangeEditLists.cs
- RtfFormatStack.cs
- WindowsSolidBrush.cs
- PropertyTabAttribute.cs
- Bold.cs
- SHA384.cs
- DataGridViewRowPrePaintEventArgs.cs
- BitArray.cs
- ViewStateModeByIdAttribute.cs
- Adorner.cs
- ChtmlCalendarAdapter.cs
- SqlWriter.cs
- CultureSpecificStringDictionary.cs
- PipeStream.cs
- ObjectAnimationUsingKeyFrames.cs
- XmlElement.cs
- DataServiceSaveChangesEventArgs.cs
- GridLength.cs
- DebugInfoExpression.cs
- XmlSchemaInfo.cs
- EffectiveValueEntry.cs
- ArrayList.cs
- GeometryGroup.cs
- Inline.cs
- ObjectDataSource.cs
- ScrollItemProviderWrapper.cs
- SmiContextFactory.cs
- WindowsNonControl.cs
- XmlSerializationReader.cs
- PinProtectionHelper.cs
- ObjectQuery.cs
- WebCategoryAttribute.cs
- WebPartCatalogCloseVerb.cs
- TextFormatterContext.cs
- BookmarkManager.cs
- UnsafeNativeMethods.cs
- ProcessRequestArgs.cs
- ADMembershipUser.cs
- UserUseLicenseDictionaryLoader.cs
- Selection.cs
- SoapUnknownHeader.cs
- ScrollItemPattern.cs
- SocketException.cs
- ComponentSerializationService.cs
- BooleanAnimationBase.cs
- PersistenceException.cs