ln.json/JSON.cs

269 lines
6.8 KiB
C#
Raw Normal View History

2017-10-26 16:41:14 +02:00
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
2017-11-03 13:13:09 +01:00
using System.Net;
using System.Reflection;
using System.Collections;
using System.Security.Cryptography;
2017-10-26 16:41:14 +02:00
namespace sharp.json
{
2017-11-03 13:13:09 +01:00
public delegate object JSONActivationDelegate(Type t);
public abstract class JSON : IEnumerable<JSON>
2017-10-26 16:41:14 +02:00
{
2017-11-03 13:13:09 +01:00
public virtual double Double { get { throw new NotImplementedException(); } }
public virtual long Integer { get { throw new NotImplementedException(); } }
public virtual string String { get { throw new NotImplementedException(); } }
public virtual bool Boolean { get { throw new NotImplementedException(); } }
public virtual JSON this[int n]
{
get { throw new NotImplementedException(String.Format("{0} has no numbered elements",GetType().Name)); }
set { throw new NotImplementedException(String.Format("{0} has no numbered elements",GetType().Name)); }
}
public virtual JSON this[string name] {
get { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
set { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
}
public virtual int Count { get { return 0; } }
public virtual bool Contains(object o){
return false;
}
public virtual void Add(JSON child)
{
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
}
public virtual void Remove(JSON child)
{
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
}
public JSONTypes JSONType { get; private set; }
protected JSON(JSONTypes type){
JSONType = type;
}
public abstract string[] prettyPrint();
public override abstract string ToString();
public string prettyFormat(){
return String.Join("\n", prettyPrint());
}
public static implicit operator JSON(Double src)
{
return new JSONNumber(src);
}
public static implicit operator JSON(int src)
{
return new JSONNumber(src);
}
public static implicit operator JSON(string text)
{
return new JSONString(text);
}
public static implicit operator JSON(bool b)
{
return b ? JSONSpecial.True : JSONSpecial.False;
}
public T To<T>(){
object o = Create(typeof(T));
return (T)o;
}
public void WriteTo(Stream stream){
byte[] data = Encoding.ASCII.GetBytes(ToString());
stream.Write(data,0,data.Length);
}
public void WriteTo(String filename)
{
FileStream fs = new FileStream(filename, FileMode.Create);
WriteTo(fs);
fs.Close();
}
public static JSON ReadFrom(string filename){
JSONParser parser = new JSONParser();
string source = File.ReadAllText(filename);
return parser.Parse(source);
}
private object Create(Type t)
{
if (t.IsPrimitive || (t == typeof(string)) )
{
return CreatePrimitive(t);
}
2017-10-26 16:41:14 +02:00
2017-11-03 13:13:09 +01:00
if (this.JSONType == JSONTypes.Object)
{
return CreateObject(t);
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
if ((this.JSONType == JSONTypes.Array) && (t.IsArray))
{
return CreateArray(t);
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}", this.JSONType.ToString(), t.Name));
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
private object CreatePrimitive(Type t){
if ((this.JSONType == JSONTypes.Null)){
return null;
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
if ((this.JSONType == JSONTypes.Array) || (this.JSONType == JSONTypes.Object)){
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}",this.JSONType.ToString(),t.Name));
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
if (t.Equals(typeof(int)) || t.Equals(typeof(long)) || t.Equals(typeof(short))){
return (object)this.Integer;
}
if (t.Equals(typeof(double)) || t.Equals(typeof(float)))
{
return (object)this.Double;
}
if (t.Equals(typeof(string)))
{
return (object)this.String;
}
if (t.Equals(typeof(Boolean)))
{
return (object)this.Boolean;
}
throw new Exception(String.Format("Unsupported primitive type",t.Name));
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
private object CreateObject(Type t){
if (t.GetConstructor(new Type[] { typeof(JSON) } ) != null){
return Activator.CreateInstance(t, this);
}
object instance = Activator.CreateInstance(t);
Dictionary<string, FieldPropertyInfo> assignedFields = new Dictionary<string, FieldPropertyInfo>();
foreach (FieldInfo fi in t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
foreach (JSONField f in fi.GetCustomAttributes<JSONField>())
{
if (this.Contains(f.Alias))
{
if (!assignedFields.ContainsKey(f.Alias) || assignedFields[f.Alias].IsAutoAssigned){
assignedFields[f.Alias] = new FieldPropertyInfo(fi, false);
break;
}
}
}
if (!assignedFields.ContainsKey(fi.Name) && this.Contains(fi.Name)){
assignedFields[fi.Name] = new FieldPropertyInfo(fi, true);
}
}
foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
foreach (JSONField f in pi.GetCustomAttributes<JSONField>())
{
if (this.Contains(f.Alias))
{
if (!assignedFields.ContainsKey(f.Alias) || assignedFields[f.Alias].IsAutoAssigned)
{
assignedFields[f.Alias] = new FieldPropertyInfo(pi, false);
break;
}
}
}
if (!assignedFields.ContainsKey(pi.Name) && this.Contains(pi.Name))
{
assignedFields[pi.Name] = new FieldPropertyInfo(pi, true);
}
}
foreach (KeyValuePair<string,FieldPropertyInfo> e in assignedFields){
e.Value.setValue(instance, this[e.Key].Create(e.Value.ValueType));
}
return instance;
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
private object CreateArray(Type t)
{
Array a = Array.CreateInstance(t.GetElementType(), this.Count);
for (int n = 0; n < this.Count;n++){
a.SetValue(this[n].Create(t.GetElementType()),n);
}
return a;
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
public virtual IEnumerator<JSON> GetEnumerator()
{
throw new NotImplementedException();
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)GetEnumerator();
2017-10-26 16:41:14 +02:00
}
2017-11-03 13:13:09 +01:00
struct FieldPropertyInfo {
public bool IsAutoAssigned { get; set; }
FieldInfo FieldInfo { get; set; }
PropertyInfo PropertyInfo { get; set; }
2017-10-26 16:41:14 +02:00
2017-11-03 13:13:09 +01:00
public FieldPropertyInfo(PropertyInfo propertyInfo,bool autoAssigned)
{
this.IsAutoAssigned = autoAssigned;
this.PropertyInfo = propertyInfo;
this.FieldInfo = null;
}
public FieldPropertyInfo(FieldInfo fieldInfo,bool autoAssigned)
{
this.IsAutoAssigned = autoAssigned;
this.PropertyInfo = null;
this.FieldInfo = fieldInfo;
}
2017-10-26 16:41:14 +02:00
2017-11-03 13:13:09 +01:00
public void setValue(object inst,object value){
if (PropertyInfo != null){
PropertyInfo.SetValue(inst,value);
} else if (FieldInfo != null){
FieldInfo.SetValue(inst,value);
}
}
public Type ValueType {
get {
if (PropertyInfo != null){
return PropertyInfo.PropertyType;
} else if (FieldInfo != null){
return FieldInfo.FieldType;
}
return null;
}
}
2017-10-26 16:41:14 +02:00
}
}
}