using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace POSV.Utils
{
public class DynamicJson : DynamicObject
{
private enum JsonType
{
@string, number, boolean, @object, array, @null
}
// public static methods
/// from JsonSring to DynamicJson
public static dynamic Parse(string json)
{
return Parse(json , Encoding.Unicode);
}
/// from JsonSring to DynamicJson
public static dynamic Parse(string json , Encoding encoding)
{
using (var reader = JsonReaderWriterFactory.CreateJsonReader(encoding.GetBytes(json) , XmlDictionaryReaderQuotas.Max))
{
return ToValue(XElement.Load(reader));
}
}
/// from JsonSringStream to DynamicJson
public static dynamic Parse(Stream stream)
{
using (var reader = JsonReaderWriterFactory.CreateJsonReader(stream , XmlDictionaryReaderQuotas.Max))
{
return ToValue(XElement.Load(reader));
}
}
/// from JsonSringStream to DynamicJson
public static dynamic Parse(Stream stream , Encoding encoding)
{
using (var reader = JsonReaderWriterFactory.CreateJsonReader(stream , encoding , XmlDictionaryReaderQuotas.Max , _ => { }))
{
return ToValue(XElement.Load(reader));
}
}
/// create JsonSring from primitive or IEnumerable or Object({public property name:property value})
public static string Serialize(object obj)
{
return CreateJsonString(new XStreamingElement("root" , CreateTypeAttr(GetJsonType(obj)) , CreateJsonNode(obj)));
}
// private static methods
private static dynamic ToValue(XElement element)
{
var type = (JsonType)Enum.Parse(typeof(JsonType) , element.Attribute("type").Value);
switch (type)
{
case JsonType.boolean:
return (bool)element;
case JsonType.number:
return (double)element;
case JsonType.@string:
return (string)element;
case JsonType.@object:
case JsonType.array:
return new DynamicJson(element , type);
case JsonType.@null:
default:
return null;
}
}
private static JsonType GetJsonType(object obj)
{
if (obj == null) return JsonType.@null;
switch (Type.GetTypeCode(obj.GetType()))
{
case TypeCode.Boolean:
return JsonType.boolean;
case TypeCode.String:
case TypeCode.Char:
case TypeCode.DateTime:
return JsonType.@string;
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
case TypeCode.SByte:
case TypeCode.Byte:
return JsonType.number;
case TypeCode.Object:
return (obj is IEnumerable) ? JsonType.array : JsonType.@object;
case TypeCode.DBNull:
case TypeCode.Empty:
default:
return JsonType.@null;
}
}
private static XAttribute CreateTypeAttr(JsonType type)
{
return new XAttribute("type" , type.ToString());
}
private static object CreateJsonNode(object obj)
{
var type = GetJsonType(obj);
switch (type)
{
case JsonType.@string:
case JsonType.number:
return obj;
case JsonType.boolean:
return obj.ToString().ToLower();
case JsonType.@object:
return CreateXObject(obj);
case JsonType.array:
return CreateXArray(obj as IEnumerable);
case JsonType.@null:
default:
return null;
}
}
private static IEnumerable CreateXArray(T obj) where T : IEnumerable
{
return obj.Cast