/// <summary> /// Decode a serialized value /// </summary> object Decode(ProcedureSignature procedure, int i, Type type, ByteString value) { if (TypeUtils.IsAClassType(type)) { return(ObjectStore.Instance.GetInstance((ulong)ProtocolBuffers.ReadValue(value, typeof(ulong)))); } else if (TypeUtils.IsACollectionType(type)) { return(DecodeCollection(procedure, i, type, value)); } else if (ProtocolBuffers.IsAMessageType(type)) { return(ProtocolBuffers.ParseFrom(type, value)); } else if (TypeUtils.IsAnEnumType(type)) { // TODO: Assumes it's underlying type is int var enumValue = ProtocolBuffers.ReadValue(value, typeof(int)); if (!Enum.IsDefined(type, enumValue)) { throw new RPCException(procedure, "Failed to convert value " + enumValue + " to enumeration type " + type); } return(Enum.ToObject(type, enumValue)); } else { return(ProtocolBuffers.ReadValue(value, type)); } }
public object[] GetArguments(ProcedureSignature procedure, IList <Argument> arguments) { // Get list of supplied argument values and whether they were set var numParameters = procedure.Parameters.Count; var argumentValues = new object [numParameters]; var argumentSet = new BitVector32(0); foreach (var argument in arguments) { argumentValues [argument.Position] = argument.Value; argumentSet [1 << (int)argument.Position] = true; } var mask = BitVector32.CreateMask(); for (int i = 0; i < numParameters; i++) { var value = argumentValues [i]; var parameter = procedure.Parameters [i]; var type = parameter.Type; if (!argumentSet [mask]) { // If the argument is not set, set it to the default value if (!parameter.HasDefaultValue) { throw new RPCException(procedure, "Argument not specified for parameter " + parameter.Name + " in " + procedure.FullyQualifiedName + ". "); } argumentValues [i] = parameter.DefaultValue; } else if (value != null && !type.IsInstanceOfType(value)) { // Check the type of the non-null argument value throw new RPCException( procedure, "Incorrect argument type for parameter " + parameter.Name + " in " + procedure.FullyQualifiedName + ". " + "Expected an argument of type " + type + ", got " + value.GetType()); } else if (value == null && !TypeUtils.IsAClassType(type)) { // Check the type of the null argument value throw new RPCException( procedure, "Incorrect argument type for parameter " + parameter.Name + " in " + procedure.FullyQualifiedName + ". " + "Expected an argument of type " + type + ", got null"); } mask = BitVector32.CreateMask(mask); } return(argumentValues); }
/// <summary> /// Check the value returned by a procedure handler. /// </summary> static void CheckReturnValue(ProcedureSignature procedure, object returnValue) { // Check if the type of the return value is valid if (returnValue != null && !procedure.ReturnType.IsInstanceOfType(returnValue)) { throw new RPCException( procedure, "Incorrect value returned by " + procedure.FullyQualifiedName + ". " + "Expected a value of type " + procedure.ReturnType + ", got " + returnValue.GetType()); } else if (returnValue == null && !TypeUtils.IsAClassType(procedure.ReturnType)) { throw new RPCException( procedure, "Incorrect value returned by " + procedure.FullyQualifiedName + ". " + "Expected a value of type " + procedure.ReturnType + ", got null"); } }
/// <summary> /// Encodes the value returned by a procedure handler into a ByteString /// </summary> ByteString EncodeReturnValue(ProcedureSignature procedure, object returnValue) { // Check the return value is missing if (returnValue == null && !TypeUtils.IsAClassType(procedure.ReturnType)) { throw new RPCException( procedure, procedure.FullyQualifiedName + " returned null. " + "Expected an object of type " + procedure.ReturnType); } // Check if the return value is of a valid type if (!TypeUtils.IsAValidType(procedure.ReturnType)) { throw new RPCException( procedure, procedure.FullyQualifiedName + " returned an object of an invalid type. " + "Expected " + procedure.ReturnType + "; got " + returnValue.GetType()); } // Encode it as a ByteString return(Encode(procedure.ReturnType, returnValue)); }
/// <summary> /// Encode a value /// </summary> ByteString Encode(Type type, object value) { if (TypeUtils.IsAClassType(type)) { return(ProtocolBuffers.WriteValue(ObjectStore.Instance.AddInstance(value), typeof(ulong))); } else if (TypeUtils.IsACollectionType(type)) { return(EncodeCollection(type, value)); } else if (ProtocolBuffers.IsAMessageType(type)) { return(ProtocolBuffers.WriteMessage(value as IMessage)); } else if (TypeUtils.IsAnEnumType(type)) { // TODO: Assumes it's underlying type is int return(ProtocolBuffers.WriteValue((int)value, typeof(int))); } else { return(ProtocolBuffers.WriteValue(value, type)); } }