using System; using System.Collections.Generic; //using System.Dynamic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Nethereum.ABI.ABIDeserialisation { /// /// This is a replication (copy) of Newtonsoft ExpandoObjectConverter to allow for PCL compilaton /// public class ExpandoObjectConverter : JsonConverter { /// /// Gets a value indicating whether this can write JSON. /// /// /// true if this can write JSON; otherwise, false. /// public override bool CanWrite { get { return false; } } /// /// Determines whether this instance can convert the specified object type. /// /// Type of the object. /// /// true if this instance can convert the specified object type; otherwise, false. /// public override bool CanConvert(Type objectType) { return objectType == typeof(IDictionary); } /// /// Reads the JSON representation of the object. /// /// The to read from. /// Type of the object. /// The existing value of object being read. /// The calling serializer. /// The object value. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return ReadValue(reader); } /// /// Writes the JSON representation of the object. /// /// The to write to. /// The value. /// The calling serializer. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // can write is set to false } private bool IsPrimitiveToken(JsonToken token) { switch (token) { case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Undefined: case JsonToken.Null: case JsonToken.Date: case JsonToken.Bytes: return true; default: return false; } } private object ReadList(JsonReader reader) { IList list = new List(); while (reader.Read()) switch (reader.TokenType) { case JsonToken.Comment: break; default: var v = ReadValue(reader); list.Add(v); break; case JsonToken.EndArray: return list; } throw new Exception("Unexpected end."); } private object ReadObject(JsonReader reader) { IDictionary expandoObject = new Dictionary(); while (reader.Read()) switch (reader.TokenType) { case JsonToken.PropertyName: var propertyName = reader.Value.ToString(); if (!reader.Read()) throw new Exception("Unexpected end."); var v = ReadValue(reader); expandoObject[propertyName] = v; break; case JsonToken.Comment: break; case JsonToken.EndObject: return expandoObject; } throw new Exception("Unexpected end."); } private object ReadValue(JsonReader reader) { while (reader.TokenType == JsonToken.Comment) if (!reader.Read()) throw new Exception("Unexpected end."); switch (reader.TokenType) { case JsonToken.StartObject: return ReadObject(reader); case JsonToken.StartArray: return ReadList(reader); default: if (IsPrimitiveToken(reader.TokenType)) return reader.Value; throw new Exception("Unexpected token when converting ExpandoObject"); } } } // Converting ABI as JArray, JObject into ExpandoObject style // This is only available for ABI, not generic JObject/ExpandoObject conversion public class JObjectToExpandoConverter { public List> JObjectArray(JArray array) { var l = new List>(); foreach(JObject obj in array) l.Add(JObject(obj)); return l; } public List JArray(JArray array) { var l = new List(); foreach(JToken token in array) l.Add(JToken(token)); return l; } public IDictionary JObject(JObject obj) { var dic = new Dictionary(); foreach(var pair in obj) { dic[pair.Key] = JToken(pair.Value); } return dic; } public object JToken(JToken token) { if(token is JObject) return JObject((JObject)token); else if(token is JArray) return JArray((JArray)token); else if(token.Type == JTokenType.String) return token.Value(); else if(token.Type == JTokenType.Boolean) return token.Value(); else if(token.Type == JTokenType.Integer) return token.Value(); else throw new Exception("unexpected token type " + token.Type); } } }