Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / PipelineModuleStepContainer.cs / 1305376 / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CodeThrowExceptionStatement.cs
- HttpProxyCredentialType.cs
- DataBindingHandlerAttribute.cs
- RangeContentEnumerator.cs
- lengthconverter.cs
- FtpRequestCacheValidator.cs
- DodSequenceMerge.cs
- HttpBrowserCapabilitiesWrapper.cs
- ProgressBar.cs
- BinarySerializer.cs
- CommittableTransaction.cs
- RichTextBoxConstants.cs
- DateTimeOffsetStorage.cs
- PersonalizationState.cs
- DesignTimeVisibleAttribute.cs
- TagPrefixInfo.cs
- Mutex.cs
- SubstitutionList.cs
- ConnectionManagementElement.cs
- DriveNotFoundException.cs
- EditorZoneBase.cs
- Ppl.cs
- HandlerBase.cs
- followingquery.cs
- EntityDataSourceColumn.cs
- RSAOAEPKeyExchangeDeformatter.cs
- ParseElement.cs
- ArithmeticException.cs
- KeySplineConverter.cs
- XmlTextWriter.cs
- MatrixTransform3D.cs
- SimpleParser.cs
- DataGridViewCellStyleConverter.cs
- TableLayoutPanelCellPosition.cs
- GlyphRunDrawing.cs
- RowUpdatedEventArgs.cs
- ASCIIEncoding.cs
- TextBoxRenderer.cs
- WebBrowserDesigner.cs
- AggregatePushdown.cs
- SymbolTable.cs
- HtmlTable.cs
- InvalidFilterCriteriaException.cs
- MsdtcWrapper.cs
- ExtentCqlBlock.cs
- TypeConverter.cs
- WindowsTitleBar.cs
- XmlReflectionMember.cs
- AuthenticationException.cs
- _TimerThread.cs
- AbstractSvcMapFileLoader.cs
- PasswordRecovery.cs
- MimeBasePart.cs
- ScriptDescriptor.cs
- Header.cs
- InstanceNormalEvent.cs
- UserControl.cs
- TextSelectionHelper.cs
- CqlParserHelpers.cs
- SystemWebCachingSectionGroup.cs
- TraceContextRecord.cs
- WebException.cs
- BuildProvider.cs
- ToolStripCustomTypeDescriptor.cs
- LayoutEditorPart.cs
- ChannelTracker.cs
- TaskHelper.cs
- ListControl.cs
- _CommandStream.cs
- CursorInteropHelper.cs
- SettingsPropertyNotFoundException.cs
- ForceCopyBuildProvider.cs
- PageStatePersister.cs
- StatusStrip.cs
- ElementMarkupObject.cs
- SqlDependencyUtils.cs
- HwndHostAutomationPeer.cs
- AffineTransform3D.cs
- CachedBitmap.cs
- SmiEventSink_Default.cs
- HttpValueCollection.cs
- StrongTypingException.cs
- XmlSignificantWhitespace.cs
- ADConnectionHelper.cs
- ControlCachePolicy.cs
- XmlSchemaSimpleContentExtension.cs
- NonVisualControlAttribute.cs
- AdPostCacheSubstitution.cs
- QilStrConcatenator.cs
- DataGridPageChangedEventArgs.cs
- TransformProviderWrapper.cs
- CheckBoxAutomationPeer.cs
- WindowsBrush.cs
- HitTestFilterBehavior.cs
- HttpCapabilitiesBase.cs
- ContainerUtilities.cs
- XmlSchema.cs
- MulticastNotSupportedException.cs
- RequestCacheEntry.cs
- DoubleMinMaxAggregationOperator.cs