private static ICollection PipelineAttributeFilter(int pipelineType, ICollection members, Attribute[] filter, object instance, IDictionary cache)
{
Debug.Assert(pipelineType != PIPELINE_ATTRIBUTES, "PipelineAttributeFilter is not supported for attributes");
IList list = members as ArrayList;
if (filter == null || filter.Length == 0)
{
return members;
}
// Now, check our cache. The cache state is only valid
// if the data coming into us is read-only. If it is read-write,
// that means something higher in the pipeline has already changed
// it so we must recompute anyway.
//
if (cache != null && (list == null || list.IsReadOnly))
{
AttributeFilterCacheItem filterCache = cache[s_pipelineAttributeFilterKeys[pipelineType]] as AttributeFilterCacheItem;
if (filterCache != null && filterCache.IsValid(filter))
{
return filterCache.FilteredMembers;
}
}
// Our cache did not contain the correct state, so generate it.
//
if (list == null || list.IsReadOnly)
{
list = new ArrayList(members);
}
ArrayList filterResult = FilterMembers(list, filter);
if (filterResult != null) list = filterResult;
// And, if we have a cache, store the updated state into it for future reference.
//
if (cache != null)
{
ICollection cacheValue;
switch (pipelineType)
{
case PIPELINE_PROPERTIES:
PropertyDescriptor[] propArray = new PropertyDescriptor[list.Count];
list.CopyTo(propArray, 0);
cacheValue = new PropertyDescriptorCollection(propArray, true);
break;
case PIPELINE_EVENTS:
EventDescriptor[] eventArray = new EventDescriptor[list.Count];
list.CopyTo(eventArray, 0);
cacheValue = new EventDescriptorCollection(eventArray, true);
break;
default:
Debug.Fail("unknown pipeline type");
cacheValue = null;
break;
}
AttributeFilterCacheItem filterCache = new AttributeFilterCacheItem(filter, cacheValue);
cache[s_pipelineAttributeFilterKeys[pipelineType]] = filterCache;
}
return list;
}