PipelineModuleStepContainer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / 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.
//------------------------------------------------------------------------------ 
// 
//     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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK