// Writes the members of an object
private void WriteMembers(NameInfo memberNameInfo,
NameInfo memberTypeNameInfo,
Object memberData,
WriteObjectInfo objectInfo,
NameInfo typeNameInfo,
WriteObjectInfo memberObjectInfo,
bool isAttribute)
{
InternalST.Soap( this, "WriteMembers Entry memberType: ",memberTypeNameInfo.NIname," memberName: ",memberNameInfo.NIname," data: ",memberData," objectId: ",objectInfo.objectId, " Container object ",objectInfo.obj, " isAttribute ", isAttribute);
Type memberType = memberNameInfo.NItype;
// Types are transmitted for a member as follows:
// The member is of type object
// The member object of type is ISerializable and
// Soap - the member is a non-primitive value type, or it is a primitive value type which needs types (TimeSpan, DateTime)
// TimeSpan and DateTime are transmitted as UInt64 to keep their precision.
// Binary - Types always transmitted.
if ((memberType == Converter.typeofObject) ||
(memberType.IsValueType && objectInfo.isSi &&
Converter.IsSiTransmitType(memberTypeNameInfo.NIprimitiveTypeEnum)))
{
memberTypeNameInfo.NItransmitTypeOnMember = true;
memberNameInfo.NItransmitTypeOnMember = true;
}
if (CheckTypeFormat(formatterEnums.FEtypeFormat, FormatterTypeStyle.TypesAlways))
{
memberTypeNameInfo.NItransmitTypeOnObject = true;
memberNameInfo.NItransmitTypeOnObject = true;
memberNameInfo.NIisParentTypeOnObject = true;
}
if (CheckForNull(objectInfo, memberNameInfo, memberTypeNameInfo, memberData))
{
return;
}
Object outObj = memberData;
Type outType = null;
// If member type does not equal data type, transmit type on object.
if (memberTypeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Invalid)
{
if (RemotingServices.IsTransparentProxy(outObj))
outType = Converter.typeofMarshalByRefObject;
else
{
outType = GetType(outObj);
if (memberType != outType)
{
memberTypeNameInfo.NItransmitTypeOnMember = true;
memberNameInfo.NItransmitTypeOnMember = true;
}
}
}
if (memberType == Converter.typeofObject)
{
memberType = GetType(memberData);
if (memberObjectInfo == null)
TypeToNameInfo(memberType, memberTypeNameInfo);
else
TypeToNameInfo(memberObjectInfo, memberTypeNameInfo);
InternalST.Soap( this, "WriteMembers memberType Object, actual memberType ",memberType);
}
if (memberObjectInfo != null && memberObjectInfo.isArray)
{
// Array
InternalST.Soap( this, "WriteMembers IsArray");
long arrayId = 0;
if (!(objectInfo.IsEmbeddedAttribute(memberNameInfo.NIname)|| IsEmbeddedAttribute(memberType)))
{
arrayId = Schedule(outObj, outType, memberObjectInfo);
}
if (arrayId > 0)
{
// Array as object
InternalST.Soap( this, "WriteMembers Schedule 3");
memberNameInfo.NIobjectId = arrayId;
WriteObjectRef(memberNameInfo, arrayId);
}
else
{
// Nested Array
serWriter.WriteMemberNested(memberNameInfo);
memberObjectInfo.objectId = arrayId;
memberNameInfo.NIobjectId = arrayId;
memberNameInfo.NIisNestedObject = true;
WriteArray(memberObjectInfo, memberNameInfo, memberObjectInfo);
}
InternalST.Soap( this, "WriteMembers Array Exit ");
return;
}
if (!WriteKnownValueClass(memberNameInfo, memberTypeNameInfo, memberData, isAttribute))
{
InternalST.Soap( this, "WriteMembers Object ",memberData);
// In soap an enum is written out as a string
if (memberTypeNameInfo.NItype.IsEnum)
WriteEnum(memberNameInfo, memberTypeNameInfo, memberData, isAttribute);
else
{
if (isAttribute)
{
// XmlAttribute must be a primitive type or string
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_NonPrimitive_XmlAttribute"), memberNameInfo.NIname));
}
// Value or NO_ID, need to explicitly check for IsValue because a top level
// value class has an objectId of 1
if ((memberType.IsValueType) || objectInfo.IsEmbeddedAttribute(memberNameInfo.NIname) || IsEmbeddedAttribute(outType))
{
InternalST.Soap( this, "WriteMembers Value Type or NO_ID parameter");
serWriter.WriteMemberNested(memberNameInfo);
memberObjectInfo.objectId = -1;
NameInfo newTypeNameInfo = TypeToNameInfo(memberObjectInfo);
newTypeNameInfo.NIobjectId = -1;
memberNameInfo.NIisNestedObject = true;
if (objectInfo.isSi)
{
memberTypeNameInfo.NItransmitTypeOnMember = true;
memberNameInfo.NItransmitTypeOnMember = true;
}
Write( memberObjectInfo, memberNameInfo, newTypeNameInfo);
PutNameInfo(newTypeNameInfo);
memberObjectInfo.ObjectEnd();
}
else
{
InternalST.Soap( this, "WriteMembers Schedule 4");
long memberObjectId = 0;
memberObjectId = Schedule(outObj, outType, memberObjectInfo);
if (memberObjectId < 0)
{
// Nested object
InternalST.Soap( this, "WriteMembers Nesting");
serWriter.WriteMemberNested(memberNameInfo);
memberObjectInfo.objectId = -1;
NameInfo newTypeNameInfo = TypeToNameInfo(memberObjectInfo);
newTypeNameInfo.NIobjectId = -1;
memberNameInfo.NIisNestedObject = true;
Write(memberObjectInfo, memberNameInfo, newTypeNameInfo);
PutNameInfo(newTypeNameInfo);
memberObjectInfo.ObjectEnd();
}
else
{
// Object reference
memberNameInfo.NIobjectId = memberObjectId;
WriteObjectRef(memberNameInfo, memberObjectId);
}
}
}
}
InternalST.Soap( this, "WriteMembers Exit ");
}