The Labs \ Source Viewer \ SSCLI \ System.Runtime.Serialization.Formatters.Binary \ ObjectMapInfo

  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: BinaryWriter
  18. **
  19. **
  20. ** Purpose: Writes primitive values to a stream
  21. **
  22. **
  23. ===========================================================*/
  24. namespace System.Runtime.Serialization.Formatters.Binary
  25. {
  26.    
  27.     using System;
  28.     using System.Collections;
  29.     using System.IO;
  30.     using System.Reflection;
  31.     using System.Text;
  32.     using System.Globalization;
  33.     using System.Runtime.Serialization.Formatters;
  34.     using System.Configuration.Assemblies;
  35.     using System.Threading;
  36.     using System.Runtime.Remoting;
  37.     using System.Runtime.Serialization;
  38.    
  39.     internal sealed class __BinaryWriter
  40.     {
  41.         internal Stream sout;
  42.         internal FormatterTypeStyle formatterTypeStyle;
  43.         internal Hashtable objectMapTable;
  44.         internal ObjectWriter objectWriter = null;
  45.         internal BinaryWriter dataWriter = null;
  46.        
  47.         internal int m_nestedObjectCount;
  48.         private int nullCount = 0;
  49.         //Count of consecutive array nulls
  50.         // Constructor
  51.         internal __BinaryWriter(Stream sout, ObjectWriter objectWriter, FormatterTypeStyle formatterTypeStyle)
  52.         {
  53.             SerTrace.Log(this, "BinaryWriter ");
  54.             this.sout = sout;
  55.             this.formatterTypeStyle = formatterTypeStyle;
  56.             this.objectWriter = objectWriter;
  57.             m_nestedObjectCount = 0;
  58.             dataWriter = new BinaryWriter(sout, Encoding.UTF8);
  59.         }
  60.        
  61.         internal void WriteBegin()
  62.         {
  63.             BCLDebug.Trace("BINARY", "\n%%%%%BinaryWriterBegin%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
  64.         }
  65.        
  66.         internal void WriteEnd()
  67.         {
  68.             BCLDebug.Trace("BINARY", "\n%%%%%BinaryWriterEnd%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
  69.             dataWriter.Flush();
  70.         }
  71.        
  72.         // Methods to write a value onto the stream
  73.         internal void WriteBoolean(bool value)
  74.         {
  75.             dataWriter.Write(value);
  76.         }
  77.        
  78.         internal void WriteByte(byte value)
  79.         {
  80.             dataWriter.Write(value);
  81.         }
  82.        
  83.         private void WriteBytes(byte[] value)
  84.         {
  85.             dataWriter.Write(value);
  86.         }
  87.        
  88.         private void WriteBytes(byte[] byteA, int offset, int size)
  89.         {
  90.             dataWriter.Write(byteA, offset, size);
  91.         }
  92.        
  93.         internal void WriteChar(char value)
  94.         {
  95.             dataWriter.Write(value);
  96.         }
  97.        
  98.         internal void WriteChars(char[] value)
  99.         {
  100.             dataWriter.Write(value);
  101.         }
  102.        
  103.        
  104.         internal void WriteDecimal(decimal value)
  105.         {
  106.             WriteString(value.ToString(CultureInfo.InvariantCulture));
  107.         }
  108.        
  109.         internal void WriteSingle(float value)
  110.         {
  111.             dataWriter.Write(value);
  112.         }
  113.        
  114.         internal void WriteDouble(double value)
  115.         {
  116.             dataWriter.Write(value);
  117.         }
  118.        
  119.         internal void WriteInt16(Int16 value)
  120.         {
  121.             dataWriter.Write(value);
  122.         }
  123.        
  124.         internal void WriteInt32(Int32 value)
  125.         {
  126.             dataWriter.Write(value);
  127.         }
  128.        
  129.         internal void WriteInt64(Int64 value)
  130.         {
  131.             dataWriter.Write(value);
  132.         }
  133.        
  134.         internal void WriteSByte(sbyte value)
  135.         {
  136.             WriteByte((byte)value);
  137.         }
  138.        
  139.         internal void WriteString(string value)
  140.         {
  141.             dataWriter.Write(value);
  142.         }
  143.        
  144.         internal void WriteTimeSpan(TimeSpan value)
  145.         {
  146.             WriteInt64(value.Ticks);
  147.         }
  148.        
  149.         internal void WriteDateTime(DateTime value)
  150.         {
  151.             WriteInt64(value.ToBinaryRaw());
  152.         }
  153.        
  154.         internal void WriteUInt16(UInt16 value)
  155.         {
  156.             dataWriter.Write(value);
  157.         }
  158.        
  159.         internal void WriteUInt32(UInt32 value)
  160.         {
  161.             dataWriter.Write(value);
  162.         }
  163.        
  164.         internal void WriteUInt64(UInt64 value)
  165.         {
  166.             dataWriter.Write(value);
  167.         }
  168.        
  169.         internal void WriteObjectEnd(NameInfo memberNameInfo, NameInfo typeNameInfo)
  170.         {
  171.         }
  172.        
  173.         internal void WriteSerializationHeaderEnd()
  174.         {
  175.             MessageEnd record = new MessageEnd();
  176.             record.Dump(sout);
  177.             record.Write(this);
  178.         }
  179.        
  180.         // Methods to write Binary Serialization Record onto the stream, a record is composed of primitive types
  181.        
  182.         internal void WriteSerializationHeader(int topId, int headerId, int minorVersion, int majorVersion)
  183.         {
  184.             SerializationHeaderRecord record = new SerializationHeaderRecord(BinaryHeaderEnum.SerializedStreamHeader, topId, headerId, minorVersion, majorVersion);
  185.             record.Dump();
  186.             record.Write(this);
  187.         }
  188.        
  189.        
  190.         internal BinaryMethodCall binaryMethodCall;
  191.         internal void WriteMethodCall()
  192.         {
  193.             if (binaryMethodCall == null)
  194.                 binaryMethodCall = new BinaryMethodCall();
  195.            
  196.             binaryMethodCall.Dump();
  197.             binaryMethodCall.Write(this);
  198.         }
  199.        
  200.         internal object[] WriteCallArray(string uri, string methodName, string typeName, Type[] instArgs, object[] args, object methodSignature, object callContext, object[] properties)
  201.         {
  202.             if (binaryMethodCall == null)
  203.                 binaryMethodCall = new BinaryMethodCall();
  204.             return binaryMethodCall.WriteArray(uri, methodName, typeName, instArgs, args, methodSignature, callContext, properties);
  205.         }
  206.        
  207.         internal BinaryMethodReturn binaryMethodReturn;
  208.         internal void WriteMethodReturn()
  209.         {
  210.             if (binaryMethodReturn == null)
  211.                 binaryMethodReturn = new BinaryMethodReturn();
  212.             binaryMethodReturn.Dump();
  213.             binaryMethodReturn.Write(this);
  214.         }
  215.        
  216.         internal object[] WriteReturnArray(object returnValue, object[] args, Exception exception, object callContext, object[] properties)
  217.         {
  218.             if (binaryMethodReturn == null)
  219.                 binaryMethodReturn = new BinaryMethodReturn();
  220.             return binaryMethodReturn.WriteArray(returnValue, args, exception, callContext, properties);
  221.         }
  222.        
  223.         internal BinaryObject binaryObject;
  224.         internal BinaryObjectWithMap binaryObjectWithMap;
  225.         internal BinaryObjectWithMapTyped binaryObjectWithMapTyped;
  226.         //internal BinaryCrossAppDomainMap crossAppDomainMap;
  227.        
  228.         internal void WriteObject(NameInfo nameInfo, NameInfo typeNameInfo, int numMembers, string[] memberNames, Type[] memberTypes, WriteObjectInfo[] memberObjectInfos)
  229.         {
  230.             InternalWriteItemNull();
  231.             int assemId;
  232.             #if _DEBUG
  233.             nameInfo.Dump("WriteObject nameInfo");
  234.             typeNameInfo.Dump("WriteObject typeNameInfo");
  235.             #endif
  236.            
  237.             int objectId = (int)nameInfo.NIobjectId;
  238.            
  239.             //if (objectId < 0)
  240.             // objectId = --m_nestedObjectCount;
  241.            
  242.             if (objectId > 0) {
  243.                 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
  244.             }
  245.            
  246.             string objectName = null;
  247.             if (objectId < 0) {
  248.                 // Nested Object
  249.                 objectName = typeNameInfo.NIname;
  250.             }
  251.             else {
  252.                 // Non-Nested
  253.                 objectName = nameInfo.NIname;
  254.             }
  255.             SerTrace.Log(this, "WriteObject objectName ", objectName);
  256.            
  257.             if (objectMapTable == null) {
  258.                 objectMapTable = new Hashtable();
  259.             }
  260.            
  261.             ObjectMapInfo objectMapInfo = (ObjectMapInfo)objectMapTable[objectName];
  262.            
  263.             if (objectMapInfo != null && objectMapInfo.isCompatible(numMembers, memberNames, memberTypes)) {
  264.                 // Object
  265.                 if (binaryObject == null)
  266.                     binaryObject = new BinaryObject();
  267.                 binaryObject.Set(objectId, objectMapInfo.objectId);
  268.                 #if _DEBUG
  269.                 binaryObject.Dump();
  270.                 #endif
  271.                 binaryObject.Write(this);
  272.             }
  273.             else if (!typeNameInfo.NItransmitTypeOnObject) {
  274.                
  275.                 // ObjectWithMap
  276.                 if (binaryObjectWithMap == null)
  277.                     binaryObjectWithMap = new BinaryObjectWithMap();
  278.                
  279.                 // BCL types are not placed into table
  280.                 assemId = (int)typeNameInfo.NIassemId;
  281.                 binaryObjectWithMap.Set(objectId, objectName, numMembers, memberNames, assemId);
  282.                
  283.                 binaryObjectWithMap.Dump();
  284.                 binaryObjectWithMap.Write(this);
  285.                 if (objectMapInfo == null)
  286.                     objectMapTable.Add(objectName, new ObjectMapInfo(objectId, numMembers, memberNames, memberTypes));
  287.             }
  288.             else {
  289.                 // ObjectWithMapTyped
  290.                 BinaryTypeEnum[] binaryTypeEnumA = new BinaryTypeEnum[numMembers];
  291.                 object[] typeInformationA = new object[numMembers];
  292.                 int[] assemIdA = new int[numMembers];
  293.                 for (int i = 0; i < numMembers; i++) {
  294.                     object typeInformation = null;
  295.                    
  296.                     binaryTypeEnumA[i] = BinaryConverter.GetBinaryTypeInfo(memberTypes[i], memberObjectInfos[i], null, objectWriter, out typeInformation, out assemId);
  297.                     typeInformationA[i] = typeInformation;
  298.                     assemIdA[i] = assemId;
  299.                     SerTrace.Log(this, "WriteObject ObjectWithMapTyped memberNames ", memberNames[i], ", memberType ", memberTypes[i], " binaryTypeEnum ", ((Enum)binaryTypeEnumA[i]).ToString(), ", typeInformation ", typeInformationA[i], " assemId ",
  300.                     assemIdA[i]);
  301.                 }
  302.                
  303.                 if (binaryObjectWithMapTyped == null)
  304.                     binaryObjectWithMapTyped = new BinaryObjectWithMapTyped();
  305.                
  306.                 // BCL types are not placed in table
  307.                 assemId = (int)typeNameInfo.NIassemId;
  308.                 binaryObjectWithMapTyped.Set(objectId, objectName, numMembers, memberNames, binaryTypeEnumA, typeInformationA, assemIdA, assemId);
  309.                 #if _DEBUG
  310.                 binaryObjectWithMapTyped.Dump();
  311.                 #endif
  312.                 binaryObjectWithMapTyped.Write(this);
  313.                 if (objectMapInfo == null)
  314.                     objectMapTable.Add(objectName, new ObjectMapInfo(objectId, numMembers, memberNames, memberTypes));
  315.             }
  316.         }
  317.        
  318.         internal BinaryObjectString binaryObjectString;
  319.         internal BinaryCrossAppDomainString binaryCrossAppDomainString;
  320.        
  321.         internal void WriteObjectString(int objectId, string value)
  322.         {
  323.             InternalWriteItemNull();
  324.            
  325.             if (binaryObjectString == null)
  326.                 binaryObjectString = new BinaryObjectString();
  327.             binaryObjectString.Set(objectId, value);
  328.             #if _DEBUG
  329.             binaryObjectString.Dump();
  330.             #endif
  331.             binaryObjectString.Write(this);
  332.         }
  333.        
  334.         internal BinaryArray binaryArray;
  335.        
  336.         internal void WriteSingleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Array array)
  337.         {
  338.             InternalWriteItemNull();
  339.             #if _DEBUG
  340.             arrayNameInfo.Dump("WriteSingleArray arrayNameInfo");
  341.             arrayElemTypeNameInfo.Dump("WriteSingleArray arrayElemTypeNameInfo");
  342.             #endif
  343.             BinaryArrayTypeEnum binaryArrayTypeEnum;
  344.             Int32[] lengthA = new Int32[1];
  345.             lengthA[0] = length;
  346.             Int32[] lowerBoundA = null;
  347.             object typeInformation = null;
  348.            
  349.             if (lowerBound == 0) {
  350.                 binaryArrayTypeEnum = BinaryArrayTypeEnum.Single;
  351.             }
  352.             else {
  353.                 binaryArrayTypeEnum = BinaryArrayTypeEnum.SingleOffset;
  354.                 lowerBoundA = new Int32[1];
  355.                 lowerBoundA[0] = lowerBound;
  356.             }
  357.            
  358.             int assemId;
  359.            
  360.             BinaryTypeEnum binaryTypeEnum = BinaryConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo.NItype, objectInfo, arrayElemTypeNameInfo.NIname, objectWriter, out typeInformation, out assemId);
  361.            
  362.             if (binaryArray == null)
  363.                 binaryArray = new BinaryArray();
  364.             binaryArray.Set((int)arrayNameInfo.NIobjectId, (int)1, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
  365.            
  366.             if (arrayNameInfo.NIobjectId > 0) {
  367.                 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
  368.             }
  369.             #if _DEBUG
  370.             binaryArray.Dump();
  371.             #endif
  372.             binaryArray.Write(this);
  373.            
  374.             if (Converter.IsWriteAsByteArray(arrayElemTypeNameInfo.NIprimitiveTypeEnum) && (lowerBound == 0)) {
  375.                 //array is written out as an array of bytes
  376.                 if (arrayElemTypeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Byte)
  377.                     WriteBytes((byte[])array);
  378.                 else if (arrayElemTypeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Char)
  379.                     WriteChars((char[])array);
  380.                 else
  381.                     WriteArrayAsBytes(array, Converter.TypeLength(arrayElemTypeNameInfo.NIprimitiveTypeEnum));
  382.             }
  383.         }
  384.        
  385.         byte[] byteBuffer = null;
  386.         int chunkSize = 4096;
  387.        
  388.         private void WriteArrayAsBytes(Array array, int typeLength)
  389.         {
  390.             InternalWriteItemNull();
  391.             int byteLength = array.Length * typeLength;
  392.             int arrayOffset = 0;
  393.             if (byteBuffer == null)
  394.                 byteBuffer = new byte[chunkSize];
  395.            
  396.             while (arrayOffset < array.Length) {
  397.                 int numArrayItems = Math.Min(chunkSize / typeLength, array.Length - arrayOffset);
  398.                 int bufferUsed = numArrayItems * typeLength;
  399.                 Buffer.InternalBlockCopy(array, arrayOffset * typeLength, byteBuffer, 0, bufferUsed);
  400.                 #if BIGENDIAN
  401.                 // we know that we are writing a primitive type, so just do a simple swap
  402.                 for (int i = 0; i < bufferUsed; i += typeLength) {
  403.                     for (int j = 0; j < typeLength / 2; j++) {
  404.                         byte tmp = byteBuffer[i + j];
  405.                         byteBuffer[i + j] = byteBuffer[i + typeLength - 1 - j];
  406.                         byteBuffer[i + typeLength - 1 - j] = tmp;
  407.                     }
  408.                 }
  409.                 #endif
  410.                 WriteBytes(byteBuffer, 0, bufferUsed);
  411.                 arrayOffset += numArrayItems;
  412.             }
  413.         }
  414.        
  415.        
  416.         internal void WriteJaggedArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound)
  417.         {
  418.             #if _DEBUG
  419.             arrayNameInfo.Dump("WriteRectangleArray arrayNameInfo");
  420.             arrayElemTypeNameInfo.Dump("WriteRectangleArray arrayElemTypeNameInfo");
  421.             #endif
  422.             InternalWriteItemNull();
  423.             BinaryArrayTypeEnum binaryArrayTypeEnum;
  424.             Int32[] lengthA = new Int32[1];
  425.             lengthA[0] = length;
  426.             Int32[] lowerBoundA = null;
  427.             object typeInformation = null;
  428.             int assemId = 0;
  429.            
  430.             if (lowerBound == 0) {
  431.                 binaryArrayTypeEnum = BinaryArrayTypeEnum.Jagged;
  432.             }
  433.             else {
  434.                 binaryArrayTypeEnum = BinaryArrayTypeEnum.JaggedOffset;
  435.                 lowerBoundA = new Int32[1];
  436.                 lowerBoundA[0] = lowerBound;
  437.             }
  438.            
  439.             BinaryTypeEnum binaryTypeEnum = BinaryConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo.NItype, objectInfo, arrayElemTypeNameInfo.NIname, objectWriter, out typeInformation, out assemId);
  440.            
  441.             if (binaryArray == null)
  442.                 binaryArray = new BinaryArray();
  443.             binaryArray.Set((int)arrayNameInfo.NIobjectId, (int)1, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
  444.            
  445.             if (arrayNameInfo.NIobjectId > 0) {
  446.                 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
  447.             }
  448.             #if _DEBUG
  449.             binaryArray.Dump();
  450.             #endif
  451.             binaryArray.Write(this);
  452.         }
  453.        
  454.         internal void WriteRectangleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int rank, int[] lengthA, int[] lowerBoundA)
  455.         {
  456.             #if _DEBUG
  457.             arrayNameInfo.Dump("WriteRectangleArray arrayNameInfo");
  458.             arrayElemTypeNameInfo.Dump("WriteRectangleArray arrayElemTypeNameInfo");
  459.             #endif
  460.             InternalWriteItemNull();
  461.            
  462.             BinaryArrayTypeEnum binaryArrayTypeEnum = BinaryArrayTypeEnum.Rectangular;
  463.             object typeInformation = null;
  464.             int assemId = 0;
  465.             BinaryTypeEnum binaryTypeEnum = BinaryConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo.NItype, objectInfo, arrayElemTypeNameInfo.NIname, objectWriter, out typeInformation, out assemId);
  466.            
  467.             if (binaryArray == null)
  468.                 binaryArray = new BinaryArray();
  469.            
  470.             for (int i = 0; i < rank; i++) {
  471.                 if (lowerBoundA[i] != 0) {
  472.                     binaryArrayTypeEnum = BinaryArrayTypeEnum.RectangularOffset;
  473.                     break;
  474.                 }
  475.                
  476.             }
  477.            
  478.             binaryArray.Set((int)arrayNameInfo.NIobjectId, rank, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
  479.            
  480.             if (arrayNameInfo.NIobjectId > 0) {
  481.                 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
  482.             }
  483.             #if _DEBUG
  484.             binaryArray.Dump();
  485.             #endif
  486.             binaryArray.Write(this);
  487.         }
  488.        
  489.        
  490.         internal void WriteObjectByteArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, byte[] byteA)
  491.         {
  492.             #if _DEBUG
  493.             arrayNameInfo.Dump("WriteObjectByteArray arrayNameInfo");
  494.             arrayElemTypeNameInfo.Dump("WriteObjectByteArray arrayElemTypeNameInfo");
  495.             #endif
  496.             InternalWriteItemNull();
  497.             WriteSingleArray(memberNameInfo, arrayNameInfo, objectInfo, arrayElemTypeNameInfo, length, lowerBound, byteA);
  498.         }
  499.        
  500.         internal MemberPrimitiveUnTyped memberPrimitiveUnTyped;
  501.         internal MemberPrimitiveTyped memberPrimitiveTyped;
  502.        
  503.         internal void WriteMember(NameInfo memberNameInfo, NameInfo typeNameInfo, object value)
  504.         {
  505.             #if _DEBUG
  506.             SerTrace.Log("BinaryWriter", "Write Member memberName ", memberNameInfo.NIname, ", value ", value);
  507.             memberNameInfo.Dump("WriteMember memberNameInfo");
  508.             typeNameInfo.Dump("WriteMember typeNameInfo");
  509.             #endif
  510.             InternalWriteItemNull();
  511.             InternalPrimitiveTypeE typeInformation = typeNameInfo.NIprimitiveTypeEnum;
  512.            
  513.             // Writes Members with primitive values
  514.            
  515.             if (memberNameInfo.NItransmitTypeOnMember) {
  516.                 if (memberPrimitiveTyped == null)
  517.                     memberPrimitiveTyped = new MemberPrimitiveTyped();
  518.                 memberPrimitiveTyped.Set((InternalPrimitiveTypeE)typeInformation, value);
  519.                
  520.                 if (memberNameInfo.NIisArrayItem) {
  521.                     BCLDebug.Trace("BINARY", "-----item-----");
  522.                 }
  523.                 else {
  524.                     BCLDebug.Trace("BINARY", "-----", memberNameInfo.NIname, "-----");
  525.                 }
  526.                 memberPrimitiveTyped.Dump();
  527.                
  528.                 memberPrimitiveTyped.Write(this);
  529.             }
  530.             else {
  531.                 if (memberPrimitiveUnTyped == null)
  532.                     memberPrimitiveUnTyped = new MemberPrimitiveUnTyped();
  533.                 memberPrimitiveUnTyped.Set(typeInformation, value);
  534.                
  535.                 if (memberNameInfo.NIisArrayItem) {
  536.                     BCLDebug.Trace("BINARY", "-----item-----");
  537.                 }
  538.                 else {
  539.                     BCLDebug.Trace("BINARY", "-----", memberNameInfo.NIname, "-----");
  540.                 }
  541.                 memberPrimitiveUnTyped.Dump();
  542.                
  543.                 memberPrimitiveUnTyped.Write(this);
  544.                
  545.             }
  546.         }
  547.        
  548.         internal ObjectNull objectNull;
  549.        
  550.        
  551.         internal void WriteNullMember(NameInfo memberNameInfo, NameInfo typeNameInfo)
  552.         {
  553.             #if _DEBUG
  554.             typeNameInfo.Dump("WriteNullMember typeNameInfo");
  555.             #endif
  556.             InternalWriteItemNull();
  557.             if (objectNull == null)
  558.                 objectNull = new ObjectNull();
  559.            
  560.             if (memberNameInfo.NIisArrayItem) {
  561.                 BCLDebug.Trace("BINARY", "-----item-----");
  562.             }
  563.             else {
  564.                 objectNull.SetNullCount(1);
  565.                 BCLDebug.Trace("BINARY", "-----", memberNameInfo.NIname, "-----");
  566.                 objectNull.Dump();
  567.                 objectNull.Write(this);
  568.                 nullCount = 0;
  569.             }
  570.         }
  571.        
  572.         internal MemberReference memberReference;
  573.        
  574.         internal void WriteMemberObjectRef(NameInfo memberNameInfo, int idRef)
  575.         {
  576.             InternalWriteItemNull();
  577.             if (memberReference == null)
  578.                 memberReference = new MemberReference();
  579.             memberReference.Set(idRef);
  580.            
  581.             if (memberNameInfo.NIisArrayItem) {
  582.                 BCLDebug.Trace("BINARY", "-----item-----");
  583.             }
  584.             else {
  585.                 BCLDebug.Trace("BINARY", "-----", memberNameInfo.NIname, "-----");
  586.             }
  587.             memberReference.Dump();
  588.            
  589.             memberReference.Write(this);
  590.         }
  591.        
  592.         internal void WriteMemberNested(NameInfo memberNameInfo)
  593.         {
  594.             InternalWriteItemNull();
  595.             if (memberNameInfo.NIisArrayItem) {
  596.                 BCLDebug.Trace("BINARY", "-----item-----");
  597.             }
  598.             else {
  599.                 BCLDebug.Trace("BINARY", "-----", memberNameInfo.NIname, "-----");
  600.             }
  601.         }
  602.        
  603.         internal void WriteMemberString(NameInfo memberNameInfo, NameInfo typeNameInfo, string value)
  604.         {
  605.             InternalWriteItemNull();
  606.             if (memberNameInfo.NIisArrayItem) {
  607.                 BCLDebug.Trace("BINARY", "-----item-----");
  608.             }
  609.             else {
  610.                 BCLDebug.Trace("BINARY", "-----", memberNameInfo.NIname, "-----");
  611.             }
  612.             WriteObjectString((int)typeNameInfo.NIobjectId, value);
  613.         }
  614.        
  615.         internal void WriteItem(NameInfo itemNameInfo, NameInfo typeNameInfo, object value)
  616.         {
  617.             InternalWriteItemNull();
  618.             WriteMember(itemNameInfo, typeNameInfo, value);
  619.         }
  620.        
  621.         internal void WriteNullItem(NameInfo itemNameInfo, NameInfo typeNameInfo)
  622.         {
  623.             nullCount++;
  624.             InternalWriteItemNull();
  625.         }
  626.        
  627.         internal void WriteDelayedNullItem()
  628.         {
  629.             nullCount++;
  630.         }
  631.        
  632.         internal void WriteItemEnd()
  633.         {
  634.             InternalWriteItemNull();
  635.         }
  636.        
  637.         private void InternalWriteItemNull()
  638.         {
  639.             if (nullCount > 0) {
  640.                 if (objectNull == null)
  641.                     objectNull = new ObjectNull();
  642.                 objectNull.SetNullCount(nullCount);
  643.                 BCLDebug.Trace("BINARY", "-----item-----");
  644.                 objectNull.Dump();
  645.                 objectNull.Write(this);
  646.                 nullCount = 0;
  647.             }
  648.         }
  649.        
  650.         internal void WriteItemObjectRef(NameInfo nameInfo, int idRef)
  651.         {
  652.             InternalWriteItemNull();
  653.             WriteMemberObjectRef(nameInfo, idRef);
  654.         }
  655.        
  656.        
  657.         internal BinaryAssembly binaryAssembly;
  658.         internal BinaryCrossAppDomainAssembly crossAppDomainAssembly;
  659.        
  660.         internal void WriteAssembly(string typeFullName, Type type, string assemblyString, int assemId, bool isNew, bool isInteropType)
  661.         {
  662.             SerTrace.Log(this, "WriteAssembly type ", type, ", id ", assemId, ", name ", assemblyString, ", isNew ", isNew);
  663.             //If the file being tested wasn't built as an assembly, then we're going to get null back
  664.             //for the assembly name. This is very unfortunate.
  665.             InternalWriteItemNull();
  666.             if (assemblyString == null) {
  667.                 assemblyString = String.Empty;
  668.             }
  669.            
  670.             if (isNew) {
  671.                 if (binaryAssembly == null)
  672.                     binaryAssembly = new BinaryAssembly();
  673.                 binaryAssembly.Set(assemId, assemblyString);
  674.                 binaryAssembly.Dump();
  675.                 binaryAssembly.Write(this);
  676.             }
  677.         }
  678.        
  679.         // Method to write a value onto a stream given its primitive type code
  680.         internal void WriteValue(InternalPrimitiveTypeE code, object value)
  681.         {
  682.             SerTrace.Log(this, "WriteValue Entry ", ((Enum)code).ToString(), " ", ((value == null) ? "<null>" : value.GetType().ToString()), " ", value);
  683.            
  684.             switch (code) {
  685.                 case InternalPrimitiveTypeE.Boolean:
  686.                     WriteBoolean(Convert.ToBoolean(value, CultureInfo.InvariantCulture));
  687.                     break;
  688.                 case InternalPrimitiveTypeE.Byte:
  689.                     WriteByte(Convert.ToByte(value, CultureInfo.InvariantCulture));
  690.                     break;
  691.                 case InternalPrimitiveTypeE.Char:
  692.                     WriteChar(Convert.ToChar(value, CultureInfo.InvariantCulture));
  693.                     break;
  694.                 case InternalPrimitiveTypeE.Double:
  695.                     WriteDouble(Convert.ToDouble(value, CultureInfo.InvariantCulture));
  696.                     break;
  697.                 case InternalPrimitiveTypeE.Int16:
  698.                     WriteInt16(Convert.ToInt16(value, CultureInfo.InvariantCulture));
  699.                     break;
  700.                 case InternalPrimitiveTypeE.Int32:
  701.                     WriteInt32(Convert.ToInt32(value, CultureInfo.InvariantCulture));
  702.                     break;
  703.                 case InternalPrimitiveTypeE.Int64:
  704.                     WriteInt64(Convert.ToInt64(value, CultureInfo.InvariantCulture));
  705.                     break;
  706.                 case InternalPrimitiveTypeE.SByte:
  707.                     WriteSByte(Convert.ToSByte(value, CultureInfo.InvariantCulture));
  708.                     break;
  709.                 case InternalPrimitiveTypeE.Single:
  710.                     WriteSingle(Convert.ToSingle(value, CultureInfo.InvariantCulture));
  711.                     break;
  712.                 case InternalPrimitiveTypeE.UInt16:
  713.                     WriteUInt16(Convert.ToUInt16(value, CultureInfo.InvariantCulture));
  714.                     break;
  715.                 case InternalPrimitiveTypeE.UInt32:
  716.                     WriteUInt32(Convert.ToUInt32(value, CultureInfo.InvariantCulture));
  717.                     break;
  718.                 case InternalPrimitiveTypeE.UInt64:
  719.                     WriteUInt64(Convert.ToUInt64(value, CultureInfo.InvariantCulture));
  720.                     break;
  721.                 case InternalPrimitiveTypeE.Decimal:
  722.                     WriteDecimal(Convert.ToDecimal(value, CultureInfo.InvariantCulture));
  723.                     break;
  724.                 case InternalPrimitiveTypeE.TimeSpan:
  725.                     WriteTimeSpan((TimeSpan)value);
  726.                     break;
  727.                 case InternalPrimitiveTypeE.DateTime:
  728.                     WriteDateTime((DateTime)value);
  729.                     break;
  730.                 default:
  731.                     throw new SerializationException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Serialization_TypeCode"), ((Enum)code).ToString()));
  732.                     break;
  733.             }
  734.             SerTrace.Log(this, "Write Exit ");
  735.         }
  736.     }
  737.    
  738.     internal sealed class ObjectMapInfo
  739.     {
  740.         internal int objectId;
  741.         int numMembers;
  742.         string[] memberNames;
  743.         Type[] memberTypes;
  744.        
  745.         internal ObjectMapInfo(int objectId, int numMembers, string[] memberNames, Type[] memberTypes)
  746.         {
  747.             this.objectId = objectId;
  748.             this.numMembers = numMembers;
  749.             this.memberNames = memberNames;
  750.             this.memberTypes = memberTypes;
  751.         }
  752.        
  753.         internal bool isCompatible(int numMembers, string[] memberNames, Type[] memberTypes)
  754.         {
  755.             bool result = true;
  756.             if (this.numMembers == numMembers) {
  757.                 for (int i = 0; i < numMembers; i++) {
  758.                     if (!(this.memberNames[i].Equals(memberNames[i]))) {
  759.                         result = false;
  760.                         break;
  761.                     }
  762.                     if ((memberTypes != null) && (this.memberTypes[i] != memberTypes[i])) {
  763.                         result = false;
  764.                         break;
  765.                     }
  766.                 }
  767.             }
  768.             else
  769.                 result = false;
  770.             return result;
  771.         }
  772.        
  773.     }
  774. }

Developer Fusion