528 lines
28 KiB
C#
528 lines
28 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Dispatcher
|
||
|
{
|
||
|
using System.Collections;
|
||
|
using System.ServiceModel.Channels;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Description;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Diagnostics;
|
||
|
using System.Runtime.Serialization;
|
||
|
using System.Reflection;
|
||
|
using System.Xml;
|
||
|
using System.Xml.Serialization;
|
||
|
using System.ServiceModel.Diagnostics;
|
||
|
using System.IO;
|
||
|
using System.Xml.Schema;
|
||
|
|
||
|
class XmlSerializerOperationFormatter : OperationFormatter
|
||
|
{
|
||
|
const string soap11Encoding = "http://schemas.xmlsoap.org/soap/encoding/";
|
||
|
const string soap12Encoding = "http://www.w3.org/2003/05/soap-encoding";
|
||
|
|
||
|
bool isEncoded;
|
||
|
|
||
|
MessageInfo requestMessageInfo;
|
||
|
MessageInfo replyMessageInfo;
|
||
|
|
||
|
public XmlSerializerOperationFormatter(OperationDescription description, XmlSerializerFormatAttribute xmlSerializerFormatAttribute,
|
||
|
MessageInfo requestMessageInfo, MessageInfo replyMessageInfo) :
|
||
|
base(description, xmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc, xmlSerializerFormatAttribute.IsEncoded)
|
||
|
{
|
||
|
if (xmlSerializerFormatAttribute.IsEncoded && xmlSerializerFormatAttribute.Style != OperationFormatStyle.Rpc)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDocEncodedNotSupported, description.Name)));
|
||
|
this.isEncoded = xmlSerializerFormatAttribute.IsEncoded;
|
||
|
|
||
|
this.requestMessageInfo = requestMessageInfo;
|
||
|
this.replyMessageInfo = replyMessageInfo;
|
||
|
}
|
||
|
|
||
|
protected override void AddHeadersToMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
|
||
|
{
|
||
|
XmlSerializer serializer;
|
||
|
MessageHeaderDescriptionTable headerDescriptionTable;
|
||
|
MessageHeaderDescription unknownHeaderDescription;
|
||
|
bool mustUnderstand;
|
||
|
bool relay;
|
||
|
string actor;
|
||
|
try
|
||
|
{
|
||
|
if (isRequest)
|
||
|
{
|
||
|
serializer = requestMessageInfo.HeaderSerializer;
|
||
|
headerDescriptionTable = requestMessageInfo.HeaderDescriptionTable;
|
||
|
unknownHeaderDescription = requestMessageInfo.UnknownHeaderDescription;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serializer = replyMessageInfo.HeaderSerializer;
|
||
|
headerDescriptionTable = replyMessageInfo.HeaderDescriptionTable;
|
||
|
unknownHeaderDescription = replyMessageInfo.UnknownHeaderDescription;
|
||
|
}
|
||
|
if (serializer != null)
|
||
|
{
|
||
|
object[] headerValues = new object[headerDescriptionTable.Count];
|
||
|
MessageHeaderOfTHelper messageHeaderOfTHelper = null;
|
||
|
int headerIndex = 0;
|
||
|
|
||
|
foreach (MessageHeaderDescription headerDescription in messageDescription.Headers)
|
||
|
{
|
||
|
object parameterValue = parameters[headerDescription.Index];
|
||
|
if (!headerDescription.IsUnknownHeaderCollection)
|
||
|
{
|
||
|
if (headerDescription.TypedHeader)
|
||
|
{
|
||
|
if (messageHeaderOfTHelper == null)
|
||
|
messageHeaderOfTHelper = new MessageHeaderOfTHelper(parameters.Length);
|
||
|
headerValues[headerIndex++] = messageHeaderOfTHelper.GetContentAndSaveHeaderAttributes(parameters[headerDescription.Index], headerDescription);
|
||
|
}
|
||
|
else
|
||
|
headerValues[headerIndex++] = parameterValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MemoryStream memoryStream = new MemoryStream();
|
||
|
XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream);
|
||
|
bufferWriter.WriteStartElement("root");
|
||
|
serializer.Serialize(bufferWriter, headerValues, null, isEncoded ? GetEncoding(message.Version.Envelope) : null);
|
||
|
bufferWriter.WriteEndElement();
|
||
|
bufferWriter.Flush();
|
||
|
XmlDocument doc = new XmlDocument();
|
||
|
memoryStream.Position = 0;
|
||
|
doc.Load(memoryStream);
|
||
|
//doc.Save(Console.Out);
|
||
|
foreach (XmlElement element in doc.DocumentElement.ChildNodes)
|
||
|
{
|
||
|
MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(element.LocalName, element.NamespaceURI);
|
||
|
if (matchingHeaderDescription == null)
|
||
|
message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
|
||
|
false/*mustUnderstand*/, null/*actor*/, false/*relay*/, element));
|
||
|
else
|
||
|
{
|
||
|
if (matchingHeaderDescription.TypedHeader)
|
||
|
messageHeaderOfTHelper.GetHeaderAttributes(matchingHeaderDescription, out mustUnderstand, out relay, out actor);
|
||
|
else
|
||
|
{
|
||
|
mustUnderstand = matchingHeaderDescription.MustUnderstand;
|
||
|
relay = matchingHeaderDescription.Relay;
|
||
|
actor = matchingHeaderDescription.Actor;
|
||
|
}
|
||
|
message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
|
||
|
mustUnderstand, actor, relay, element));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (unknownHeaderDescription != null && parameters[unknownHeaderDescription.Index] != null)
|
||
|
{
|
||
|
foreach (object unknownHeader in (IEnumerable)parameters[unknownHeaderDescription.Index])
|
||
|
{
|
||
|
|
||
|
XmlElement element = (XmlElement)GetContentOfMessageHeaderOfT(unknownHeaderDescription, unknownHeader, out mustUnderstand, out relay, out actor);
|
||
|
if (element != null)
|
||
|
message.Headers.Add(new XmlElementMessageHeader(this, message.Version, element.LocalName, element.NamespaceURI,
|
||
|
mustUnderstand, actor, relay, element));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
catch (InvalidOperationException e)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
|
||
|
SR.GetString(SR.SFxErrorSerializingHeader, messageDescription.MessageName, e.Message), e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void GetHeadersFromMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
XmlSerializer serializer;
|
||
|
MessageHeaderDescriptionTable headerDescriptionTable;
|
||
|
MessageHeaderDescription unknownHeaderDescription;
|
||
|
if (isRequest)
|
||
|
{
|
||
|
serializer = requestMessageInfo.HeaderSerializer;
|
||
|
headerDescriptionTable = requestMessageInfo.HeaderDescriptionTable;
|
||
|
unknownHeaderDescription = requestMessageInfo.UnknownHeaderDescription;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
serializer = replyMessageInfo.HeaderSerializer;
|
||
|
headerDescriptionTable = replyMessageInfo.HeaderDescriptionTable;
|
||
|
unknownHeaderDescription = replyMessageInfo.UnknownHeaderDescription;
|
||
|
}
|
||
|
MessageHeaders headers = message.Headers;
|
||
|
ArrayList unknownHeaders = null;
|
||
|
XmlDocument xmlDoc = null;
|
||
|
if (unknownHeaderDescription != null)
|
||
|
{
|
||
|
unknownHeaders = new ArrayList();
|
||
|
xmlDoc = new XmlDocument();
|
||
|
}
|
||
|
if (serializer == null)
|
||
|
{
|
||
|
if (unknownHeaderDescription != null)
|
||
|
{
|
||
|
for (int headerIndex = 0; headerIndex < headers.Count; headerIndex++)
|
||
|
AddUnknownHeader(unknownHeaderDescription, unknownHeaders, xmlDoc, null/*bufferWriter*/, headers[headerIndex], headers.GetReaderAtHeader(headerIndex));
|
||
|
parameters[unknownHeaderDescription.Index] = unknownHeaders.ToArray(unknownHeaderDescription.TypedHeader ? typeof(MessageHeader<XmlElement>) : typeof(XmlElement));
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
MemoryStream memoryStream = new MemoryStream();
|
||
|
XmlDictionaryWriter bufferWriter = XmlDictionaryWriter.CreateTextWriter(memoryStream);
|
||
|
message.WriteStartEnvelope(bufferWriter);
|
||
|
message.WriteStartHeaders(bufferWriter);
|
||
|
MessageHeaderOfTHelper messageHeaderOfTHelper = null;
|
||
|
for (int headerIndex = 0; headerIndex < headers.Count; headerIndex++)
|
||
|
{
|
||
|
MessageHeaderInfo header = headers[headerIndex];
|
||
|
XmlDictionaryReader headerReader = headers.GetReaderAtHeader(headerIndex);
|
||
|
MessageHeaderDescription matchingHeaderDescription = headerDescriptionTable.Get(header.Name, header.Namespace);
|
||
|
if (matchingHeaderDescription != null)
|
||
|
{
|
||
|
if (header.MustUnderstand)
|
||
|
headers.UnderstoodHeaders.Add(header);
|
||
|
if (matchingHeaderDescription.TypedHeader)
|
||
|
{
|
||
|
if (messageHeaderOfTHelper == null)
|
||
|
messageHeaderOfTHelper = new MessageHeaderOfTHelper(parameters.Length);
|
||
|
messageHeaderOfTHelper.SetHeaderAttributes(matchingHeaderDescription, header.MustUnderstand, header.Relay, header.Actor);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
if (matchingHeaderDescription == null && unknownHeaderDescription != null)
|
||
|
AddUnknownHeader(unknownHeaderDescription, unknownHeaders, xmlDoc, bufferWriter, header, headerReader);
|
||
|
else
|
||
|
bufferWriter.WriteNode(headerReader, false);
|
||
|
headerReader.Close();
|
||
|
}
|
||
|
bufferWriter.WriteEndElement();
|
||
|
bufferWriter.WriteEndElement();
|
||
|
bufferWriter.Flush();
|
||
|
|
||
|
/*
|
||
|
XmlDocument doc = new XmlDocument();
|
||
|
memoryStream.Position = 0;
|
||
|
doc.Load(memoryStream);
|
||
|
doc.Save(Console.Out);
|
||
|
*/
|
||
|
|
||
|
memoryStream.Position = 0;
|
||
|
XmlDictionaryReader bufferReader = XmlDictionaryReader.CreateTextReader(memoryStream.GetBuffer(), 0, (int)memoryStream.Length, XmlDictionaryReaderQuotas.Max);
|
||
|
|
||
|
bufferReader.ReadStartElement();
|
||
|
bufferReader.MoveToContent();
|
||
|
if (!bufferReader.IsEmptyElement)
|
||
|
{
|
||
|
bufferReader.ReadStartElement();
|
||
|
object[] headerValues = (object[])serializer.Deserialize(bufferReader, isEncoded ? GetEncoding(message.Version.Envelope) : null);
|
||
|
int headerIndex = 0;
|
||
|
foreach (MessageHeaderDescription headerDescription in messageDescription.Headers)
|
||
|
{
|
||
|
if (!headerDescription.IsUnknownHeaderCollection)
|
||
|
{
|
||
|
object parameterValue = headerValues[headerIndex++];
|
||
|
if (headerDescription.TypedHeader && parameterValue != null)
|
||
|
parameterValue = messageHeaderOfTHelper.CreateMessageHeader(headerDescription, parameterValue);
|
||
|
parameters[headerDescription.Index] = parameterValue;
|
||
|
}
|
||
|
}
|
||
|
bufferReader.Close();
|
||
|
}
|
||
|
if (unknownHeaderDescription != null)
|
||
|
parameters[unknownHeaderDescription.Index] = unknownHeaders.ToArray(unknownHeaderDescription.TypedHeader ? typeof(MessageHeader<XmlElement>) : typeof(XmlElement));
|
||
|
}
|
||
|
catch (InvalidOperationException e)
|
||
|
{
|
||
|
// all exceptions from XmlSerializer get wrapped in InvalidOperationException,
|
||
|
// so we must be conservative and never turn this into a fault
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
|
||
|
SR.GetString(SR.SFxErrorDeserializingHeader, messageDescription.MessageName), e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void AddUnknownHeader(MessageHeaderDescription unknownHeaderDescription, ArrayList unknownHeaders, XmlDocument xmlDoc, XmlDictionaryWriter bufferWriter, MessageHeaderInfo header, XmlDictionaryReader headerReader)
|
||
|
{
|
||
|
object unknownHeader = xmlDoc.ReadNode(headerReader);
|
||
|
if (bufferWriter != null)
|
||
|
((XmlElement)unknownHeader).WriteTo(bufferWriter);
|
||
|
if (unknownHeader != null && unknownHeaderDescription.TypedHeader)
|
||
|
unknownHeader = TypedHeaderManager.Create(unknownHeaderDescription.Type, unknownHeader, header.MustUnderstand, header.Relay, header.Actor);
|
||
|
|
||
|
unknownHeaders.Add(unknownHeader);
|
||
|
}
|
||
|
|
||
|
protected override void WriteBodyAttributes(XmlDictionaryWriter writer, MessageVersion version)
|
||
|
{
|
||
|
if (isEncoded && version.Envelope == EnvelopeVersion.Soap11)
|
||
|
{
|
||
|
string encoding = GetEncoding(version.Envelope);
|
||
|
writer.WriteAttributeString("encodingStyle", version.Envelope.Namespace, encoding);
|
||
|
}
|
||
|
writer.WriteAttributeString("xmlns", "xsi", null, XmlSchema.InstanceNamespace);
|
||
|
writer.WriteAttributeString("xmlns", "xsd", null, XmlSchema.Namespace);
|
||
|
}
|
||
|
|
||
|
protected override void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, string action, MessageDescription messageDescription, object returnValue, object[] parameters, bool isRequest)
|
||
|
{
|
||
|
if (writer == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
|
||
|
if (parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
|
||
|
try
|
||
|
{
|
||
|
MessageInfo messageInfo;
|
||
|
if (isRequest)
|
||
|
messageInfo = requestMessageInfo;
|
||
|
else
|
||
|
messageInfo = replyMessageInfo;
|
||
|
if (messageInfo.RpcEncodedTypedMessageBodyParts == null)
|
||
|
{
|
||
|
SerializeBody(writer, version, messageInfo.BodySerializer, messageDescription.Body.ReturnValue, messageDescription.Body.Parts, returnValue, parameters);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
object[] bodyPartValues = new object[messageInfo.RpcEncodedTypedMessageBodyParts.Count];
|
||
|
object bodyObject = parameters[messageDescription.Body.Parts[0].Index];
|
||
|
if (bodyObject == null)
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxBodyCannotBeNull, messageDescription.MessageName)));
|
||
|
int i = 0;
|
||
|
foreach (MessagePartDescription bodyPart in messageInfo.RpcEncodedTypedMessageBodyParts)
|
||
|
{
|
||
|
MemberInfo member = bodyPart.MemberInfo;
|
||
|
FieldInfo field = member as FieldInfo;
|
||
|
if (field != null)
|
||
|
bodyPartValues[i++] = field.GetValue(bodyObject);
|
||
|
else
|
||
|
{
|
||
|
PropertyInfo property = member as PropertyInfo;
|
||
|
if (property != null)
|
||
|
bodyPartValues[i++] = property.GetValue(bodyObject, null);
|
||
|
}
|
||
|
}
|
||
|
SerializeBody(writer, version, messageInfo.BodySerializer, null/*returnPart*/, messageInfo.RpcEncodedTypedMessageBodyParts, null/*returnValue*/, bodyPartValues);
|
||
|
}
|
||
|
catch (InvalidOperationException e)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
|
||
|
SR.GetString(SR.SFxErrorSerializingBody, messageDescription.MessageName, e.Message), e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, object returnValue, object[] parameters)
|
||
|
{
|
||
|
if (serializer == null)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
bool hasReturnValue = IsValidReturnValue(returnPart);
|
||
|
object[] bodyParameters = new object[bodyParts.Count + (hasReturnValue ? 1 : 0)];
|
||
|
int paramIndex = 0;
|
||
|
|
||
|
if (hasReturnValue)
|
||
|
bodyParameters[paramIndex++] = returnValue;
|
||
|
|
||
|
for (int i = 0; i < bodyParts.Count; i++)
|
||
|
bodyParameters[paramIndex++] = parameters[bodyParts[i].Index];
|
||
|
|
||
|
string encoding = isEncoded ? GetEncoding(version.Envelope) : null;
|
||
|
serializer.Serialize(writer, bodyParameters, null, encoding);
|
||
|
}
|
||
|
|
||
|
|
||
|
protected override object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, string action, MessageDescription messageDescription, object[] parameters, bool isRequest)
|
||
|
{
|
||
|
MessageInfo messageInfo;
|
||
|
if (isRequest)
|
||
|
messageInfo = requestMessageInfo;
|
||
|
else
|
||
|
messageInfo = replyMessageInfo;
|
||
|
if (messageInfo.RpcEncodedTypedMessageBodyParts == null)
|
||
|
return DeserializeBody(reader, version, messageInfo.BodySerializer, messageDescription.Body.ReturnValue, messageDescription.Body.Parts, parameters, isRequest);
|
||
|
|
||
|
object[] bodyPartValues = new object[messageInfo.RpcEncodedTypedMessageBodyParts.Count];
|
||
|
DeserializeBody(reader, version, messageInfo.BodySerializer, null/*returnPart*/, messageInfo.RpcEncodedTypedMessageBodyParts, bodyPartValues, isRequest);
|
||
|
object bodyObject = Activator.CreateInstance(messageDescription.Body.Parts[0].Type);
|
||
|
int i = 0;
|
||
|
foreach (MessagePartDescription bodyPart in messageInfo.RpcEncodedTypedMessageBodyParts)
|
||
|
{
|
||
|
MemberInfo member = bodyPart.MemberInfo;
|
||
|
FieldInfo field = member as FieldInfo;
|
||
|
if (field != null)
|
||
|
field.SetValue(bodyObject, bodyPartValues[i++]);
|
||
|
else
|
||
|
{
|
||
|
PropertyInfo property = member as PropertyInfo;
|
||
|
if (property != null)
|
||
|
property.SetValue(bodyObject, bodyPartValues[i++], null);
|
||
|
}
|
||
|
}
|
||
|
parameters[messageDescription.Body.Parts[0].Index] = bodyObject;
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, XmlSerializer serializer, MessagePartDescription returnPart, MessagePartDescriptionCollection bodyParts, object[] parameters, bool isRequest)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
if (reader == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("reader"));
|
||
|
if (parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
|
||
|
object returnValue = null;
|
||
|
if (serializer == null)
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
if (reader.NodeType == XmlNodeType.EndElement)
|
||
|
return null;
|
||
|
|
||
|
object[] bodyParameters = (object[])serializer.Deserialize(reader, isEncoded ? GetEncoding(version.Envelope) : null);
|
||
|
|
||
|
int paramIndex = 0;
|
||
|
if (IsValidReturnValue(returnPart))
|
||
|
returnValue = bodyParameters[paramIndex++];
|
||
|
|
||
|
for (int i = 0; i < bodyParts.Count; i++)
|
||
|
parameters[bodyParts[i].Index] = bodyParameters[paramIndex++];
|
||
|
return returnValue;
|
||
|
}
|
||
|
catch (InvalidOperationException e)
|
||
|
{
|
||
|
// all exceptions from XmlSerializer get wrapped in InvalidOperationException,
|
||
|
// so we must be conservative and never turn this into a fault
|
||
|
string resourceKey = isRequest ? SR.SFxErrorDeserializingRequestBody : SR.SFxErrorDeserializingReplyBody;
|
||
|
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
|
||
|
SR.GetString(resourceKey, OperationName), e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static string GetEncoding(EnvelopeVersion version)
|
||
|
{
|
||
|
if (version == EnvelopeVersion.Soap11)
|
||
|
{
|
||
|
return soap11Encoding;
|
||
|
}
|
||
|
else if (version == EnvelopeVersion.Soap12)
|
||
|
{
|
||
|
return soap12Encoding;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("version",
|
||
|
SR.GetString(SR.EnvelopeVersionNotSupported, version));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal abstract class MessageInfo
|
||
|
{
|
||
|
internal abstract XmlSerializer BodySerializer { get; }
|
||
|
internal abstract XmlSerializer HeaderSerializer { get; }
|
||
|
internal abstract MessageHeaderDescriptionTable HeaderDescriptionTable { get; }
|
||
|
internal abstract MessageHeaderDescription UnknownHeaderDescription { get; }
|
||
|
internal abstract MessagePartDescriptionCollection RpcEncodedTypedMessageBodyParts { get; }
|
||
|
}
|
||
|
|
||
|
class MessageHeaderOfTHelper
|
||
|
{
|
||
|
object[] attributes;
|
||
|
internal MessageHeaderOfTHelper(int parameterCount)
|
||
|
{
|
||
|
attributes = new object[parameterCount];
|
||
|
}
|
||
|
internal object GetContentAndSaveHeaderAttributes(object parameterValue, MessageHeaderDescription headerDescription)
|
||
|
{
|
||
|
if (parameterValue == null)
|
||
|
return null;
|
||
|
bool mustUnderstand;
|
||
|
bool relay;
|
||
|
string actor;
|
||
|
if (headerDescription.Multiple)
|
||
|
{
|
||
|
object[] messageHeaderOfTArray = (object[])parameterValue;
|
||
|
MessageHeader<object>[] messageHeaderOfTAttributes = new MessageHeader<object>[messageHeaderOfTArray.Length];
|
||
|
Array tArray = Array.CreateInstance(headerDescription.Type, messageHeaderOfTArray.Length);
|
||
|
for (int i = 0; i < tArray.Length; i++)
|
||
|
{
|
||
|
tArray.SetValue(GetContentOfMessageHeaderOfT(headerDescription, messageHeaderOfTArray[i], out mustUnderstand, out relay, out actor), i);
|
||
|
messageHeaderOfTAttributes[i] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
|
||
|
}
|
||
|
attributes[headerDescription.Index] = messageHeaderOfTAttributes;
|
||
|
return tArray;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
object content = GetContentOfMessageHeaderOfT(headerDescription, parameterValue, out mustUnderstand, out relay, out actor);
|
||
|
attributes[headerDescription.Index] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
|
||
|
return content;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
internal void GetHeaderAttributes(MessageHeaderDescription headerDescription, out bool mustUnderstand, out bool relay, out string actor)
|
||
|
{
|
||
|
MessageHeader<object> matchingMessageHeaderOfTAttribute = null;
|
||
|
if (headerDescription.Multiple)
|
||
|
{
|
||
|
MessageHeader<object>[] messageHeaderOfTAttributes = (MessageHeader<object>[])attributes[headerDescription.Index];
|
||
|
for (int i = 0; i < messageHeaderOfTAttributes.Length; i++)
|
||
|
{
|
||
|
if (messageHeaderOfTAttributes[i] != null)
|
||
|
{
|
||
|
matchingMessageHeaderOfTAttribute = messageHeaderOfTAttributes[i];
|
||
|
messageHeaderOfTAttributes[i] = null;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
//assert(matchingMessageHeaderOfTAttribute != null);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
matchingMessageHeaderOfTAttribute = (MessageHeader<object>)attributes[headerDescription.Index];
|
||
|
mustUnderstand = matchingMessageHeaderOfTAttribute.MustUnderstand;
|
||
|
relay = matchingMessageHeaderOfTAttribute.Relay;
|
||
|
actor = matchingMessageHeaderOfTAttribute.Actor;
|
||
|
}
|
||
|
|
||
|
internal void SetHeaderAttributes(MessageHeaderDescription headerDescription, bool mustUnderstand, bool relay, string actor)
|
||
|
{
|
||
|
if (headerDescription.Multiple)
|
||
|
{
|
||
|
if (attributes[headerDescription.Index] == null)
|
||
|
attributes[headerDescription.Index] = new List<MessageHeader<object>>();
|
||
|
((List<MessageHeader<object>>)attributes[headerDescription.Index]).Add(new MessageHeader<object>(null, mustUnderstand, actor, relay));
|
||
|
}
|
||
|
else
|
||
|
attributes[headerDescription.Index] = new MessageHeader<object>(null, mustUnderstand, actor, relay);
|
||
|
|
||
|
}
|
||
|
internal object CreateMessageHeader(MessageHeaderDescription headerDescription, object headerValue)
|
||
|
{
|
||
|
if (headerDescription.Multiple)
|
||
|
{
|
||
|
IList<MessageHeader<object>> messageHeaderOfTAttributes = (IList<MessageHeader<object>>)attributes[headerDescription.Index];
|
||
|
object[] messageHeaderOfTArray = (object[])Array.CreateInstance(TypedHeaderManager.GetMessageHeaderType(headerDescription.Type), messageHeaderOfTAttributes.Count);
|
||
|
Array headerValues = (Array)headerValue;
|
||
|
for (int i = 0; i < messageHeaderOfTArray.Length; i++)
|
||
|
{
|
||
|
MessageHeader<object> messageHeaderOfTAttribute = messageHeaderOfTAttributes[i];
|
||
|
messageHeaderOfTArray[i] = TypedHeaderManager.Create(headerDescription.Type, headerValues.GetValue(i),
|
||
|
messageHeaderOfTAttribute.MustUnderstand, messageHeaderOfTAttribute.Relay, messageHeaderOfTAttribute.Actor);
|
||
|
}
|
||
|
return messageHeaderOfTArray;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MessageHeader<object> messageHeaderOfTAttribute = (MessageHeader<object>)attributes[headerDescription.Index];
|
||
|
return TypedHeaderManager.Create(headerDescription.Type, headerValue,
|
||
|
messageHeaderOfTAttribute.MustUnderstand, messageHeaderOfTAttribute.Relay, messageHeaderOfTAttribute.Actor);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|