mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
1322 lines
50 KiB
C#
1322 lines
50 KiB
C#
// ==++==
|
|
//
|
|
//
|
|
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// The use and distribution terms for this software are contained in the file
|
|
// named license.txt, which can be found in the root of this distribution.
|
|
// By using this software in any fashion, you are agreeing to be bound by the
|
|
// terms of this license.
|
|
//
|
|
// You must not remove this notice, or any other, from this software.
|
|
//
|
|
//
|
|
// ==--==
|
|
//============================================================
|
|
//
|
|
// Class: SerObjectInfo
|
|
// Purpose: Holds information about an objects Members
|
|
//
|
|
// Date: September 29, 1999
|
|
//
|
|
//============================================================
|
|
|
|
|
|
namespace System.Runtime.Serialization.Formatters.Soap
|
|
{
|
|
using System.Runtime.Remoting;
|
|
using System.Runtime.Remoting.Metadata;
|
|
using System.Runtime.Serialization;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Reflection;
|
|
using System.Diagnostics;
|
|
|
|
// This class contains information about an object. It is used so that
|
|
// the rest of the Formatter routines can use a common interface for
|
|
// a normal object, an ISerializable object, and a surrogate object
|
|
//
|
|
// The methods in this class are for the internal use of the Formatters.
|
|
// There use will be restricted when signing is supported for assemblies
|
|
internal sealed class WriteObjectInfo
|
|
{
|
|
internal int objectInfoId;
|
|
|
|
internal Object obj;
|
|
internal Type objectType;
|
|
|
|
internal bool isSi = false;
|
|
internal bool isNamed = false;
|
|
internal bool isTyped = false;
|
|
|
|
internal SerializationInfo si = null;
|
|
|
|
internal SerObjectInfoCache cache = null;
|
|
|
|
internal Object[] memberData = null;
|
|
internal ISerializationSurrogate serializationSurrogate = null;
|
|
internal ISurrogateSelector surrogateSelector;
|
|
internal IFormatterConverter converter;
|
|
|
|
internal StreamingContext context;
|
|
|
|
internal SerObjectInfoInit serObjectInfoInit = null;
|
|
|
|
// Writing and Parsing information
|
|
internal long objectId;
|
|
internal long assemId;
|
|
|
|
private int lastPosition = 0;
|
|
private SoapAttributeInfo parentMemberAttributeInfo;
|
|
internal bool isArray = false;
|
|
internal SoapAttributeInfo typeAttributeInfo;
|
|
internal WriteObjectInfo arrayElemObjectInfo;
|
|
|
|
|
|
internal WriteObjectInfo()
|
|
{
|
|
}
|
|
|
|
internal void ObjectEnd()
|
|
{
|
|
InternalST.Soap( this, objectInfoId," objectType ",objectType," ObjectEnd");
|
|
PutObjectInfo(serObjectInfoInit, this);
|
|
}
|
|
|
|
private void InternalInit()
|
|
{
|
|
InternalST.Soap( this, objectInfoId," InternalInit");
|
|
obj = null;
|
|
objectType = null;
|
|
isSi = false;
|
|
isNamed = false;
|
|
isTyped = false;
|
|
si = null;
|
|
cache = null;
|
|
memberData = null;
|
|
isArray = false;
|
|
|
|
// Writing and Parsing information
|
|
objectId = 0;
|
|
assemId = 0;
|
|
|
|
// Added for Soap
|
|
lastPosition = 0;
|
|
typeAttributeInfo = null;
|
|
parentMemberAttributeInfo = null;
|
|
arrayElemObjectInfo = null;
|
|
}
|
|
|
|
internal static WriteObjectInfo Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo)
|
|
{
|
|
WriteObjectInfo soi = GetObjectInfo(serObjectInfoInit);
|
|
|
|
soi.InitSerialize(obj, surrogateSelector, context, serObjectInfoInit, converter, attributeInfo);
|
|
return soi;
|
|
}
|
|
|
|
// Write constructor
|
|
internal void InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo)
|
|
{
|
|
InternalST.Soap( this, objectInfoId," Constructor 1 ",obj);
|
|
this.context = context;
|
|
this.obj = obj;
|
|
this.serObjectInfoInit = serObjectInfoInit;
|
|
this.parentMemberAttributeInfo = attributeInfo;
|
|
this.surrogateSelector = surrogateSelector;
|
|
this.converter = converter;
|
|
ISurrogateSelector surrogateSelectorTemp;
|
|
|
|
if (RemotingServices.IsTransparentProxy(obj))
|
|
objectType = Converter.typeofMarshalByRefObject;
|
|
else
|
|
objectType = obj.GetType();
|
|
|
|
if (objectType.IsArray)
|
|
{
|
|
arrayElemObjectInfo = Serialize(objectType.GetElementType(), surrogateSelector, context, serObjectInfoInit, converter, null);
|
|
typeAttributeInfo = GetTypeAttributeInfo();
|
|
isArray = true;
|
|
InitNoMembers();
|
|
return;
|
|
}
|
|
|
|
InternalST.Soap( this, objectInfoId," Constructor 1 trace 2");
|
|
|
|
typeAttributeInfo = GetTypeAttributeInfo();
|
|
|
|
if (surrogateSelector != null && (serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp)) != null)
|
|
{
|
|
InternalST.Soap( this, objectInfoId," Constructor 1 trace 3");
|
|
si = new SerializationInfo(objectType, converter);
|
|
if (!objectType.IsPrimitive)
|
|
serializationSurrogate.GetObjectData(obj, si, context);
|
|
InitSiWrite();
|
|
}
|
|
else if (obj is ISerializable)
|
|
{
|
|
if (!objectType.IsSerializable)
|
|
{
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_NonSerType"),
|
|
objectType.FullName, objectType.Module.Assembly.FullName));
|
|
}
|
|
si = new SerializationInfo(objectType, converter);
|
|
((ISerializable)obj).GetObjectData(si, context);
|
|
InternalST.Soap( this, objectInfoId," Constructor 1 trace 4 ISerializable "+objectType);
|
|
InitSiWrite();
|
|
}
|
|
else
|
|
{
|
|
InternalST.Soap(this, objectInfoId," Constructor 1 trace 5");
|
|
InitMemberInfo();
|
|
}
|
|
}
|
|
|
|
[Conditional("SER_LOGGING")]
|
|
private void DumpMemberInfo()
|
|
{
|
|
for (int i=0; i<cache.memberInfos.Length; i++)
|
|
{
|
|
InternalST.Soap( this, objectInfoId," Constructor 1 memberInfos data ",cache.memberInfos[i].Name," ",memberData[i]);
|
|
|
|
}
|
|
}
|
|
|
|
internal static WriteObjectInfo Serialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo)
|
|
{
|
|
WriteObjectInfo soi = GetObjectInfo(serObjectInfoInit);
|
|
soi.InitSerialize(objectType, surrogateSelector, context, serObjectInfoInit, converter, attributeInfo);
|
|
return soi;
|
|
}
|
|
|
|
// Write Constructor used for array types or null members
|
|
internal void InitSerialize(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, SoapAttributeInfo attributeInfo)
|
|
{
|
|
|
|
InternalST.Soap( this, objectInfoId," Constructor 2 ",objectType);
|
|
|
|
this.objectType = objectType;
|
|
this.context = context;
|
|
this.serObjectInfoInit = serObjectInfoInit;
|
|
this.parentMemberAttributeInfo = attributeInfo;
|
|
this.surrogateSelector = surrogateSelector;
|
|
this.converter = converter;
|
|
|
|
if (objectType.IsArray)
|
|
{
|
|
arrayElemObjectInfo = Serialize(objectType.GetElementType(), surrogateSelector, context, serObjectInfoInit, converter, null);
|
|
typeAttributeInfo = GetTypeAttributeInfo();
|
|
InitNoMembers();
|
|
return;
|
|
}
|
|
|
|
typeAttributeInfo = GetTypeAttributeInfo();
|
|
|
|
ISurrogateSelector surrogateSelectorTemp = null;
|
|
|
|
if (surrogateSelector!=null)
|
|
serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp);
|
|
|
|
if (serializationSurrogate != null)
|
|
{
|
|
isSi = true;
|
|
}
|
|
else if (objectType == Converter.typeofObject)
|
|
{
|
|
}
|
|
else if (Converter.typeofISerializable.IsAssignableFrom(objectType))
|
|
isSi = true;
|
|
|
|
if (isSi)
|
|
{
|
|
si = new SerializationInfo(objectType, converter);
|
|
cache = new SerObjectInfoCache();
|
|
cache.fullTypeName = si.FullTypeName;
|
|
cache.assemblyString = si.AssemblyName;
|
|
}
|
|
else
|
|
{
|
|
InitMemberInfo();
|
|
}
|
|
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitSerialize Exit ",isSi);
|
|
}
|
|
|
|
private void InitSiWrite()
|
|
{
|
|
InternalST.Soap( this, objectInfoId," InitSiWrite Entry ");
|
|
// FormatterWrapper instructs the Formatters to use the
|
|
// __WrappedObject has the real object. This is a way
|
|
// to get Surrogates to return a real object.
|
|
if (si.FullTypeName.Equals("FormatterWrapper"))
|
|
{
|
|
obj = si.GetValue("__WrappedObject", Converter.typeofObject);
|
|
InitSerialize(obj, surrogateSelector, context, serObjectInfoInit, converter, null);
|
|
}
|
|
else
|
|
{
|
|
|
|
SerializationInfoEnumerator siEnum = null;
|
|
isSi = true;
|
|
siEnum = si.GetEnumerator();
|
|
int infoLength = 0;
|
|
|
|
infoLength = si.MemberCount;
|
|
|
|
int count = infoLength;
|
|
|
|
// For ISerializable cache cannot be saved because each object instance can have different values
|
|
// BinaryWriter only puts the map on the wire if the ISerializable map cannot be reused.
|
|
cache = new SerObjectInfoCache();
|
|
cache.memberNames = new String[count];
|
|
cache.memberTypes = new Type[count];
|
|
memberData = new Object[count];
|
|
|
|
cache.fullTypeName = si.FullTypeName;
|
|
cache.assemblyString = si.AssemblyName;
|
|
siEnum = si.GetEnumerator();
|
|
for (int i=0; siEnum.MoveNext(); i++)
|
|
{
|
|
cache.memberNames[i] = siEnum.Name;
|
|
cache.memberTypes[i] = siEnum.ObjectType;
|
|
memberData[i] = siEnum.Value;
|
|
InternalST.Soap( this,objectInfoId+" ",objectType," InitSiWrite ",cache.memberNames[i]," Type ",cache.memberTypes[i]," data ",memberData[i]);
|
|
}
|
|
|
|
isNamed = true;
|
|
isTyped = false;
|
|
}
|
|
InternalST.Soap(this, objectInfoId," InitSiWrite Exit ");
|
|
}
|
|
|
|
private void InitNoMembers()
|
|
{
|
|
cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
|
|
if (cache == null)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo new cache");
|
|
cache = new SerObjectInfoCache();
|
|
cache.fullTypeName = objectType.FullName;
|
|
cache.assemblyString = objectType.Module.Assembly.FullName;
|
|
serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
|
|
}
|
|
}
|
|
|
|
private void InitMemberInfo()
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo Entry");
|
|
|
|
cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
|
|
if (cache == null)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo new cache");
|
|
cache = new SerObjectInfoCache();
|
|
int count = 0;
|
|
if (!objectType.IsByRef) // byref will only occur for MethodSignature
|
|
{
|
|
cache.memberInfos = FormatterServices.GetSerializableMembers(objectType, context);
|
|
count = cache.memberInfos.Length;
|
|
}
|
|
cache.memberNames = new String[count];
|
|
cache.memberTypes = new Type[count];
|
|
cache.memberAttributeInfos = new SoapAttributeInfo[count];
|
|
|
|
// Calculate new arrays
|
|
for (int i=0; i<count; i++)
|
|
{
|
|
cache.memberNames[i] = cache.memberInfos[i].Name;
|
|
cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
|
|
cache.memberAttributeInfos[i] = Attr.GetMemberAttributeInfo(cache.memberInfos[i], cache.memberNames[i], cache.memberTypes[i]);
|
|
InternalST.Soap( this, objectInfoId," InitMemberInfo name ",cache.memberNames[i],", type ",cache.memberTypes[i],", memberInfoType ",cache.memberInfos[i].GetType());
|
|
}
|
|
cache.fullTypeName = objectType.FullName;
|
|
cache.assemblyString = objectType.Module.Assembly.FullName;
|
|
serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
|
|
}
|
|
|
|
if (obj != null)
|
|
{
|
|
memberData = FormatterServices.GetObjectData(obj, cache.memberInfos);
|
|
DumpMemberInfo();
|
|
}
|
|
|
|
isTyped = true;
|
|
isNamed = true;
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo Exit");
|
|
}
|
|
|
|
|
|
// Return type name for the object.
|
|
|
|
internal String GetTypeFullName()
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetTypeFullName isSi ",isSi, " "+cache.fullTypeName);
|
|
return cache.fullTypeName;
|
|
}
|
|
|
|
internal String GetAssemblyString()
|
|
{
|
|
String assemblyString = null;
|
|
InternalST.Soap( this,objectInfoId," ", objectType, " GetAssemblyString Entry isSi ",isSi);
|
|
|
|
if (arrayElemObjectInfo != null)
|
|
assemblyString = arrayElemObjectInfo.GetAssemblyString();
|
|
else if (IsAttributeNameSpace())
|
|
assemblyString = typeAttributeInfo.m_nameSpace;
|
|
else
|
|
assemblyString = cache.assemblyString;
|
|
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetAssemblyString Exit ",assemblyString);
|
|
return assemblyString;
|
|
}
|
|
|
|
|
|
// Retrieves the member type from the MemberInfo
|
|
|
|
internal Type GetMemberType(MemberInfo objMember)
|
|
{
|
|
Type objectType = null;
|
|
|
|
if (objMember is FieldInfo)
|
|
{
|
|
objectType = ((FieldInfo)objMember).FieldType;
|
|
InternalST.Soap( this, objectInfoId," ", "GetMemberType FieldInfo ",objectType);
|
|
}
|
|
else if (objMember is PropertyInfo)
|
|
{
|
|
objectType = ((PropertyInfo)objMember).PropertyType;
|
|
InternalST.Soap( this,objectInfoId," ", "GetMemberType PropertyInfo ",objectType);
|
|
}
|
|
else
|
|
{
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_SerMemberInfo"),objMember.GetType()));
|
|
}
|
|
|
|
return objectType;
|
|
}
|
|
|
|
// Return the information about the object's members
|
|
|
|
internal void GetMemberInfo(out String[] outMemberNames, out Type[] outMemberTypes, out Object[] outMemberData, out SoapAttributeInfo[] outAttributeInfo)
|
|
{
|
|
outMemberNames = cache.memberNames;
|
|
outMemberTypes = cache.memberTypes;
|
|
outMemberData = memberData;
|
|
outAttributeInfo = cache.memberAttributeInfos;
|
|
|
|
if (isSi)
|
|
{
|
|
if (!isNamed)
|
|
throw new SerializationException(SoapUtil.GetResourceString("Serialization_ISerializableMemberInfo"));
|
|
}
|
|
}
|
|
|
|
private static WriteObjectInfo GetObjectInfo(SerObjectInfoInit serObjectInfoInit)
|
|
{
|
|
WriteObjectInfo objectInfo = null;
|
|
|
|
if (!serObjectInfoInit.oiPool.IsEmpty())
|
|
{
|
|
objectInfo = (WriteObjectInfo)serObjectInfoInit.oiPool.Pop();
|
|
objectInfo.InternalInit();
|
|
//InternalST.Soap( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo from pool");
|
|
}
|
|
else
|
|
{
|
|
objectInfo = new WriteObjectInfo();
|
|
objectInfo.objectInfoId = serObjectInfoInit.objectInfoIdCount++;
|
|
//InternalST.Soap( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo new not from pool");
|
|
}
|
|
|
|
return objectInfo;
|
|
}
|
|
|
|
private int Position(String name)
|
|
{
|
|
InternalST.Soap( this, objectInfoId," Position ",lastPosition," ",name);
|
|
if (cache.memberNames[lastPosition].Equals(name))
|
|
{
|
|
return lastPosition;
|
|
}
|
|
else if ((++lastPosition < cache.memberNames.Length) && (cache.memberNames[lastPosition].Equals(name)))
|
|
{
|
|
return lastPosition;
|
|
}
|
|
else
|
|
{
|
|
// Search for name
|
|
InternalST.Soap( this, objectInfoId," Position miss search for name "+name);
|
|
for (int i=0; i<cache.memberNames.Length; i++)
|
|
{
|
|
if (cache.memberNames[i].Equals(name))
|
|
{
|
|
lastPosition = i;
|
|
return lastPosition;
|
|
}
|
|
}
|
|
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_Position"),objectType+" "+name));
|
|
}
|
|
}
|
|
|
|
private static void PutObjectInfo(SerObjectInfoInit serObjectInfoInit, WriteObjectInfo objectInfo)
|
|
{
|
|
serObjectInfoInit.oiPool.Push(objectInfo);
|
|
//InternalST.Soap( "PutObjectInfo",objectInfo.objectInfoId," PutObjectInfo to pool");
|
|
}
|
|
|
|
internal bool IsInteropNameSpace()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsInteropNameSpace();
|
|
|
|
if (IsAttributeNameSpace() || IsCallElement())
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsCallElement()
|
|
{
|
|
// This should only return true when this object is being
|
|
// serialized first.
|
|
|
|
if ((objectType != Converter.typeofObject) &&
|
|
(Converter.typeofIMethodCallMessage.IsAssignableFrom(objectType) &&
|
|
!Converter.typeofIConstructionCallMessage.IsAssignableFrom(objectType)) ||
|
|
(objectType == Converter.typeofReturnMessage) ||
|
|
(objectType == Converter.typeofInternalSoapMessage))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal bool IsCustomXmlAttribute()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsCustomXmlAttribute();
|
|
|
|
if ((typeAttributeInfo != null) &&
|
|
((typeAttributeInfo.m_attributeType & SoapAttributeType.XmlAttribute) != 0))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsCustomXmlElement()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsCustomXmlElement();
|
|
|
|
if ((typeAttributeInfo != null) &&
|
|
((typeAttributeInfo.m_attributeType & SoapAttributeType.XmlElement) != 0))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsAttributeNameSpace()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsAttributeNameSpace();
|
|
|
|
if ((typeAttributeInfo != null) && (typeAttributeInfo.m_nameSpace != null))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsAttributeElementName()
|
|
{
|
|
if ((typeAttributeInfo != null) && (typeAttributeInfo.m_elementName != null))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsAttributeTypeName()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsAttributeTypeName();
|
|
|
|
if ((typeAttributeInfo != null) && (typeAttributeInfo.m_typeName != null))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
// Check for Interop type (SchemaType)
|
|
private SoapAttributeInfo GetTypeAttributeInfo()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.GetTypeAttributeInfo();
|
|
|
|
SoapAttributeInfo attributeInfo = null;
|
|
if (parentMemberAttributeInfo != null)
|
|
attributeInfo = parentMemberAttributeInfo;
|
|
else
|
|
attributeInfo = new SoapAttributeInfo();
|
|
|
|
Attr.ProcessTypeAttribute(objectType, attributeInfo);
|
|
|
|
attributeInfo.Dump("type "+objectType);
|
|
return attributeInfo;
|
|
}
|
|
|
|
|
|
// Specifies whether the embedded attribute is set for a member.
|
|
|
|
internal bool IsEmbeddedAttribute(String name)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," IsEmbedded Entry ",name);
|
|
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsEmbeddedAttribute(name);
|
|
|
|
bool isEmbedded = false;
|
|
if (cache.memberAttributeInfos != null && cache.memberAttributeInfos.Length > 0)
|
|
{
|
|
SoapAttributeInfo attributeInfo = cache.memberAttributeInfos[Position(name)];
|
|
isEmbedded = attributeInfo.IsEmbedded();
|
|
}
|
|
InternalST.Soap( this,objectInfoId," ", objectType," IsEmbedded Exit ",isEmbedded);
|
|
return isEmbedded;
|
|
}
|
|
}
|
|
|
|
|
|
internal sealed class ReadObjectInfo
|
|
{
|
|
internal int objectInfoId;
|
|
|
|
internal Object obj;
|
|
internal Type objectType;
|
|
|
|
|
|
internal ObjectManager objectManager;
|
|
|
|
internal int count;
|
|
|
|
internal bool isSi = false;
|
|
internal bool isNamed = false;
|
|
internal bool isTyped = false;
|
|
|
|
internal SerializationInfo si = null;
|
|
|
|
internal SerObjectInfoCache cache = null;
|
|
|
|
internal String[] wireMemberNames = null;
|
|
internal Type[] wireMemberTypes = null;
|
|
internal Object[] memberData = null;
|
|
|
|
private int lastPosition = 0;
|
|
|
|
internal ISurrogateSelector surrogateSelector = null;
|
|
internal ISerializationSurrogate serializationSurrogate = null;
|
|
|
|
internal StreamingContext context;
|
|
|
|
|
|
// Si Read
|
|
internal ArrayList memberTypesList;
|
|
|
|
internal SerObjectInfoInit serObjectInfoInit = null;
|
|
|
|
internal IFormatterConverter formatterConverter;
|
|
|
|
// fake object for soap top record when remoting or IRemotingFormatter interface
|
|
internal bool bfake = false;
|
|
internal bool bSoapFault = false;
|
|
internal ArrayList paramNameList; // Contain parameter names in correct order
|
|
private int majorVersion = 0;
|
|
private int minorVersion = 0;
|
|
internal SoapAttributeInfo typeAttributeInfo;
|
|
private ReadObjectInfo arrayElemObjectInfo;
|
|
private int numberMembersSeen = 0;
|
|
|
|
internal ReadObjectInfo()
|
|
{
|
|
}
|
|
|
|
internal void ObjectEnd()
|
|
{
|
|
InternalST.Soap( this, objectInfoId," objectType ",objectType," ObjectEnd");
|
|
PutObjectInfo(serObjectInfoInit, this);
|
|
}
|
|
|
|
private void InternalInit()
|
|
{
|
|
InternalST.Soap( this, objectInfoId," objectType ",objectType," InternalInit");
|
|
obj = null;
|
|
objectType = null;
|
|
count = 0;
|
|
isSi = false;
|
|
isNamed = false;
|
|
isTyped = false;
|
|
si = null;
|
|
wireMemberNames = null;
|
|
wireMemberTypes = null;
|
|
cache = null;
|
|
lastPosition = 0;
|
|
numberMembersSeen = 0;
|
|
|
|
bfake = false;
|
|
bSoapFault = false;
|
|
majorVersion = 0;
|
|
minorVersion = 0;
|
|
typeAttributeInfo = null;
|
|
arrayElemObjectInfo = null;
|
|
|
|
|
|
|
|
// Si Read
|
|
if (memberTypesList != null)
|
|
{
|
|
memberTypesList.Clear();
|
|
}
|
|
|
|
}
|
|
|
|
internal static ReadObjectInfo Create(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, String assemblyName)
|
|
{
|
|
ReadObjectInfo soi = GetObjectInfo(serObjectInfoInit);
|
|
soi.Init(objectType, surrogateSelector, context, objectManager, serObjectInfoInit, converter, assemblyName);
|
|
return soi;
|
|
}
|
|
|
|
|
|
// Read Constructor
|
|
internal void Init(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, String assemblyName)
|
|
{
|
|
|
|
InternalST.Soap( this, objectInfoId," Constructor 3 ",objectType);
|
|
|
|
this.objectType = objectType;
|
|
this.objectManager = objectManager;
|
|
this.context = context;
|
|
this.serObjectInfoInit = serObjectInfoInit;
|
|
this.formatterConverter = converter;
|
|
|
|
InitReadConstructor(objectType, surrogateSelector, context, assemblyName);
|
|
}
|
|
|
|
internal static ReadObjectInfo Create(Type objectType, String[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, String assemblyName)
|
|
{
|
|
ReadObjectInfo soi = GetObjectInfo(serObjectInfoInit);
|
|
soi.Init(objectType, memberNames,memberTypes, surrogateSelector, context, objectManager, serObjectInfoInit, converter, assemblyName);
|
|
return soi;
|
|
}
|
|
|
|
// Read Constructor
|
|
internal void Init(Type objectType, String[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, String assemblyName)
|
|
{
|
|
InternalST.Soap( this,objectInfoId, " Constructor 5 ",objectType);
|
|
this.objectType = objectType;
|
|
this.objectManager = objectManager;
|
|
this.wireMemberNames = memberNames;
|
|
this.wireMemberTypes = memberTypes;
|
|
this.context = context;
|
|
this.serObjectInfoInit = serObjectInfoInit;
|
|
this.formatterConverter = converter;
|
|
if (memberNames != null)
|
|
isNamed = true;
|
|
if (memberTypes != null)
|
|
isTyped = true;
|
|
|
|
InitReadConstructor(objectType, surrogateSelector, context, assemblyName);
|
|
}
|
|
|
|
private void InitReadConstructor(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, String assemblyName)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitReadConstructor Entry ",objectType);
|
|
|
|
if (objectType.IsArray)
|
|
{
|
|
arrayElemObjectInfo = Create(objectType.GetElementType(), surrogateSelector, context, objectManager, serObjectInfoInit, formatterConverter, assemblyName);
|
|
typeAttributeInfo = GetTypeAttributeInfo();
|
|
InitNoMembers();
|
|
return;
|
|
}
|
|
|
|
ISurrogateSelector surrogateSelectorTemp = null;
|
|
|
|
if (surrogateSelector!=null)
|
|
serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out surrogateSelectorTemp);
|
|
|
|
if (serializationSurrogate != null)
|
|
{
|
|
isSi = true;
|
|
}
|
|
else if (objectType == Converter.typeofObject)
|
|
{
|
|
}
|
|
else if (Converter.typeofISerializable.IsAssignableFrom(objectType))
|
|
isSi = true;
|
|
|
|
if (isSi)
|
|
{
|
|
si = new SerializationInfo(objectType, formatterConverter);
|
|
InitSiRead(assemblyName);
|
|
}
|
|
else
|
|
{
|
|
InitMemberInfo();
|
|
}
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitReadConstructor Exit ",isSi);
|
|
}
|
|
|
|
private void InitSiRead(String assemblyName)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo new cache");
|
|
if (assemblyName != null)
|
|
{
|
|
// Need to set to assembly name from the wire. This assembly name could contain version information
|
|
// not in the default assembly name which was returned from fusion
|
|
si.AssemblyName = assemblyName;
|
|
}
|
|
cache = new SerObjectInfoCache();
|
|
cache.fullTypeName = si.FullTypeName;
|
|
cache.assemblyString = si.AssemblyName;
|
|
|
|
// Input from IFieldInfo
|
|
cache.memberNames = wireMemberNames;
|
|
cache.memberTypes = wireMemberTypes;
|
|
|
|
if (memberTypesList != null)
|
|
{
|
|
memberTypesList = new ArrayList(20);
|
|
}
|
|
|
|
|
|
if (wireMemberNames != null && wireMemberTypes != null)
|
|
isTyped = true;
|
|
}
|
|
|
|
private void InitNoMembers()
|
|
{
|
|
cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
|
|
if (cache == null)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo new cache");
|
|
cache = new SerObjectInfoCache();
|
|
cache.fullTypeName = objectType.FullName;
|
|
cache.assemblyString = objectType.Module.Assembly.FullName;
|
|
serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
|
|
}
|
|
}
|
|
|
|
private void InitMemberInfo()
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo Entry");
|
|
|
|
cache = (SerObjectInfoCache)serObjectInfoInit.seenBeforeTable[objectType];
|
|
if (cache == null)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo new cache");
|
|
cache = new SerObjectInfoCache();
|
|
cache.memberInfos = FormatterServices.GetSerializableMembers(objectType, context);
|
|
count = cache.memberInfos.Length;
|
|
cache.memberNames = new String[count];
|
|
cache.memberTypes = new Type[count];
|
|
cache.memberAttributeInfos = new SoapAttributeInfo[count];
|
|
|
|
// Calculate new arrays
|
|
for (int i=0; i<count; i++)
|
|
{
|
|
cache.memberNames[i] = cache.memberInfos[i].Name;
|
|
cache.memberTypes[i] = GetMemberType(cache.memberInfos[i]);
|
|
cache.memberAttributeInfos[i] = Attr.GetMemberAttributeInfo(cache.memberInfos[i], cache.memberNames[i], cache.memberTypes[i]);
|
|
InternalST.Soap( this, objectInfoId," InitMemberInfo name ",cache.memberNames[i],", type ",cache.memberTypes[i],", memberInfoType ",cache.memberInfos[i].GetType());
|
|
}
|
|
cache.fullTypeName = objectType.FullName;
|
|
cache.assemblyString = objectType.Module.Assembly.FullName;
|
|
serObjectInfoInit.seenBeforeTable.Add(objectType, cache);
|
|
}
|
|
memberData = new Object[cache.memberNames.Length];
|
|
|
|
isTyped = true;
|
|
isNamed = true;
|
|
InternalST.Soap( this,objectInfoId," ", objectType," InitMemberInfo Exit");
|
|
}
|
|
|
|
internal String GetAssemblyString()
|
|
{
|
|
String assemblyString = null;
|
|
InternalST.Soap( this,objectInfoId," ", objectType, " GetAssemblyString Entry isSi ",isSi);
|
|
|
|
if (arrayElemObjectInfo != null)
|
|
assemblyString = arrayElemObjectInfo.GetAssemblyString();
|
|
else if (IsAttributeNameSpace())
|
|
assemblyString = typeAttributeInfo.m_nameSpace;
|
|
else
|
|
assemblyString = cache.assemblyString;
|
|
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetAssemblyString Exit ",assemblyString);
|
|
return assemblyString;
|
|
}
|
|
|
|
|
|
// Get the memberInfo for a memberName
|
|
internal MemberInfo GetMemberInfo(String name)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetMemberInfo Entry ",name);
|
|
if (isSi)
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_MemberInfo"),objectType+" "+name));
|
|
if (cache.memberInfos == null)
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_NoMemberInfo"),objectType+" "+name));
|
|
return cache.memberInfos[Position(name)];
|
|
}
|
|
|
|
internal Type GetMemberType(MemberInfo objMember)
|
|
{
|
|
Type objectType = null;
|
|
|
|
if (objMember is FieldInfo)
|
|
{
|
|
objectType = ((FieldInfo)objMember).FieldType;
|
|
InternalST.Soap( this, objectInfoId," ", "GetMemberType FieldInfo ",objectType);
|
|
}
|
|
else if (objMember is PropertyInfo)
|
|
{
|
|
objectType = ((PropertyInfo)objMember).PropertyType;
|
|
InternalST.Soap( this,objectInfoId," ", "GetMemberType PropertyInfo ",objectType);
|
|
}
|
|
else
|
|
{
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_SerMemberInfo"),objMember.GetType()));
|
|
}
|
|
|
|
return objectType;
|
|
}
|
|
|
|
// Get the ObjectType for a memberName
|
|
internal Type GetType(String name)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetType Entry ",name);
|
|
Type type = null;
|
|
if (isTyped)
|
|
type = cache.memberTypes[Position(name)];
|
|
else
|
|
type = (Type)memberTypesList[Position(name)];
|
|
|
|
if (type == null)
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_ISerializableTypes"),objectType+" "+name));
|
|
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetType Exit ",type);
|
|
return type;
|
|
}
|
|
|
|
internal Type GetType(int position)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetType Entry ByPosition ",position);
|
|
Type type = null;
|
|
if (isTyped)
|
|
{
|
|
if (position >= cache.memberTypes.Length)
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_ISerializableTypes"),objectType+" "+position));
|
|
type = cache.memberTypes[position];
|
|
|
|
InternalST.Soap( this,objectInfoId," ", objectType," GetType Exit ByPosition ",type);
|
|
}
|
|
return type;
|
|
}
|
|
|
|
|
|
internal void AddParamName(String name)
|
|
{
|
|
if (!bfake)
|
|
return;
|
|
|
|
if (name[0] == '_' && name[1] == '_')
|
|
{
|
|
if (name == "__fault")
|
|
{
|
|
bSoapFault = true;
|
|
return;
|
|
}
|
|
else if (name == "__methodName" || name == "__keyToNamespaceTable" || name == "__paramNameList" || name == "__xmlNameSpace")
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
InternalST.Soap( this,objectInfoId," ", objectType," AddParamName Add "+name);
|
|
paramNameList.Add(name);
|
|
}
|
|
|
|
// Adds the value for a memberName
|
|
internal void AddValue(String name, Object value)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," AddValue ",name," ",value," isSi ",isSi);
|
|
if (isSi)
|
|
{
|
|
if (bfake)
|
|
{
|
|
AddParamName(name);
|
|
}
|
|
|
|
si.AddValue(name, value, objectType);
|
|
}
|
|
else
|
|
{
|
|
// Console.WriteLine("Calling add value for " + name + " with value " + value);
|
|
|
|
int position = Position(name);
|
|
memberData[position] = value;
|
|
}
|
|
}
|
|
|
|
internal void AddMemberSeen()
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," AddMemberSeen ");
|
|
numberMembersSeen++;
|
|
}
|
|
|
|
//Soap fake object
|
|
internal ArrayList SetFakeObject()
|
|
{
|
|
bfake = true;
|
|
paramNameList = new ArrayList(10);
|
|
return paramNameList;
|
|
}
|
|
|
|
internal void SetVersion(int major, int minor)
|
|
{
|
|
majorVersion = major;
|
|
minorVersion = minor;
|
|
}
|
|
|
|
// Records an objectId in a member when the actual object for that member is not yet known
|
|
internal void RecordFixup(long objectId, String name, long idRef)
|
|
{
|
|
|
|
if (isSi)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType, " RecordFixup RecordDelayedFixup objectId ",objectId," name ",name," idRef ",idRef," isSi ",isSi);
|
|
objectManager.RecordDelayedFixup(objectId, name, idRef);
|
|
}
|
|
else
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," RecordFixup objectId ",objectId," name ",name," idRef ",idRef," isSi ",isSi);
|
|
objectManager.RecordFixup(objectId, cache.memberInfos[Position(name)], idRef);
|
|
}
|
|
}
|
|
|
|
|
|
// Fills in the values for an object
|
|
internal void PopulateObjectMembers()
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," PopulateObjectMembers isSi ",isSi);
|
|
if (!isSi)
|
|
{
|
|
if (numberMembersSeen != cache.memberInfos.Length &&
|
|
majorVersion >= 1 && minorVersion >= 0 &&
|
|
!IsInteropNameSpace() &&
|
|
objectType != Converter.typeofHeader &&
|
|
!bfake)
|
|
{
|
|
throw new SerializationException(SoapUtil.GetResourceString("Serialization_WrongNumberOfMembers",
|
|
objectType, cache.memberInfos.Length, numberMembersSeen));
|
|
}
|
|
|
|
DumpPopulate(cache.memberInfos, memberData);
|
|
|
|
FormatterServices.PopulateObjectMembers(obj, cache.memberInfos, memberData);
|
|
numberMembersSeen = 0;
|
|
}
|
|
}
|
|
|
|
[Conditional("SER_LOGGING")]
|
|
private void DumpPopulate(MemberInfo[] memberInfos, Object[] memberData)
|
|
{
|
|
for (int i=0; i<memberInfos.Length; i++)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," PopulateObjectMembers ",memberInfos[i].Name," ",memberData[i]);
|
|
|
|
}
|
|
}
|
|
|
|
[Conditional("SER_LOGGING")]
|
|
private void DumpPopulateSi()
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," PopulateObjectMembers SetObjectData, ISerializable obj ");
|
|
SerializationInfoEnumerator siEnum = si.GetEnumerator();
|
|
for (int i=0; siEnum.MoveNext(); i++)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ",objectType," Populate Si ",siEnum.Name," ",siEnum.Value);
|
|
}
|
|
}
|
|
|
|
// Specifies the position in the memberNames array of this name
|
|
|
|
private int Position(String name)
|
|
{
|
|
InternalST.Soap( this, objectInfoId," Position ",lastPosition," ",name);
|
|
if (cache.memberNames[lastPosition].Equals(name))
|
|
{
|
|
return lastPosition;
|
|
}
|
|
else if ((++lastPosition < cache.memberNames.Length) && (cache.memberNames[lastPosition].Equals(name)))
|
|
{
|
|
return lastPosition;
|
|
}
|
|
else
|
|
{
|
|
// Search for name
|
|
InternalST.Soap( this, objectInfoId," Position miss search for name "+name);
|
|
for (int i=0; i<cache.memberNames.Length; i++)
|
|
{
|
|
if (cache.memberNames[i].Equals(name))
|
|
{
|
|
lastPosition = i;
|
|
return lastPosition;
|
|
}
|
|
}
|
|
|
|
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_Position"),objectType+" "+name));
|
|
}
|
|
}
|
|
|
|
|
|
private static ReadObjectInfo GetObjectInfo(SerObjectInfoInit serObjectInfoInit)
|
|
{
|
|
ReadObjectInfo objectInfo = null;
|
|
|
|
if (!serObjectInfoInit.oiPool.IsEmpty())
|
|
{
|
|
objectInfo = (ReadObjectInfo)serObjectInfoInit.oiPool.Pop();
|
|
objectInfo.InternalInit();
|
|
//InternalST.Soap( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo from pool");
|
|
}
|
|
else
|
|
{
|
|
objectInfo = new ReadObjectInfo();
|
|
objectInfo.objectInfoId = serObjectInfoInit.objectInfoIdCount++;
|
|
//InternalST.Soap( "GetObjectInfo",objectInfo.objectInfoId," GetObjectInfo new not from pool");
|
|
}
|
|
|
|
return objectInfo;
|
|
}
|
|
|
|
private static void PutObjectInfo(SerObjectInfoInit serObjectInfoInit, ReadObjectInfo objectInfo)
|
|
{
|
|
serObjectInfoInit.oiPool.Push(objectInfo);
|
|
//InternalST.Soap( "PutObjectInfo",objectInfo.objectInfoId," PutObjectInfo to pool");
|
|
}
|
|
|
|
internal bool IsInteropNameSpace()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsInteropNameSpace();
|
|
|
|
if (IsAttributeNameSpace() || IsCallElement())
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsCallElement()
|
|
{
|
|
// This should only return true when this object is being
|
|
// serialized first.
|
|
|
|
if ((objectType != Converter.typeofObject) &&
|
|
(Converter.typeofIMethodCallMessage.IsAssignableFrom(objectType) &&
|
|
!Converter.typeofIConstructionCallMessage.IsAssignableFrom(objectType)) ||
|
|
(objectType == Converter.typeofReturnMessage) ||
|
|
(objectType == Converter.typeofInternalSoapMessage))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
internal bool IsCustomXmlAttribute()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsCustomXmlAttribute();
|
|
|
|
if ((typeAttributeInfo != null) &&
|
|
((typeAttributeInfo.m_attributeType & SoapAttributeType.XmlAttribute) != 0))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsCustomXmlElement()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsCustomXmlElement();
|
|
|
|
if ((typeAttributeInfo != null) &&
|
|
((typeAttributeInfo.m_attributeType & SoapAttributeType.XmlElement) != 0))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsAttributeNameSpace()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsAttributeNameSpace();
|
|
|
|
if ((typeAttributeInfo != null) && (typeAttributeInfo.m_nameSpace != null))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsAttributeElementName()
|
|
{
|
|
if ((typeAttributeInfo != null) && (typeAttributeInfo.m_elementName != null))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
internal bool IsAttributeTypeName()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsAttributeTypeName();
|
|
|
|
if ((typeAttributeInfo != null) && (typeAttributeInfo.m_typeName != null))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
|
|
// Check for Interop type (SchemaType)
|
|
private SoapAttributeInfo GetTypeAttributeInfo()
|
|
{
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.GetTypeAttributeInfo();
|
|
|
|
SoapAttributeInfo attributeInfo = null;
|
|
attributeInfo = new SoapAttributeInfo();
|
|
|
|
Attr.ProcessTypeAttribute(objectType, attributeInfo);
|
|
|
|
attributeInfo.Dump("type "+objectType);
|
|
return attributeInfo;
|
|
}
|
|
|
|
|
|
// Specifies whether the embedded attribute is set for a member.
|
|
|
|
internal bool IsEmbeddedAttribute(String name)
|
|
{
|
|
InternalST.Soap( this,objectInfoId," ", objectType," IsEmbedded Entry ",name);
|
|
|
|
if (arrayElemObjectInfo != null)
|
|
return arrayElemObjectInfo.IsEmbeddedAttribute(name);
|
|
|
|
bool isEmbedded = false;
|
|
if (cache.memberAttributeInfos != null)
|
|
{
|
|
SoapAttributeInfo attributeInfo = cache.memberAttributeInfos[Position(name)];
|
|
isEmbedded = attributeInfo.IsEmbedded();
|
|
}
|
|
InternalST.Soap( this,objectInfoId," ", objectType," IsEmbedded Exit ",isEmbedded);
|
|
return isEmbedded;
|
|
}
|
|
}
|
|
|
|
internal sealed class SerObjectInfoCache
|
|
{
|
|
internal String fullTypeName = null;
|
|
internal String assemblyString = null;
|
|
internal MemberInfo[] memberInfos = null;
|
|
internal String[] memberNames = null;
|
|
internal Type[] memberTypes = null;
|
|
internal SoapAttributeInfo[] memberAttributeInfos = null;
|
|
}
|
|
|
|
internal sealed class SerObjectInfoInit
|
|
{
|
|
internal Hashtable seenBeforeTable = new Hashtable();
|
|
internal int objectInfoIdCount = 1;
|
|
internal SerStack oiPool = new SerStack("SerObjectInfo Pool");
|
|
}
|
|
|
|
internal sealed class Attr
|
|
{
|
|
|
|
internal static SoapAttributeInfo GetMemberAttributeInfo(MemberInfo memberInfo, String name, Type type)
|
|
{
|
|
|
|
SoapAttributeInfo attributeInfo = new SoapAttributeInfo();
|
|
ProcessTypeAttribute(type, attributeInfo);
|
|
ProcessMemberInfoAttribute(memberInfo, attributeInfo);
|
|
attributeInfo.Dump("memberInfo "+name);
|
|
return attributeInfo;
|
|
}
|
|
|
|
|
|
internal static void ProcessTypeAttribute(Type type, SoapAttributeInfo attributeInfo)
|
|
{
|
|
SoapTypeAttribute attr = (SoapTypeAttribute)
|
|
InternalRemotingServices.GetCachedSoapAttribute(type);
|
|
|
|
if (attr.Embedded)
|
|
attributeInfo.m_attributeType |= SoapAttributeType.Embedded;
|
|
|
|
String xmlName, xmlNamespace;
|
|
|
|
if (SoapServices.GetXmlElementForInteropType(type, out xmlName, out xmlNamespace))
|
|
{
|
|
attributeInfo.m_attributeType |= SoapAttributeType.XmlElement;
|
|
attributeInfo.m_elementName = xmlName;
|
|
attributeInfo.m_nameSpace = xmlNamespace;
|
|
}
|
|
|
|
if (SoapServices.GetXmlTypeForInteropType(type, out xmlName, out xmlNamespace))
|
|
{
|
|
attributeInfo.m_attributeType |= SoapAttributeType.XmlType;
|
|
attributeInfo.m_typeName = xmlName;
|
|
attributeInfo.m_typeNamespace = xmlNamespace;
|
|
}
|
|
|
|
} // ProcessTypeAttribute
|
|
|
|
|
|
internal static void ProcessMemberInfoAttribute(MemberInfo memberInfo, SoapAttributeInfo attributeInfo)
|
|
{
|
|
SoapAttribute attr = (SoapAttribute)
|
|
InternalRemotingServices.GetCachedSoapAttribute(memberInfo);
|
|
|
|
if (attr.Embedded)
|
|
attributeInfo.m_attributeType |= SoapAttributeType.Embedded;
|
|
|
|
// check for attribute and other junk
|
|
if (attr is SoapFieldAttribute)
|
|
{
|
|
SoapFieldAttribute fieldAttr = (SoapFieldAttribute)attr;
|
|
if (fieldAttr.UseAttribute)
|
|
{
|
|
attributeInfo.m_attributeType |= SoapAttributeType.XmlAttribute;
|
|
attributeInfo.m_elementName = fieldAttr.XmlElementName;
|
|
attributeInfo.m_nameSpace = fieldAttr.XmlNamespace;
|
|
}
|
|
else
|
|
{
|
|
if (fieldAttr.IsInteropXmlElement())
|
|
{
|
|
attributeInfo.m_attributeType |= SoapAttributeType.XmlElement;
|
|
attributeInfo.m_elementName = fieldAttr.XmlElementName;
|
|
attributeInfo.m_nameSpace = fieldAttr.XmlNamespace;
|
|
}
|
|
}
|
|
}
|
|
} // ProcessMemberInfoAttribute
|
|
|
|
}
|
|
}
|