The Labs \ Source Viewer \ SSCLI \ System.Runtime.Serialization \ SerializationInfo

  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. ** Class:  SerializationInfo
  18. **
  19. **
  20. ** Purpose: The structure for holding all of the data needed
  21. **          for object serialization and deserialization.
  22. **
  23. **
  24. ===========================================================*/
  25. namespace System.Runtime.Serialization
  26. {
  27.    
  28.     using System;
  29.     using System.Reflection;
  30.     using System.Runtime.Remoting;
  31.     using System.Runtime.Remoting.Proxies;
  32.     using System.Globalization;
  33.    
  34.     [System.Runtime.InteropServices.ComVisible(true)]
  35.     public sealed class SerializationInfo
  36.     {
  37.         private const int defaultSize = 4;
  38.        
  39.         internal string[] m_members;
  40.         internal object[] m_data;
  41.         internal Type[] m_types;
  42.         internal string m_fullTypeName;
  43.         internal int m_currMember;
  44.         internal string m_assemName;
  45.         internal IFormatterConverter m_converter;
  46.        
  47.         [CLSCompliant(false)]
  48.         public SerializationInfo(Type type, IFormatterConverter converter)
  49.         {
  50.             if (null == type) {
  51.                 throw new ArgumentNullException("type");
  52.             }
  53.            
  54.             if (converter == null) {
  55.                 throw new ArgumentNullException("converter");
  56.             }
  57.            
  58.            
  59.             m_fullTypeName = type.FullName;
  60.             m_assemName = type.Module.Assembly.FullName;
  61.             BCLDebug.Assert(m_fullTypeName != null, "[SerializationInfo.ctor]m_fullTypeName!=null");
  62.             BCLDebug.Assert(m_assemName != null, "[SerializationInfo.ctor]m_assemName!=null");
  63.            
  64.             m_members = new string[defaultSize];
  65.             m_data = new object[defaultSize];
  66.             m_types = new Type[defaultSize];
  67.            
  68.             m_converter = converter;
  69.            
  70.             m_currMember = 0;
  71.            
  72.         }
  73.        
  74.         public string FullTypeName {
  75.             get { return m_fullTypeName; }
  76.             set {
  77.                 if (null == value) {
  78.                     throw new ArgumentNullException("value");
  79.                 }
  80.                 m_fullTypeName = value;
  81.             }
  82.         }
  83.        
  84.         public string AssemblyName {
  85.             get { return m_assemName; }
  86.            
  87.             set {
  88.                 if (null == value) {
  89.                     throw new ArgumentNullException("value");
  90.                 }
  91.                 m_assemName = value;
  92.             }
  93.         }
  94.        
  95.         public void SetType(Type type)
  96.         {
  97.             if (type == null) {
  98.                 throw new ArgumentNullException("type");
  99.             }
  100.             m_fullTypeName = type.FullName;
  101.             m_assemName = type.Module.Assembly.FullName;
  102.             BCLDebug.Assert(m_fullTypeName != null, "[SerializationInfo.ctor]m_fullTypeName!=null");
  103.             BCLDebug.Assert(m_assemName != null, "[SerializationInfo.ctor]m_assemName!=null");
  104.         }
  105.        
  106.        
  107.         public int MemberCount {
  108.             get { return m_currMember; }
  109.         }
  110.        
  111.         public SerializationInfoEnumerator GetEnumerator()
  112.         {
  113.             return new SerializationInfoEnumerator(m_members, m_data, m_types, m_currMember);
  114.         }
  115.        
  116.        
  117.         private void ExpandArrays()
  118.         {
  119.             int newSize;
  120.             BCLDebug.Assert(m_members.Length == m_currMember, "[SerializationInfo.ExpandArrays]m_members.Length == m_currMember");
  121.            
  122.             newSize = (m_currMember * 2);
  123.            
  124.             //
  125.             // In the pathological case, we may wrap
  126.             //
  127.             if (newSize < m_currMember) {
  128.                 if (Int32.MaxValue > m_currMember) {
  129.                     newSize = Int32.MaxValue;
  130.                 }
  131.             }
  132.            
  133.             //
  134.             // Allocate more space and copy the data
  135.             //
  136.             string[] newMembers = new string[newSize];
  137.             object[] newData = new object[newSize];
  138.             Type[] newTypes = new Type[newSize];
  139.            
  140.             Array.Copy(m_members, newMembers, m_currMember);
  141.             Array.Copy(m_data, newData, m_currMember);
  142.             Array.Copy(m_types, newTypes, m_currMember);
  143.            
  144.             //
  145.             // Assign the new arrys back to the member vars.
  146.             //
  147.             m_members = newMembers;
  148.             m_data = newData;
  149.             m_types = newTypes;
  150.         }
  151.        
  152.         public void AddValue(string name, object value, Type type)
  153.         {
  154.             if (null == name) {
  155.                 throw new ArgumentNullException("name");
  156.             }
  157.            
  158.             if (null == type) {
  159.                 throw new ArgumentNullException("type");
  160.             }
  161.            
  162.             //
  163.             // Walk until we find a member by the same name or until
  164.             // we reach the end. If we find a member by the same name,
  165.             // throw.
  166.             for (int i = 0; i < m_currMember; i++) {
  167.                 if (m_members[i].Equals(name)) {
  168.                     BCLDebug.Trace("SER", "[SerializationInfo.AddValue]Tried to add ", name, " twice to the SI.");
  169.                    
  170.                     throw new SerializationException(Environment.GetResourceString("Serialization_SameNameTwice"));
  171.                 }
  172.             }
  173.            
  174.             AddValue(name, value, type, m_currMember);
  175.            
  176.         }
  177.        
  178.         public void AddValue(string name, object value)
  179.         {
  180.             if (null == value) {
  181.                 AddValue(name, value, typeof(object));
  182.             }
  183.             else {
  184.                 AddValue(name, value, value.GetType());
  185.             }
  186.         }
  187.        
  188.         public void AddValue(string name, bool value)
  189.         {
  190.             AddValue(name, (object)value, typeof(bool));
  191.         }
  192.        
  193.         public void AddValue(string name, char value)
  194.         {
  195.             AddValue(name, (object)value, typeof(char));
  196.         }
  197.        
  198.        
  199.         [CLSCompliant(false)]
  200.         public void AddValue(string name, sbyte value)
  201.         {
  202.             AddValue(name, (object)value, typeof(sbyte));
  203.         }
  204.        
  205.         public void AddValue(string name, byte value)
  206.         {
  207.             AddValue(name, (object)value, typeof(byte));
  208.         }
  209.        
  210.         public void AddValue(string name, short value)
  211.         {
  212.             AddValue(name, (object)value, typeof(short));
  213.         }
  214.        
  215.         [CLSCompliant(false)]
  216.         public void AddValue(string name, ushort value)
  217.         {
  218.             AddValue(name, (object)value, typeof(ushort));
  219.         }
  220.        
  221.         public void AddValue(string name, int value)
  222.         {
  223.             AddValue(name, (object)value, typeof(int));
  224.         }
  225.        
  226.         [CLSCompliant(false)]
  227.         public void AddValue(string name, uint value)
  228.         {
  229.             AddValue(name, (object)value, typeof(uint));
  230.         }
  231.        
  232.         public void AddValue(string name, long value)
  233.         {
  234.             AddValue(name, (object)value, typeof(long));
  235.         }
  236.        
  237.         [CLSCompliant(false)]
  238.         public void AddValue(string name, ulong value)
  239.         {
  240.             AddValue(name, (object)value, typeof(ulong));
  241.         }
  242.        
  243.         public void AddValue(string name, float value)
  244.         {
  245.             AddValue(name, (object)value, typeof(float));
  246.         }
  247.        
  248.         public void AddValue(string name, double value)
  249.         {
  250.             AddValue(name, (object)value, typeof(double));
  251.         }
  252.        
  253.         public void AddValue(string name, decimal value)
  254.         {
  255.             AddValue(name, (object)value, typeof(decimal));
  256.         }
  257.        
  258.         public void AddValue(string name, DateTime value)
  259.         {
  260.             AddValue(name, (object)value, typeof(DateTime));
  261.         }
  262.        
  263.         internal void AddValue(string name, object value, Type type, int index)
  264.         {
  265.             //
  266.             // If we need to expand the arrays, do so.
  267.             //
  268.             if (index >= m_members.Length) {
  269.                 ExpandArrays();
  270.             }
  271.            
  272.             //
  273.             // Add the data and then advance the counter.
  274.             //
  275.             m_members[index] = name;
  276.             m_data[index] = value;
  277.             m_types[index] = type;
  278.             m_currMember++;
  279.         }
  280.        
  281. /*=================================UpdateValue==================================
  282.         **Action: Finds the value if it exists in the current data.  If it does, we replace
  283.         **        the values, if not, we append it to the end.  This is useful to the
  284.         **        ObjectManager when it's performing fixups, but shouldn't be used by
  285.         **        clients.  Exposing out this functionality would allow children to overwrite
  286.         **        their parent's values.
  287.         **Returns: void
  288.         **Arguments: name  -- the name of the data to be updated.
  289.         **          value -- the new value.
  290.         **          type  -- the type of the data being added.
  291.         **Exceptions: None.  All error checking is done with asserts.
  292.         ==============================================================================*/       
  293.         internal void UpdateValue(string name, object value, Type type)
  294.         {
  295.             BCLDebug.Assert(null != name, "[SerializationInfo.UpdateValue]name!=null");
  296.             BCLDebug.Assert(null != value, "[SerializationInfo.UpdateValue]value!=null");
  297.             BCLDebug.Assert(null != type, "[SerializationInfo.UpdateValue]type!=null");
  298.            
  299.             int index = FindElement(name);
  300.             if (index < 0) {
  301.                 AddValue(name, value, type, m_currMember);
  302.             }
  303.             else {
  304.                 m_members[index] = name;
  305.                 m_data[index] = value;
  306.                 m_types[index] = type;
  307.             }
  308.            
  309.         }
  310.        
  311.         private int FindElement(string name)
  312.         {
  313.             if (null == name) {
  314.                 throw new ArgumentNullException("name");
  315.             }
  316.             BCLDebug.Trace("SER", "[SerializationInfo.FindElement]Looking for ", name, " CurrMember is: ", m_currMember);
  317.             for (int i = 0; i < m_currMember; i++) {
  318.                 BCLDebug.Assert(m_members[i] != null, "[SerializationInfo.FindElement]Null Member in String array.");
  319.                 if (m_members[i].Equals(name)) {
  320.                     return i;
  321.                 }
  322.             }
  323.             return -1;
  324.         }
  325.        
  326. /*==================================GetElement==================================
  327.         **Action: Use FindElement to get the location of a particular member and then return
  328.         **        the value of the element at that location.  The type of the member is
  329.         **        returned in the foundType field.
  330.         **Returns: The value of the element at the position associated with name.
  331.         **Arguments: name -- the name of the element to find.
  332.         **          foundType -- the type of the element associated with the given name.
  333.         **Exceptions: None.  FindElement does null checking and throws for elements not
  334.         **            found.
  335.         ==============================================================================*/       
  336.         private object GetElement(string name, out Type foundType)
  337.         {
  338.             int index = FindElement(name);
  339.             if (index == -1) {
  340.                 throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_NotFound"), name));
  341.             }
  342.            
  343.             BCLDebug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
  344.             BCLDebug.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
  345.            
  346.             foundType = m_types[index];
  347.             BCLDebug.Assert(foundType != null, "[SerializationInfo.GetElement]foundType!=null");
  348.             return m_data[index];
  349.         }
  350.        
  351.         [System.Runtime.InteropServices.ComVisible(true)]
  352.         private object GetElementNoThrow(string name, out Type foundType)
  353.         {
  354.             int index = FindElement(name);
  355.             if (index == -1) {
  356.                 foundType = null;
  357.                 return null;
  358.             }
  359.            
  360.             BCLDebug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
  361.             BCLDebug.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
  362.            
  363.             foundType = m_types[index];
  364.             BCLDebug.Assert(foundType != null, "[SerializationInfo.GetElement]foundType!=null");
  365.             return m_data[index];
  366.         }
  367.        
  368.         //
  369.         // The user should call one of these getters to get the data back in the
  370.         // form requested.
  371.         //
  372.        
  373.         public object GetValue(string name, Type type)
  374.         {
  375.             Type foundType;
  376.             object value;
  377.            
  378.             if (null == type) {
  379.                 throw new ArgumentNullException("type");
  380.             }
  381.            
  382.             value = GetElement(name, out foundType);
  383.             if (RemotingServices.IsTransparentProxy(value)) {
  384.                 RealProxy proxy = RemotingServices.GetRealProxy(value);
  385.                 if (RemotingServices.ProxyCheckCast(proxy, type))
  386.                     return value;
  387.             }
  388.             else if (foundType == type || type.IsAssignableFrom(foundType) || value == null) {
  389.                 return value;
  390.             }
  391.            
  392.             BCLDebug.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
  393.            
  394.             return m_converter.Convert(value, type);
  395.         }
  396.        
  397.         [System.Runtime.InteropServices.ComVisible(true)]
  398.         internal object GetValueNoThrow(string name, Type type)
  399.         {
  400.             Type foundType;
  401.             object value;
  402.            
  403.             BCLDebug.Assert(null != type, "[SerializationInfo.GetValue]type ==null");
  404.            
  405.             value = GetElementNoThrow(name, out foundType);
  406.             if (value == null)
  407.                 return null;
  408.             if (RemotingServices.IsTransparentProxy(value)) {
  409.                 RealProxy proxy = RemotingServices.GetRealProxy(value);
  410.                 if (RemotingServices.ProxyCheckCast(proxy, type))
  411.                     return value;
  412.             }
  413.             else if (foundType == type || type.IsAssignableFrom(foundType) || value == null) {
  414.                 return value;
  415.             }
  416.            
  417.             BCLDebug.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
  418.            
  419.             return m_converter.Convert(value, type);
  420.         }
  421.        
  422.         public bool GetBoolean(string name)
  423.         {
  424.             Type foundType;
  425.             object value;
  426.            
  427.             value = GetElement(name, out foundType);
  428.             if (foundType == typeof(bool)) {
  429.                 return (bool)value;
  430.             }
  431.             return m_converter.ToBoolean(value);
  432.         }
  433.        
  434.         public char GetChar(string name)
  435.         {
  436.             Type foundType;
  437.             object value;
  438.            
  439.             value = GetElement(name, out foundType);
  440.             if (foundType == typeof(char)) {
  441.                 return (char)value;
  442.             }
  443.             return m_converter.ToChar(value);
  444.         }
  445.        
  446.         [CLSCompliant(false)]
  447.         public sbyte GetSByte(string name)
  448.         {
  449.             Type foundType;
  450.             object value;
  451.            
  452.             value = GetElement(name, out foundType);
  453.             if (foundType == typeof(sbyte)) {
  454.                 return (sbyte)value;
  455.             }
  456.             return m_converter.ToSByte(value);
  457.         }
  458.        
  459.         public byte GetByte(string name)
  460.         {
  461.             Type foundType;
  462.             object value;
  463.            
  464.             value = GetElement(name, out foundType);
  465.             if (foundType == typeof(byte)) {
  466.                 return (byte)value;
  467.             }
  468.             return m_converter.ToByte(value);
  469.         }
  470.        
  471.         public short GetInt16(string name)
  472.         {
  473.             Type foundType;
  474.             object value;
  475.            
  476.             value = GetElement(name, out foundType);
  477.             if (foundType == typeof(short)) {
  478.                 return (short)value;
  479.             }
  480.             return m_converter.ToInt16(value);
  481.         }
  482.        
  483.         [CLSCompliant(false)]
  484.         public ushort GetUInt16(string name)
  485.         {
  486.             Type foundType;
  487.             object value;
  488.            
  489.             value = GetElement(name, out foundType);
  490.             if (foundType == typeof(ushort)) {
  491.                 return (ushort)value;
  492.             }
  493.             return m_converter.ToUInt16(value);
  494.         }
  495.        
  496.         public int GetInt32(string name)
  497.         {
  498.             Type foundType;
  499.             object value;
  500.            
  501.             value = GetElement(name, out foundType);
  502.             if (foundType == typeof(int)) {
  503.                 return (int)value;
  504.             }
  505.             return m_converter.ToInt32(value);
  506.         }
  507.        
  508.         [CLSCompliant(false)]
  509.         public uint GetUInt32(string name)
  510.         {
  511.             Type foundType;
  512.             object value;
  513.            
  514.             value = GetElement(name, out foundType);
  515.             if (foundType == typeof(uint)) {
  516.                 return (uint)value;
  517.             }
  518.             return m_converter.ToUInt32(value);
  519.         }
  520.        
  521.         public long GetInt64(string name)
  522.         {
  523.             Type foundType;
  524.             object value;
  525.            
  526.             value = GetElement(name, out foundType);
  527.             if (foundType == typeof(long)) {
  528.                 return (long)value;
  529.             }
  530.             return m_converter.ToInt64(value);
  531.         }
  532.        
  533.         [CLSCompliant(false)]
  534.         public ulong GetUInt64(string name)
  535.         {
  536.             Type foundType;
  537.             object value;
  538.            
  539.             value = GetElement(name, out foundType);
  540.             if (foundType == typeof(ulong)) {
  541.                 return (ulong)value;
  542.             }
  543.             return m_converter.ToUInt64(value);
  544.         }
  545.        
  546.         public float GetSingle(string name)
  547.         {
  548.             Type foundType;
  549.             object value;
  550.            
  551.             value = GetElement(name, out foundType);
  552.             if (foundType == typeof(float)) {
  553.                 return (float)value;
  554.             }
  555.             return m_converter.ToSingle(value);
  556.         }
  557.        
  558.        
  559.         public double GetDouble(string name)
  560.         {
  561.             Type foundType;
  562.             object value;
  563.            
  564.             value = GetElement(name, out foundType);
  565.             if (foundType == typeof(double)) {
  566.                 return (double)value;
  567.             }
  568.             return m_converter.ToDouble(value);
  569.         }
  570.        
  571.         public decimal GetDecimal(string name)
  572.         {
  573.             Type foundType;
  574.             object value;
  575.            
  576.             value = GetElement(name, out foundType);
  577.             if (foundType == typeof(decimal)) {
  578.                 return (decimal)value;
  579.             }
  580.             return m_converter.ToDecimal(value);
  581.         }
  582.        
  583.         public DateTime GetDateTime(string name)
  584.         {
  585.             Type foundType;
  586.             object value;
  587.            
  588.             value = GetElement(name, out foundType);
  589.             if (foundType == typeof(DateTime)) {
  590.                 return (DateTime)value;
  591.             }
  592.             return m_converter.ToDateTime(value);
  593.         }
  594.        
  595.         public string GetString(string name)
  596.         {
  597.             Type foundType;
  598.             object value;
  599.            
  600.             value = GetElement(name, out foundType);
  601.             if (foundType == typeof(string) || value == null) {
  602.                 return (string)value;
  603.             }
  604.             return m_converter.ToString(value);
  605.         }
  606.        
  607.         internal string[] MemberNames {
  608.             get { return m_members; }
  609.         }
  610.        
  611.        
  612.         internal object[] MemberValues {
  613.             get { return m_data; }
  614.         }
  615.        
  616.     }
  617. }

Developer Fusion