The Labs \ Source Viewer \ SSCLI \ System.Runtime.Versioning \ VersioningHelper

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** Purpose: Resource annotation rules.
  18. **
  19. ===========================================================*/
  20. using System;
  21. using System.Diagnostics;
  22. using Microsoft.Win32;
  23. namespace System.Runtime.Versioning
  24. {
  25.     [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
  26.     [Conditional("RESOURCE_ANNOTATION_WORK")]
  27.     public sealed class ResourceConsumptionAttribute : Attribute
  28.     {
  29.         private ResourceScope _consumptionScope;
  30.         private ResourceScope _resourceScope;
  31.        
  32.         public ResourceConsumptionAttribute(ResourceScope resourceScope)
  33.         {
  34.             _resourceScope = resourceScope;
  35.             _consumptionScope = _resourceScope;
  36.         }
  37.        
  38.         public ResourceConsumptionAttribute(ResourceScope resourceScope, ResourceScope consumptionScope)
  39.         {
  40.             _resourceScope = resourceScope;
  41.             _consumptionScope = consumptionScope;
  42.         }
  43.        
  44.         public ResourceScope ResourceScope {
  45.             get { return _resourceScope; }
  46.         }
  47.        
  48.         public ResourceScope ConsumptionScope {
  49.             get { return _consumptionScope; }
  50.         }
  51.     }
  52.    
  53.     [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
  54.     [Conditional("RESOURCE_ANNOTATION_WORK")]
  55.     public sealed class ResourceExposureAttribute : Attribute
  56.     {
  57.         private ResourceScope _resourceExposureLevel;
  58.        
  59.         public ResourceExposureAttribute(ResourceScope exposureLevel)
  60.         {
  61.             _resourceExposureLevel = exposureLevel;
  62.         }
  63.        
  64.         public ResourceScope ResourceExposureLevel {
  65.             get { return _resourceExposureLevel; }
  66.         }
  67.     }
  68.    
  69.    
  70.     // Default visibility is Public, which isn't specified in this enum.
  71.     // Public == the lack of Private or Assembly
  72.     // Does this actually work? Need to investigate that.
  73.     [Flags()]
  74.     public enum ResourceScope
  75.     {
  76.         None = 0,
  77.         // Resource type
  78.         Machine = 1,
  79.         Process = 2,
  80.         AppDomain = 4,
  81.         Library = 8,
  82.         // Visibility
  83.         Private = 16,
  84.         // Private to this one class.
  85.         Assembly = 32
  86.         // Assembly-level, like C#'s "internal"
  87.     }
  88.    
  89.    
  90.     [Flags()]
  91.     internal enum SxSRequirements
  92.     {
  93.         None = 0,
  94.         AppDomainID = 1,
  95.         ProcessID = 2,
  96.         AssemblyName = 4,
  97.         TypeName = 8
  98.     }
  99.    
  100.     public static class VersioningHelper
  101.     {
  102.         // These depend on the exact values given to members of the ResourceScope enum.
  103.         private static ResourceScope ResTypeMask = ResourceScope.Machine | ResourceScope.Process | ResourceScope.AppDomain | ResourceScope.Library;
  104.         private static ResourceScope VisibilityMask = ResourceScope.Private | ResourceScope.Assembly;
  105.        
  106.         public static string MakeVersionSafeName(string name, ResourceScope from, ResourceScope to)
  107.         {
  108.             return MakeVersionSafeName(name, from, to, null);
  109.         }
  110.        
  111.         [ResourceExposure(ResourceScope.None)]
  112.         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
  113.         public static string MakeVersionSafeName(string name, ResourceScope from, ResourceScope to, Type type)
  114.         {
  115.             ResourceScope fromResType = from & ResTypeMask;
  116.             ResourceScope toResType = to & ResTypeMask;
  117.             if (fromResType > toResType)
  118.                 throw new ArgumentException(Environment.GetResourceString("Argument_ResourceScopeWrongDirection", fromResType, toResType), "from");
  119.            
  120.             SxSRequirements requires = GetRequirements(to, from);
  121.            
  122.             if ((requires & (SxSRequirements.AssemblyName | SxSRequirements.TypeName)) != 0 && type == null)
  123.                 throw new ArgumentNullException("type", Environment.GetResourceString("ArgumentNull_TypeRequiredByResourceScope"));
  124.            
  125.             string postfix = "";
  126.             const string separator = "_";
  127.             if ((requires & SxSRequirements.ProcessID) != 0)
  128.                 postfix += separator + Win32Native.GetCurrentProcessId();
  129.             if ((requires & SxSRequirements.AppDomainID) != 0)
  130.                 postfix += separator + AppDomain.CurrentDomain.GetAppDomainId();
  131.             if ((requires & SxSRequirements.TypeName) != 0)
  132.                 postfix += separator + type.Name;
  133.             if ((requires & SxSRequirements.AssemblyName) != 0)
  134.                 postfix += separator + type.Assembly.FullName;
  135.            
  136.             return name + postfix;
  137.         }
  138.        
  139.         private static SxSRequirements GetRequirements(ResourceScope consumeAsScope, ResourceScope calleeScope)
  140.         {
  141.             SxSRequirements requires = SxSRequirements.None;
  142.            
  143.             switch (calleeScope & ResTypeMask) {
  144.                 case ResourceScope.Machine:
  145.                     switch (consumeAsScope & ResTypeMask) {
  146.                         case ResourceScope.Machine:
  147.                             // No work
  148.                             break;
  149.                         case ResourceScope.Process:
  150.                            
  151.                             requires |= SxSRequirements.ProcessID;
  152.                             break;
  153.                         case ResourceScope.AppDomain:
  154.                            
  155.                             requires |= SxSRequirements.AppDomainID | SxSRequirements.ProcessID;
  156.                             break;
  157.                         default:
  158.                            
  159.                             throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", consumeAsScope), "consumeAsScope");
  160.                             break;
  161.                     }
  162.                     break;
  163.                 case ResourceScope.Process:
  164.                    
  165.                     if ((consumeAsScope & ResourceScope.AppDomain) != 0)
  166.                         requires |= SxSRequirements.AppDomainID;
  167.                     break;
  168.                 case ResourceScope.AppDomain:
  169.                    
  170.                     // No work
  171.                     break;
  172.                 default:
  173.                    
  174.                     throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", calleeScope), "calleeScope");
  175.                     break;
  176.             }
  177.            
  178.             switch (calleeScope & VisibilityMask) {
  179.                 case ResourceScope.None:
  180.                     // Public - implied
  181.                     switch (consumeAsScope & VisibilityMask) {
  182.                         case ResourceScope.None:
  183.                             // Public - implied
  184.                             // No work
  185.                             break;
  186.                         case ResourceScope.Assembly:
  187.                            
  188.                             requires |= SxSRequirements.AssemblyName;
  189.                             break;
  190.                         case ResourceScope.Private:
  191.                            
  192.                             requires |= SxSRequirements.TypeName | SxSRequirements.AssemblyName;
  193.                             break;
  194.                         default:
  195.                            
  196.                             throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", consumeAsScope), "consumeAsScope");
  197.                             break;
  198.                     }
  199.                     break;
  200.                 case ResourceScope.Assembly:
  201.                    
  202.                     if ((consumeAsScope & ResourceScope.Private) != 0)
  203.                         requires |= SxSRequirements.TypeName;
  204.                     break;
  205.                 case ResourceScope.Private:
  206.                    
  207.                     // No work
  208.                     break;
  209.                 default:
  210.                    
  211.                     throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", calleeScope), "calleeScope");
  212.                     break;
  213.             }
  214.            
  215.             if (consumeAsScope == calleeScope) {
  216.                 BCLDebug.Assert(requires == SxSRequirements.None, "Computed a strange set of required resource scoping. It's probably wrong.");
  217.             }
  218.            
  219.             return requires;
  220.         }
  221.     }
  222. }

Developer Fusion