1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/* Copyright (c) 2008-2011 - Eric P. Mangold
* Released under the terms of the MIT/X11 license - see LICENSE.txt */
using System;
using System.Collections;
using System.Collections.Generic;
namespace AMP
{
internal class Parameter
{
internal string name;
internal IAmpType type;
public Parameter(string name, IAmpType ampType)
{
this.name = name;
type = ampType;
}
}
public class Command
{
// The return value of Responder must be in the form of Object since we allow you
// to return a Msg (if responding synchronously) or a DeferredResponse (if you need to
// respond asyncronously).
public delegate Object Responder(Msg msg, Object state);
private static readonly log4net.ILog log = log4net.LogManager.GetLogger("AMP");
public bool RequiresAnswer { get; set; }
private string name;
internal List<Parameter> arguments;
internal List<Parameter> response;
internal Dictionary<System.Type, byte[]> errors = new Dictionary<System.Type, byte[]>();
public string Name
{
get { return name; }
}
public Command()
{
arguments = new List<Parameter>();
response = new List<Parameter>();
// These are the errors that every Command will know about, since they
// are part of the AMP protocol.
errors.Add(typeof(Error.UnknownRemoteError), Error.Codes.UNKNOWN_ERROR_CODE);
errors.Add(typeof(Error.UnhandledCommand), Error.Codes.UNHANDLED_ERROR_CODE);
RequiresAnswer = true; // default. changeable.
}
internal Command(List<Parameter> args)
: this()
{
arguments = args;
}
public Command(string name)
: this()
{
this.name = name;
}
public void AddArgument(string keyName, IAmpType type)
{
arguments.Add(new Parameter(keyName, type));
}
public void AddResponse(string keyName, IAmpType type)
{
response.Add(new Parameter(keyName, type));
}
public void AddError(System.Type errorClass, byte[] errorCode)
{
errors.Add(errorClass, errorCode);
}
internal Msg_Raw ToRawMessage(Msg typed_msg, MsgType msgType)
{
List<Parameter> paramList = (msgType == MsgType.REQUEST ? arguments : response);
var result = new Msg_Raw();
foreach (Parameter param in paramList)
{
if (!typed_msg.ContainsKey(param.name))
{
log.ErrorFormat("Command {0}: paramter \"{1}\" not found in msg!", name, param.name);
throw new Error.ParameterNotFound();
}
result.Add(param.name, param.type.ToAmpBytes(typed_msg[param.name]));
}
return result;
}
internal Msg ToTypedMessage(Msg_Raw raw_msg, MsgType msgType)
{
List<Parameter> paramList = (msgType == MsgType.REQUEST ? arguments : response);
var result = new Msg();
foreach (Parameter param in paramList)
{
if (!raw_msg.ContainsKey(param.name))
{
log.ErrorFormat("Command {0}: paramter \"{1}\" not found in msg!", name, param.name);
throw new Error.ParameterNotFound();
}
result.Add(param.name, param.type.FromAmpBytes(raw_msg[param.name]));
}
return result;
}
}
internal enum MsgType
{
REQUEST,
RESPONSE
}
}
|