Ejemplo n.º 1
0
        // does some consisitency check between the CA list and every CA attribute usage and after
        // discarding unwanted CA return an array of them
        static private Object[] CheckConsistencyAndCreateArray(CustomAttribute caItem, Type caType)
        {
            // we got the max number of attributes, we may have to trim this list but let's get a count for now
            if (caItem == null)
            {
                return((caType == null || caType.IsValueType) ? s_gObjectEmptyArray : (Object[])Array.CreateInstance(caType, 0));
            }

            int             caCount      = 0;
            int             hasInherited = (caItem == null) ? 0 : caItem.m_inheritLevel;
            CustomAttribute caNext       = caItem;
            CustomAttribute caPrev       = null;

            // walk and revert the list
            while (caNext != null)
            {
                caCount++;
                CustomAttribute caTemp = caNext.m_next;
                caNext.m_next = caPrev;
                caPrev        = caNext;
                caNext        = caTemp;
            }
            caItem = caPrev;

            // now we have a list of custom attribute of some type. That list may contain subtype of the specific
            // type, so for every other type we have to go and check whether multiple and inherited are respected
            if (caCount > 0 && hasInherited > 0)
            {
                // keep track of the CA types so we can make inspection reasonable fast
                Hashtable htCAData = new Hashtable(11);

                // loop through the list of attributes checking for consistency, once an attribute
                // has been inspected is never going to be looked at again, and neither an attribute
                // of the same type.
                // This loop and the inspectedCATypes array should make that happen
                caNext = caItem;
                CustomAttribute caLast = null;
                while (caNext != null)
                {
                    AttributeUsageAttribute usage = null;
                    int caTypeLevelFound          = 0;

                    // get current attribute type
                    Type t = caNext.GetAttributeType();

                    // look if the type has already been seen
                    CAData caData = (CAData)htCAData[t];
                    if (caData != null)
                    {
                        usage            = caData.usage;
                        caTypeLevelFound = caData.level;
                    }

                    if (usage == null)
                    {
                        // no type found, load the attribute usage
                        // do not save the attribute usage yet because the next block may discard
                        // the attribute which implies we pretend we never saw. That is kind of
                        // bad because we may end up reloading it again if another type comes into the picture
                        // but we prefer the perf hit to more code complication for a case that seem to
                        // be submarginal
                        usage = CustomAttribute.GetAttributeUsage(t);
                    }

                    // if this is an inherited attribute and the attribute usage does not allow that, OR
                    // if the attribute was seen already on a different inheritance level and multiple is not allowed
                    // THEN discard
                    if ((caNext.m_inheritLevel > 0 && !usage.Inherited) ||
                        (caData != null && caTypeLevelFound < caNext.m_inheritLevel && !usage.AllowMultiple))
                    {
                        if (caLast == null)
                        {
                            caItem = caNext.m_next;
                        }
                        else
                        {
                            caLast.m_next = caNext.m_next;
                        }
                        caNext = caNext.m_next;
                        caCount--;
                        continue;
                    }

                    if (caData == null)
                    {
                        // the attribute was never seen so far so we should add it to the table and keep going
                        htCAData[t] = new CAData(t, usage, caNext.m_inheritLevel);
                    }

                    caLast = caNext;
                    caNext = caNext.m_next;
                }
            }

            // time to return the array
            if (caCount > 0)
            {
                if (caType == null || caType.IsValueType)
                {
                    caType = s_ObjectType;
                }
                Object[] cas = (Object[])Array.CreateInstance(caType, caCount);
                caNext = caItem;
                for (int i = 0; i < caCount; i++)
                {
                    cas[i] = caNext.GetObject();
                    caNext = caNext.m_next;
                }
                return(cas);
            }
            else
            {
                return((caType == null || caType.IsValueType) ? s_gObjectEmptyArray : (Object[])Array.CreateInstance(caType, 0));
            }
        }
Ejemplo n.º 2
0
        // does some consisitency check between the CA list and every CA attribute usage and after
        // discarding unwanted CA return an array of them
        static private Object[] CheckConsistencyAndCreateArray(CustomAttribute caItem, Type caType) {
            // we got the max number of attributes, we may have to trim this list but let's get a count for now
            if (caItem == null) 
                return (caType == null || caType.IsValueType) ? s_gObjectEmptyArray : (Object[])Array.CreateInstance(caType, 0);
            
            int caCount = 0;
            int hasInherited = (caItem == null) ? 0 : caItem.m_inheritLevel;
            CustomAttribute caNext = caItem;
            CustomAttribute caPrev = null;
            // walk and revert the list
            while (caNext != null) {
                caCount++;
                CustomAttribute caTemp = caNext.m_next;
                caNext.m_next = caPrev;
                caPrev = caNext;
                caNext = caTemp;
            }
            caItem = caPrev;
            
            // now we have a list of custom attribute of some type. That list may contain subtype of the specific
            // type, so for every other type we have to go and check whether multiple and inherited are respected
            if (caCount > 0 && hasInherited > 0) {

                // keep track of the CA types so we can make inspection reasonable fast
                Hashtable htCAData = new Hashtable(11);

                // loop through the list of attributes checking for consistency, once an attribute
                // has been inspected is never going to be looked at again, and neither an attribute 
                // of the same type. 
                // This loop and the inspectedCATypes array should make that happen
                caNext = caItem;
                CustomAttribute caLast = null;
                while (caNext != null) {
                    AttributeUsageAttribute usage = null;
                    int caTypeLevelFound = 0;
                    
                    // get current attribute type
                    Type t = caNext.GetAttributeType();
                    
                    // look if the type has already been seen
                    CAData caData = (CAData)htCAData[t];
                    if (caData != null) {
                        usage = caData.usage;
                        caTypeLevelFound = caData.level;
                    }
                    
                    if (usage == null) 
                        // no type found, load the attribute usage 
                        // do not save the attribute usage yet because the next block may discard 
                        // the attribute which implies we pretend we never saw. That is kind of
                        // bad because we may end up reloading it again if another type comes into the picture 
                        // but we prefer the perf hit to more code complication for a case that seem to
                        // be submarginal
                        usage = CustomAttribute.GetAttributeUsage(t);

                    // if this is an inherited attribute and the attribute usage does not allow that, OR
                    // if the attribute was seen already on a different inheritance level and multiple is not allowed
                    // THEN discard
                    if ((caNext.m_inheritLevel > 0 && !usage.Inherited) || 
                            (caData != null && caTypeLevelFound < caNext.m_inheritLevel && !usage.AllowMultiple)) {
                        if (caLast == null) 
                            caItem = caNext.m_next;
                        else 
                            caLast.m_next = caNext.m_next;
                        caNext = caNext.m_next;
                        caCount--;
                        continue;
                    }

                    if (caData == null) 
                        // the attribute was never seen so far so we should add it to the table and keep going
                        htCAData[t] = new CAData(t, usage, caNext.m_inheritLevel);

                    caLast = caNext;
                    caNext = caNext.m_next;
                }
            }

            // time to return the array
            if (caCount > 0) {
                if (caType == null || caType.IsValueType) 
                    caType = s_ObjectType;
                Object[] cas = (Object[])Array.CreateInstance(caType, caCount);
                caNext = caItem;
                for (int i = 0; i < caCount; i++) {
                    cas[i] = caNext.GetObject();
                    caNext = caNext.m_next;
                }
                return cas;
            }
            else
                return (caType == null || caType.IsValueType) ? s_gObjectEmptyArray : (Object[])Array.CreateInstance(caType, 0);
        }