public static object ReadMethodResponse (BinaryElement elem, BinaryReader reader, bool hasHeaders, HeaderHandler headerHandler, IMethodCallMessage methodCallMessage, BinaryFormatter formatter)
{
if (elem != BinaryElement.MethodResponse) throw new SerializationException("Invalid format. Expected BinaryElement.MethodResponse, found " + elem);
MethodFlags flags = (MethodFlags) reader.ReadByte ();
ReturnTypeTag typeTag = (ReturnTypeTag) reader.ReadByte ();
bool hasContextInfo = (flags & MethodFlags.IncludesLogicalCallContext) > 0;
// FIXME: find a meaning for those 2 bytes
reader.ReadByte();
reader.ReadByte();
object returnValue = null;
object[] outArgs = null;
LogicalCallContext callContext = null;
Exception exception = null;
object[] extraProperties = null;
Header[] headers = null;
if ((typeTag & ReturnTypeTag.PrimitiveType) > 0)
{
Type type = BinaryCommon.GetTypeFromCode (reader.ReadByte());
returnValue = ObjectReader.ReadPrimitiveTypeValue (reader, type);
}
if ((flags & MethodFlags.PrimitiveArguments) > 0)
{
uint count = reader.ReadUInt32();
outArgs = new object[count];
for (int n=0; n<count; n++) {
Type type = BinaryCommon.GetTypeFromCode (reader.ReadByte());
outArgs[n] = ObjectReader.ReadPrimitiveTypeValue (reader, type);
}
}
if (hasContextInfo || (typeTag & ReturnTypeTag.ObjectType) > 0 ||
(typeTag & ReturnTypeTag.Exception) > 0 ||
(flags & MethodFlags.ArgumentsInSimpleArray) > 0 ||
(flags & MethodFlags.ArgumentsInMultiArray) > 0)
{
// There objects that need to be deserialized using an ObjectReader
ObjectReader objectReader = new ObjectReader (formatter);
object result;
objectReader.ReadObjectGraph (reader, hasHeaders, out result, out headers);
object[] msgInfo = (object[]) result;
if ((typeTag & ReturnTypeTag.Exception) > 0) {
exception = (Exception) msgInfo[0];
if (hasContextInfo) callContext = (LogicalCallContext)msgInfo[1];
}
else if ((flags & MethodFlags.NoArguments) > 0 || (flags & MethodFlags.PrimitiveArguments) > 0) {
int n = 0;
if ((typeTag & ReturnTypeTag.ObjectType) > 0) returnValue = msgInfo [n++];
if (hasContextInfo) callContext = (LogicalCallContext)msgInfo[n++];
if (n < msgInfo.Length) extraProperties = (object[]) msgInfo[n];
}
else if ((flags & MethodFlags.ArgumentsInSimpleArray) > 0) {
outArgs = msgInfo;
}
else {
int n = 0;
outArgs = (object[]) msgInfo[n++];
if ((typeTag & ReturnTypeTag.ObjectType) > 0) returnValue = msgInfo[n++];
if (hasContextInfo) callContext = (LogicalCallContext)msgInfo[n++];
if (n < msgInfo.Length) extraProperties = (object[]) msgInfo[n];
}
}
else {
reader.ReadByte (); // Reads the stream ender
}
if (headerHandler != null)
headerHandler(headers);
if (exception != null)
return new ReturnMessage (exception, methodCallMessage);
else
{
int argCount = (outArgs!=null) ? outArgs.Length : 0;
ReturnMessage result = new ReturnMessage (returnValue, outArgs, argCount, callContext, methodCallMessage);
if (extraProperties != null) {
foreach (DictionaryEntry entry in extraProperties)
result.Properties [(string)entry.Key] = entry.Value;
}
return result;
}
}