using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Linq;
namespace Nethereum.Unity.RpcModel
{
/*
RPC Model simplified and downported to net351 from EdjCase.JsonRPC.Core
https://github.com/edjCase/JsonRpc/tree/master/src/EdjCase.JsonRpc.Core
The MIT License (MIT)
Copyright(c) 2015 Gekctek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
internal static class RpcResponseExtensions
{
///
/// Parses and returns the result of the rpc response as the type specified.
/// Otherwise throws a parsing exception
///
/// Type of object to parse the response as
/// Rpc response object
/// Returns the type's default value if the result is null. Otherwise throws parsing exception
/// Result of response as type specified
public static T GetResult(this RpcResponse response, bool returnDefaultIfNull = true, JsonSerializerSettings settings = null)
{
if (response.Result == null)
{
if(!returnDefaultIfNull && default(T) != null)
{
throw new Exception("Unable to convert the result (null) to type " + typeof(T));
}
return default(T);
}
try
{
if(settings == null)
{
return response.Result.ToObject();
}
else
{
JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
return response.Result.ToObject(jsonSerializer);
}
}
catch (Exception ex)
{
throw new Exception("Unable to convert the result to type " + typeof(T), ex);
}
}
}
[JsonObject]
internal class RpcResponse
{
[JsonConstructor]
protected RpcResponse()
{
JsonRpcVersion = "2.0";
}
/// Request id
protected RpcResponse(object id)
{
this.Id = id;
JsonRpcVersion = "2.0";
}
/// Request id
/// Request error
public RpcResponse(object id, RpcError error) : this(id)
{
this.Error = error;
}
/// Request id
/// Response result object
public RpcResponse(object id, JToken result) : this(id)
{
this.Result = result;
}
///
/// Request id (Required but nullable)
///
[JsonProperty("id", Required = Required.AllowNull)]
public object Id { get; private set; }
///
/// Rpc request version (Required)
///
[JsonProperty("jsonrpc", Required = Required.Always)]
public string JsonRpcVersion { get; private set; }
///
/// Reponse result object (Required)
///
[JsonProperty("result", Required = Required.Default)] //TODO somehow enforce this or an error, not both
public JToken Result { get; private set; }
///
/// Error from processing Rpc request (Required)
///
[JsonProperty("error", Required = Required.Default)]
public RpcError Error { get; private set; }
[JsonIgnore]
public bool HasError { get{ return this.Error != null;}}
}
[JsonObject]
internal class RpcRequest
{
[JsonConstructor]
private RpcRequest()
{
}
/// Request id
/// Target method name
/// List of parameters for the target method
public RpcRequest(object id, string method, params object[] parameterList)
{
this.Id = id;
this.JsonRpcVersion = "2.0";
this.Method = method;
this.RawParameters = parameterList;
}
/// Request id
/// Target method name
/// Map of parameter name to parameter value for the target method
public RpcRequest(object id, string method, Dictionary parameterMap)
{
this.Id = id;
this.JsonRpcVersion = "2.0";
this.Method = method;
this.RawParameters = parameterMap;
}
///
/// Request Id (Optional)
///
[JsonProperty("id")]
public object Id { get; private set; }
///
/// Version of the JsonRpc to be used (Required)
///
[JsonProperty("jsonrpc", Required = Required.Always)]
public string JsonRpcVersion { get; private set; }
///
/// Name of the target method (Required)
///
[JsonProperty("method", Required = Required.Always)]
public string Method { get; private set; }
///
/// Parameters to invoke the method with (Optional)
///
[JsonProperty("params")]
[JsonConverter(typeof(RpcParametersJsonConverter))]
public object RawParameters { get; private set; }
}
///
/// Json converter for Rpc parameters
///
internal class RpcParametersJsonConverter : JsonConverter
{
///
/// Writes the value of the parameters to json format
///
/// Json writer
/// Value to be converted to json format
/// Json serializer
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
///
/// Read the json format and return the correct object type/value for it
///
/// Json reader
/// Type of property being set
/// The current value of the property being set
/// Json serializer
/// The object value of the converted json value
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.StartObject:
try
{
JObject jObject = JObject.Load(reader);
return jObject.ToObject>();
}
catch (Exception)
{
throw new Exception("Request parameters can only be an associative array, list or null.");
}
case JsonToken.StartArray:
return JArray.Load(reader).ToObject