The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Channels \ BaseTransportHeadersEnumerator

  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. // File: BaseTransportHeaders.cs
  17. //
  18. // Summary: Base class for special-cased transport headers implementations.
  19. //
  20. //==========================================================================
  21. using System;
  22. using System.Collections;
  23. using System.Globalization;
  24. using System.Net;
  25. namespace System.Runtime.Remoting.Channels
  26. {
  27.    
  28.     [Serializable()]
  29.     internal class BaseTransportHeaders : ITransportHeaders
  30.     {
  31.         // IMPORTANT: If a new wellknown header is added, MapHeaderNameToIndex,
  32.         // GetValueFromHeaderIndex, and SetValueFromHeaderIndex methods must
  33.         // be updated (as well as WellknownHeaderCount)!!!
  34.        
  35.         internal const int WellknownHeaderCount = 4;
  36.        
  37.         private object _connectionId;
  38.         // 0) CommonTransportKeys.ConnectionId
  39.         private object _ipAddress;
  40.         // 1) CommonTransportKeys.IPAddress
  41.         private string _requestUri;
  42.         // 2) CommonTransportKeys.RequestUri
  43.         private string _contentType;
  44.         // 3) "Content-Type"
  45.        
  46.         // transport headers structure is for non well-known headers
  47.         private ITransportHeaders _otherHeaders;
  48.        
  49.        
  50.         public BaseTransportHeaders()
  51.         {
  52.             _otherHeaders = null;
  53.         }
  54.        
  55.        
  56.         public string RequestUri {
  57.             get { return _requestUri; }
  58.             set { _requestUri = value; }
  59.         }
  60.         // RequestUri
  61.        
  62.         public string ContentType {
  63.             get { return _contentType; }
  64.             set { _contentType = value; }
  65.         }
  66.         // ContentType
  67.        
  68.         public object ConnectionId {
  69.             set { _connectionId = value; }
  70.         }
  71.        
  72.         public IPAddress IPAddress {
  73.             set { _ipAddress = value; }
  74.         }
  75.        
  76.        
  77.         //
  78.         // ITransportHeaders implementation
  79.         //
  80.        
  81.         public object this[object key]
  82.         {
  83.             get {
  84.                 string strKey = key as string;
  85.                 if (strKey != null) {
  86.                     int index = MapHeaderNameToIndex(strKey);
  87.                     if (index != -1)
  88.                         return GetValueFromHeaderIndex(index);
  89.                 }
  90.                
  91.                 if (_otherHeaders != null)
  92.                     return _otherHeaders[key];
  93.                
  94.                 return null;
  95.             }
  96.             // get
  97.             set {
  98.                 bool bSet = false;
  99.                
  100.                 string strKey = key as string;
  101.                 if (strKey != null) {
  102.                     int index = MapHeaderNameToIndex(strKey);
  103.                     if (index != -1) {
  104.                         SetValueFromHeaderIndex(index, value);
  105.                         bSet = true;
  106.                     }
  107.                 }
  108.                
  109.                 if (!bSet) {
  110.                     if (_otherHeaders == null)
  111.                         _otherHeaders = new TransportHeaders();
  112.                     _otherHeaders[key] = value;
  113.                 }
  114.             }
  115.         }
  116.         // set
  117.         // Object this[Object key]
  118.        
  119.         public IEnumerator GetEnumerator()
  120.         {
  121.             return new BaseTransportHeadersEnumerator(this);
  122.         }
  123.         // GetEnumerator
  124.        
  125.         internal IEnumerator GetOtherHeadersEnumerator()
  126.         {
  127.             if (_otherHeaders == null)
  128.                 return null;
  129.            
  130.             return _otherHeaders.GetEnumerator();
  131.         }
  132.         // GetOtherHeadersEnumerator
  133.        
  134.        
  135.         internal int MapHeaderNameToIndex(string headerName)
  136.         {
  137.             // 0) CommonTransportKeys.ConnectionId
  138.             // 1) CommonTransportKeys.IPAddress
  139.             // 2) CommonTransportKeys.RequestUri
  140.             // 3) "Content-Type"
  141.            
  142.             if (String.Compare(headerName, CommonTransportKeys.ConnectionId, StringComparison.OrdinalIgnoreCase) == 0)
  143.                 return 0;
  144.             else if (String.Compare(headerName, CommonTransportKeys.IPAddress, StringComparison.OrdinalIgnoreCase) == 0)
  145.                 return 1;
  146.             else if (String.Compare(headerName, CommonTransportKeys.RequestUri, StringComparison.OrdinalIgnoreCase) == 0)
  147.                 return 2;
  148.             else if (String.Compare(headerName, "Content-Type", StringComparison.OrdinalIgnoreCase) == 0)
  149.                 return 3;
  150.            
  151.             return -1;
  152.         }
  153.         // MapHeaderNameToIndex
  154.        
  155.         internal string MapHeaderIndexToName(int index)
  156.         {
  157.             // 0) CommonTransportKeys.ConnectionId
  158.             // 1) CommonTransportKeys.IPAddress
  159.             // 2) CommonTransportKeys.RequestUri
  160.             // 3) "Content-Type"
  161.            
  162.             switch (index) {
  163.                 case 0:
  164.                     return CommonTransportKeys.ConnectionId;
  165.                 case 1:
  166.                     return CommonTransportKeys.IPAddress;
  167.                 case 2:
  168.                     return CommonTransportKeys.RequestUri;
  169.                 case 3:
  170.                     return "Content-Type";
  171.                 default:
  172.                    
  173.                     return null;
  174.             }
  175.            
  176.         }
  177.         // MapHeaderNameToIndex
  178.        
  179.         internal object GetValueFromHeaderIndex(int index)
  180.         {
  181.             // NOTE: If this method returns the null, then that indicates the header has no
  182.             // value (i.e. isn't in the "dictionary"). For the purposes of iteration, this
  183.             // means that the header should be skipped.
  184.            
  185.             // 0) CommonTransportKeys.ConnectionId
  186.             // 1) CommonTransportKeys.IPAddress
  187.             // 2) CommonTransportKeys.RequestUri
  188.             // 3) "Content-Type"
  189.            
  190.             switch (index) {
  191.                 case 0:
  192.                     return _connectionId;
  193.                 case 1:
  194.                     return _ipAddress;
  195.                 case 2:
  196.                     return _requestUri;
  197.                 case 3:
  198.                     return _contentType;
  199.                 default:
  200.                    
  201.                     return null;
  202.             }
  203.            
  204.         }
  205.         // MapHeaderIndexToValue
  206.        
  207.         internal void SetValueFromHeaderIndex(int index, object value)
  208.         {
  209.             // NOTE: If this method returns the null, then that indicates the header has no
  210.             // value (i.e. isn't in the "dictionary"). For the purposes of iteration, this
  211.             // means that the header should be skipped.
  212.            
  213.             // 0) CommonTransportKeys.ConnectionId
  214.             // 1) CommonTransportKeys.IPAddress
  215.             // 2) CommonTransportKeys.RequestUri
  216.             // 3) "Content-Type"
  217.            
  218.             switch (index) {
  219.                 case 0:
  220.                     _connectionId = value;
  221.                     break;
  222.                 case 1:
  223.                     _ipAddress = value;
  224.                     break;
  225.                 case 2:
  226.                     _requestUri = (string)value;
  227.                     break;
  228.                 case 3:
  229.                     _contentType = (string)value;
  230.                     break;
  231.                 default:
  232.                    
  233.                    
  234.                     {
  235.                         InternalRemotingServices.RemotingAssert(false, "someone forgot to update this method");
  236.                         break;
  237.                     }
  238.                     break;
  239.                
  240.             }
  241.             // switch (index)
  242.         }
  243.         // MapHeaderIndexToValue
  244.        
  245.        
  246.     }
  247.     // class BaseTransportHeaders
  248.    
  249.    
  250.     internal class BaseTransportHeadersEnumerator : IEnumerator
  251.     {
  252.         private BaseTransportHeaders _headers;
  253.         private bool _bStarted;
  254.         private int _currentIndex;
  255.         private IEnumerator _otherHeadersEnumerator;
  256.        
  257.         public BaseTransportHeadersEnumerator(BaseTransportHeaders headers)
  258.         {
  259.             _headers = headers;
  260.             Reset();
  261.         }
  262.         // BaseTransportHeadersEnumerator
  263.        
  264.         public bool MoveNext()
  265.         {
  266.             if (_currentIndex != -1) {
  267.                 if (_bStarted)
  268.                     _currentIndex++;
  269.                 else
  270.                     _bStarted = true;
  271.                
  272.                 while (_currentIndex != -1) {
  273.                     if (_currentIndex >= BaseTransportHeaders.WellknownHeaderCount) {
  274.                         _otherHeadersEnumerator = _headers.GetOtherHeadersEnumerator();
  275.                         _currentIndex = -1;
  276.                     }
  277.                     else {
  278.                         if (_headers.GetValueFromHeaderIndex(_currentIndex) != null)
  279.                             return true;
  280.                        
  281.                         _currentIndex++;
  282.                     }
  283.                 }
  284.             }
  285.            
  286.             if (_otherHeadersEnumerator != null) {
  287.                 if (!_otherHeadersEnumerator.MoveNext()) {
  288.                     _otherHeadersEnumerator = null;
  289.                     return false;
  290.                 }
  291.                 else
  292.                     return true;
  293.             }
  294.            
  295.             return false;
  296.         }
  297.         // MoveNext
  298.         public void Reset()
  299.         {
  300.             _bStarted = false;
  301.             _currentIndex = 0;
  302.             _otherHeadersEnumerator = null;
  303.         }
  304.         // Reset
  305.         public object Current {
  306.             get {
  307.                 if (!_bStarted)
  308.                     return null;
  309.                
  310.                 if (_currentIndex != -1) {
  311.                     return new DictionaryEntry(_headers.MapHeaderIndexToName(_currentIndex), _headers.GetValueFromHeaderIndex(_currentIndex));
  312.                 }
  313.                
  314.                 if (_otherHeadersEnumerator != null) {
  315.                     return _otherHeadersEnumerator.Current;
  316.                 }
  317.                
  318.                 return null;
  319.             }
  320.         }
  321.         // Current
  322.     }
  323.     // class BaseTransportHeadersEnumerator
  324.    
  325.    
  326.    
  327. }
  328. // namespace System.Runtime.Remoting.Channels

Developer Fusion