Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / PipelineModuleStepContainer.cs / 1 / PipelineModuleStepContainer.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * A simple container class for module events * * Copyright (c) 2005 Microsoft Corporation */ namespace System.Web { using System; using System.Collections.Generic; using System.Globalization; using System.Web; using Debug=System.Web.Util.Debug; // this class is a container for application module events // there is one instance of this class per module per application instance // Since execution steps are tied to an application instance, this needs to be // as well internal sealed class PipelineModuleStepContainer { #if DBG string _moduleName; internal string DebugModuleName { set { Debug.Assert( !String.IsNullOrEmpty(value), "!String.IsNullOrEmpty(value)"); if (_moduleName != null) { // make sure we're not ever crossing the modules Debug.Assert(value == _moduleName, "value == _moduleName"); } _moduleName = value; } get { return (String.IsNullOrEmpty(_moduleName)) ? String.Empty : _moduleName; } } #endif // request notifications are bit flags in a DWORD // so we will won't have more than 12 // we could do with fewer but in order simplify indexing, // we'll use the whole 12 // the arrays are lazily allocated so modules that only // subscribe to one type of event will only get one type of step arr List[] _moduleSteps; List [] _modulePostSteps; internal PipelineModuleStepContainer() { } private List GetStepArray(RequestNotification notification, bool isPostEvent) { #if DBG Debug.Trace("PipelineRuntime", "GetStepArray for " + DebugModuleName + " for " + notification.ToString() + " and " + isPostEvent + "\r\n"); #endif List [] steps = _moduleSteps; if (isPostEvent) { steps = _modulePostSteps; } Debug.Assert(null != steps, "null != steps"); int index = EventToIndex(notification); Debug.Assert(index != -1, "index != -1"); Debug.Trace("PipelineRuntime", "GetStepArray: " + notification.ToString() + " mapped to index " + index.ToString(CultureInfo.InvariantCulture) + "\r\n"); List stepArray = steps[index]; // we shouldn't be asking for events that aren't mapped to this // module at all Debug.Assert(null != stepArray, "null != stepArray"); return stepArray; } internal int GetEventCount(RequestNotification notification, bool isPostEvent) { List stepArray = GetStepArray(notification, isPostEvent); if (null == stepArray) { return 0; } return stepArray.Count; } internal HttpApplication.IExecutionStep GetNextEvent(RequestNotification notification, bool isPostEvent, int eventIndex) { List stepArray = GetStepArray(notification, isPostEvent); Debug.Assert(eventIndex >= 0, "eventIndex >= 0"); Debug.Assert(eventIndex < stepArray.Count, "eventIndex < stepArray.Count"); return stepArray[eventIndex]; } internal void RemoveEvent(RequestNotification notification, bool isPostEvent, Delegate handler) { // if module instances unregister multiple times, this can fail on subsequent attempts // so don't use GetStepArray which does extra checked verification List [] steps = _moduleSteps; if (isPostEvent) { steps = _modulePostSteps; } if (steps == null) { return; } int index = EventToIndex(notification); List stepArray = steps[index]; if (null == stepArray) { return; } int toRemove = -1; HttpApplication.SyncEventExecutionStep syncStep; for (int i = 0; i < stepArray.Count; i++ ) { // we don't support removing async event handlers // but the event syntax forces us to handle [....] events syncStep = stepArray[i] as HttpApplication.SyncEventExecutionStep; if (null != syncStep) { if (syncStep.Handler == (EventHandler)handler) { toRemove = i; break; } } } if (toRemove != -1) { stepArray.RemoveAt(toRemove); } } internal void AddEvent(RequestNotification notification, bool isPostEvent, HttpApplication.IExecutionStep step) { int index = EventToIndex(notification); #if DBG Debug.Trace("PipelineRuntime", "Adding event: " + DebugModuleName + " " + notification.ToString() + " " + isPostEvent.ToString() + "@ index " + index.ToString(CultureInfo.InvariantCulture) + "\r\n"); #endif Debug.Assert(index != -1, "index != -1"); List [] steps = null; if (isPostEvent) { if (null == _modulePostSteps) { _modulePostSteps = new List [ 32 ]; } steps = _modulePostSteps; } else { if (null == _moduleSteps) { _moduleSteps = new List [ 32 ]; } steps = _moduleSteps; } Debug.Assert(steps != null, "steps != null"); // retrieve the steps for this event (typically none at this point) // allocate a new container as necessary and add this step // in the event that a single module has registered more than once // for a given event, we'll have multiple steps here List stepArray = steps[index]; if (null == stepArray) { // first touch, instantiate and save it stepArray = new List (); steps[index] = stepArray; } stepArray.Add(step); } // we have tried various techniques here for converting a request notification // into an index but a simple switch statement has so far performed the best // basically, the problem is converting a single on bit to its position // so 0x00000001 == 0, 0x00000002 == 1, etc. // Managed code doesn't support all the request flags so we only translate // the ones we deal with to keep the switch table as simple as possible private static int EventToIndex(RequestNotification notification) { int index = -1; switch (notification) { // 0x00000001 case RequestNotification.BeginRequest: return 0; // 0x00000002 case RequestNotification.AuthenticateRequest: return 1; // 0x00000004 case RequestNotification.AuthorizeRequest: return 2; // 0x00000008 case RequestNotification.ResolveRequestCache: return 3; // 0x00000010 case RequestNotification.MapRequestHandler: return 4; // 0x00000020 case RequestNotification.AcquireRequestState: return 5; // 0x00000040 case RequestNotification.PreExecuteRequestHandler: return 6; // 0x00000080 case RequestNotification.ExecuteRequestHandler: return 7; // 0x00000100 case RequestNotification.ReleaseRequestState: return 8; // 0x00000200 case RequestNotification.UpdateRequestCache: return 9; // 0x00000400 case RequestNotification.LogRequest: return 10; // 0x00000800 case RequestNotification.EndRequest: return 11; // 0x20000000 case RequestNotification.SendResponse : return 12; default: Debug.Assert(index != -1, "invalid request notification--need to update switch table?"); return index; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * A simple container class for module events * * Copyright (c) 2005 Microsoft Corporation */ namespace System.Web { using System; using System.Collections.Generic; using System.Globalization; using System.Web; using Debug=System.Web.Util.Debug; // this class is a container for application module events // there is one instance of this class per module per application instance // Since execution steps are tied to an application instance, this needs to be // as well internal sealed class PipelineModuleStepContainer { #if DBG string _moduleName; internal string DebugModuleName { set { Debug.Assert( !String.IsNullOrEmpty(value), "!String.IsNullOrEmpty(value)"); if (_moduleName != null) { // make sure we're not ever crossing the modules Debug.Assert(value == _moduleName, "value == _moduleName"); } _moduleName = value; } get { return (String.IsNullOrEmpty(_moduleName)) ? String.Empty : _moduleName; } } #endif // request notifications are bit flags in a DWORD // so we will won't have more than 12 // we could do with fewer but in order simplify indexing, // we'll use the whole 12 // the arrays are lazily allocated so modules that only // subscribe to one type of event will only get one type of step arr List[] _moduleSteps; List [] _modulePostSteps; internal PipelineModuleStepContainer() { } private List GetStepArray(RequestNotification notification, bool isPostEvent) { #if DBG Debug.Trace("PipelineRuntime", "GetStepArray for " + DebugModuleName + " for " + notification.ToString() + " and " + isPostEvent + "\r\n"); #endif List [] steps = _moduleSteps; if (isPostEvent) { steps = _modulePostSteps; } Debug.Assert(null != steps, "null != steps"); int index = EventToIndex(notification); Debug.Assert(index != -1, "index != -1"); Debug.Trace("PipelineRuntime", "GetStepArray: " + notification.ToString() + " mapped to index " + index.ToString(CultureInfo.InvariantCulture) + "\r\n"); List stepArray = steps[index]; // we shouldn't be asking for events that aren't mapped to this // module at all Debug.Assert(null != stepArray, "null != stepArray"); return stepArray; } internal int GetEventCount(RequestNotification notification, bool isPostEvent) { List stepArray = GetStepArray(notification, isPostEvent); if (null == stepArray) { return 0; } return stepArray.Count; } internal HttpApplication.IExecutionStep GetNextEvent(RequestNotification notification, bool isPostEvent, int eventIndex) { List stepArray = GetStepArray(notification, isPostEvent); Debug.Assert(eventIndex >= 0, "eventIndex >= 0"); Debug.Assert(eventIndex < stepArray.Count, "eventIndex < stepArray.Count"); return stepArray[eventIndex]; } internal void RemoveEvent(RequestNotification notification, bool isPostEvent, Delegate handler) { // if module instances unregister multiple times, this can fail on subsequent attempts // so don't use GetStepArray which does extra checked verification List [] steps = _moduleSteps; if (isPostEvent) { steps = _modulePostSteps; } if (steps == null) { return; } int index = EventToIndex(notification); List stepArray = steps[index]; if (null == stepArray) { return; } int toRemove = -1; HttpApplication.SyncEventExecutionStep syncStep; for (int i = 0; i < stepArray.Count; i++ ) { // we don't support removing async event handlers // but the event syntax forces us to handle [....] events syncStep = stepArray[i] as HttpApplication.SyncEventExecutionStep; if (null != syncStep) { if (syncStep.Handler == (EventHandler)handler) { toRemove = i; break; } } } if (toRemove != -1) { stepArray.RemoveAt(toRemove); } } internal void AddEvent(RequestNotification notification, bool isPostEvent, HttpApplication.IExecutionStep step) { int index = EventToIndex(notification); #if DBG Debug.Trace("PipelineRuntime", "Adding event: " + DebugModuleName + " " + notification.ToString() + " " + isPostEvent.ToString() + "@ index " + index.ToString(CultureInfo.InvariantCulture) + "\r\n"); #endif Debug.Assert(index != -1, "index != -1"); List [] steps = null; if (isPostEvent) { if (null == _modulePostSteps) { _modulePostSteps = new List [ 32 ]; } steps = _modulePostSteps; } else { if (null == _moduleSteps) { _moduleSteps = new List [ 32 ]; } steps = _moduleSteps; } Debug.Assert(steps != null, "steps != null"); // retrieve the steps for this event (typically none at this point) // allocate a new container as necessary and add this step // in the event that a single module has registered more than once // for a given event, we'll have multiple steps here List stepArray = steps[index]; if (null == stepArray) { // first touch, instantiate and save it stepArray = new List (); steps[index] = stepArray; } stepArray.Add(step); } // we have tried various techniques here for converting a request notification // into an index but a simple switch statement has so far performed the best // basically, the problem is converting a single on bit to its position // so 0x00000001 == 0, 0x00000002 == 1, etc. // Managed code doesn't support all the request flags so we only translate // the ones we deal with to keep the switch table as simple as possible private static int EventToIndex(RequestNotification notification) { int index = -1; switch (notification) { // 0x00000001 case RequestNotification.BeginRequest: return 0; // 0x00000002 case RequestNotification.AuthenticateRequest: return 1; // 0x00000004 case RequestNotification.AuthorizeRequest: return 2; // 0x00000008 case RequestNotification.ResolveRequestCache: return 3; // 0x00000010 case RequestNotification.MapRequestHandler: return 4; // 0x00000020 case RequestNotification.AcquireRequestState: return 5; // 0x00000040 case RequestNotification.PreExecuteRequestHandler: return 6; // 0x00000080 case RequestNotification.ExecuteRequestHandler: return 7; // 0x00000100 case RequestNotification.ReleaseRequestState: return 8; // 0x00000200 case RequestNotification.UpdateRequestCache: return 9; // 0x00000400 case RequestNotification.LogRequest: return 10; // 0x00000800 case RequestNotification.EndRequest: return 11; // 0x20000000 case RequestNotification.SendResponse : return 12; default: Debug.Assert(index != -1, "invalid request notification--need to update switch table?"); return index; } } } } // 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
- HttpWrapper.cs
- ClientSettingsSection.cs
- XamlVector3DCollectionSerializer.cs
- ExpressionNode.cs
- ResourceExpressionBuilder.cs
- TypeTypeConverter.cs
- EditorPartChrome.cs
- CqlBlock.cs
- SiteMapNodeItem.cs
- NavigationService.cs
- WindowsBrush.cs
- XmlNodeWriter.cs
- StringResourceManager.cs
- MethodRental.cs
- DeviceSpecificChoiceCollection.cs
- XmlDocumentFragment.cs
- SectionRecord.cs
- TextCharacters.cs
- TableLayoutPanelBehavior.cs
- GACIdentityPermission.cs
- TimeSpanMinutesConverter.cs
- SharedPerformanceCounter.cs
- CancellationTokenRegistration.cs
- NullableDoubleAverageAggregationOperator.cs
- SerializerProvider.cs
- AnimationClockResource.cs
- ActiveXHost.cs
- MdiWindowListStrip.cs
- ManipulationDeltaEventArgs.cs
- Pen.cs
- XLinq.cs
- ActiveXHost.cs
- PagerStyle.cs
- SchemaNamespaceManager.cs
- AdornedElementPlaceholder.cs
- HttpFileCollectionBase.cs
- ProfileBuildProvider.cs
- TableCellAutomationPeer.cs
- MarkedHighlightComponent.cs
- CachedFontFace.cs
- ZipIOLocalFileHeader.cs
- TextViewElement.cs
- QilReference.cs
- ImageClickEventArgs.cs
- SystemEvents.cs
- PathData.cs
- XmlParserContext.cs
- SoapSchemaImporter.cs
- IndividualDeviceConfig.cs
- HostingPreferredMapPath.cs
- DefaultSerializationProviderAttribute.cs
- DataGridViewImageColumn.cs
- DataServiceExpressionVisitor.cs
- ListBase.cs
- WebPageTraceListener.cs
- StorageEntityContainerMapping.cs
- ProgressPage.cs
- _Rfc2616CacheValidators.cs
- NonSerializedAttribute.cs
- SystemUdpStatistics.cs
- Function.cs
- GraphicsContext.cs
- DataException.cs
- GraphicsState.cs
- EntityDataSourceView.cs
- GeneralTransform3DCollection.cs
- MouseGesture.cs
- CacheOutputQuery.cs
- CommandHelper.cs
- RegexGroup.cs
- VersionedStreamOwner.cs
- ViewgenContext.cs
- WebDisplayNameAttribute.cs
- CurrentChangedEventManager.cs
- XmlReaderDelegator.cs
- DataStreamFromComStream.cs
- DBConcurrencyException.cs
- FilterUserControlBase.cs
- XmlSerializerVersionAttribute.cs
- StreamResourceInfo.cs
- SspiWrapper.cs
- UpdateProgress.cs
- SingleSelectRootGridEntry.cs
- ListenerHandler.cs
- PageAdapter.cs
- DefaultBinder.cs
- HijriCalendar.cs
- SelectorAutomationPeer.cs
- XmlSchemaAll.cs
- XmlAnyElementAttributes.cs
- LoadedEvent.cs
- TemplateManager.cs
- LazyLoadBehavior.cs
- ConfigurationStrings.cs
- CodeExpressionStatement.cs
- EncryptedKey.cs
- CodeTypeReferenceCollection.cs
- EntityDataSourceContainerNameConverter.cs
- SafeThemeHandle.cs
- WpfWebRequestHelper.cs