263 lines
8.0 KiB
C#
263 lines
8.0 KiB
C#
/* INFINITY CODE 2013-2019 */
|
|
/* http://www.infinity-code.com */
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using InfinityCode.RealWorldTerrain.Utils;
|
|
using UnityEngine;
|
|
|
|
namespace InfinityCode.RealWorldTerrain.JSON
|
|
{
|
|
/// <summary>
|
|
/// The wrapper for JSON value.
|
|
/// </summary>
|
|
public class RealWorldTerrainJsonValue : RealWorldTerrainJsonItem
|
|
{
|
|
private ValueType _type;
|
|
private object _value;
|
|
|
|
public override RealWorldTerrainJsonItem this[string key]
|
|
{
|
|
get { return null; }
|
|
}
|
|
|
|
public override RealWorldTerrainJsonItem this[int index]
|
|
{
|
|
get { return null; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets / sets the current value
|
|
/// </summary>
|
|
public object value
|
|
{
|
|
get { return _value; }
|
|
set
|
|
{
|
|
#if !UNITY_WP_8_1 || UNITY_EDITOR
|
|
if (value == null || value is DBNull)
|
|
#else
|
|
if (value == null)
|
|
#endif
|
|
{
|
|
_type = ValueType.NULL;
|
|
_value = value;
|
|
}
|
|
else if (value is string)
|
|
{
|
|
_type = ValueType.STRING;
|
|
_value = value;
|
|
}
|
|
else if (value is double)
|
|
{
|
|
_type = ValueType.DOUBLE;
|
|
_value = (double) value;
|
|
}
|
|
else if (value is float)
|
|
{
|
|
_type = ValueType.DOUBLE;
|
|
_value = (double) (float) value;
|
|
}
|
|
else if (value is bool)
|
|
{
|
|
_type = ValueType.BOOLEAN;
|
|
_value = value;
|
|
}
|
|
else if (value is long)
|
|
{
|
|
_type = ValueType.LONG;
|
|
_value = value;
|
|
}
|
|
else if (value is int || value is short || value is byte)
|
|
{
|
|
_type = ValueType.LONG;
|
|
_value = Convert.ChangeType(value, typeof(long));
|
|
}
|
|
else throw new Exception("Unknown type of value.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the type of value
|
|
/// </summary>
|
|
public ValueType type
|
|
{
|
|
get { return _type; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="value">Value</param>
|
|
public RealWorldTerrainJsonValue(object value)
|
|
{
|
|
this.value = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="value">Value</param>
|
|
/// <param name="type">Type of value</param>
|
|
public RealWorldTerrainJsonValue(object value, ValueType type)
|
|
{
|
|
_value = value;
|
|
_type = type;
|
|
}
|
|
|
|
public override object Deserialize(Type type, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public)
|
|
{
|
|
return Value(type);
|
|
}
|
|
|
|
public override RealWorldTerrainJsonItem GetAll(string key)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public override void ToJSON(StringBuilder b)
|
|
{
|
|
if (_type == ValueType.STRING) WriteString(b);
|
|
else if (_type == ValueType.NULL) b.Append("null");
|
|
else if (_type == ValueType.BOOLEAN) b.Append((bool) _value ? "true" : "false");
|
|
else if (_type == ValueType.DOUBLE) b.Append(((double) value).ToString(RealWorldTerrainCultureInfo.cultureInfo));
|
|
else b.Append(value);
|
|
}
|
|
|
|
public override IEnumerator<RealWorldTerrainJsonItem> GetEnumerator()
|
|
{
|
|
yield return this;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
if (type == ValueType.DOUBLE) return ((double) value).ToString(RealWorldTerrainCultureInfo.cultureInfo);
|
|
return value.ToString();
|
|
}
|
|
|
|
public override object Value(Type t)
|
|
{
|
|
if (_type == ValueType.NULL || _value == null)
|
|
{
|
|
if (RealWorldTerrainReflectionHelper.IsValueType(t)) return Activator.CreateInstance(t);
|
|
return null;
|
|
}
|
|
|
|
if (t == typeof(string)) return Convert.ChangeType(_value, t);
|
|
|
|
if (_type == ValueType.BOOLEAN)
|
|
{
|
|
if (t == typeof(bool)) return Convert.ChangeType(_value, t);
|
|
}
|
|
else if (_type == ValueType.DOUBLE)
|
|
{
|
|
if (t == typeof(double)) return Convert.ChangeType(_value, t, RealWorldTerrainCultureInfo.numberFormat);
|
|
if (t == typeof(float)) return Convert.ChangeType((double) _value, t, RealWorldTerrainCultureInfo.numberFormat);
|
|
}
|
|
else if (_type == ValueType.LONG)
|
|
{
|
|
if (t == typeof(long)) return Convert.ChangeType(_value, t);
|
|
#if UNITY_EDITOR
|
|
if (t.IsSubclassOf(typeof(UnityEngine.Object)))
|
|
{
|
|
return UnityEditor.EditorUtility.InstanceIDToObject((int) (long) _value);
|
|
}
|
|
#endif
|
|
|
|
try
|
|
{
|
|
return Convert.ChangeType((long) _value, t);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.Log(e.Message + "\n" + e.StackTrace);
|
|
return null;
|
|
}
|
|
}
|
|
else if (_type == ValueType.STRING)
|
|
{
|
|
MethodInfo method = RealWorldTerrainReflectionHelper.GetMethod(t, "Parse", new[] {typeof(string), typeof(IFormatProvider)});
|
|
if (method != null) return method.Invoke(null, new object[] {value, RealWorldTerrainCultureInfo.numberFormat});
|
|
|
|
method = RealWorldTerrainReflectionHelper.GetMethod(t, "Parse", new[] {typeof(string)});
|
|
return method.Invoke(null, new[] {value});
|
|
}
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
ToJSON(builder);
|
|
throw new InvalidCastException(t.FullName + "\n" + builder);
|
|
}
|
|
|
|
private void WriteString(StringBuilder b)
|
|
{
|
|
b.Append('\"');
|
|
|
|
string s = value as string;
|
|
|
|
int runIndex = -1;
|
|
int l = s.Length;
|
|
for (var index = 0; index < l; ++index)
|
|
{
|
|
var c = s[index];
|
|
|
|
if (c >= ' ' && c < 128 && c != '\"' && c != '\\')
|
|
{
|
|
if (runIndex == -1) runIndex = index;
|
|
|
|
continue;
|
|
}
|
|
|
|
if (runIndex != -1)
|
|
{
|
|
b.Append(s, runIndex, index - runIndex);
|
|
runIndex = -1;
|
|
}
|
|
|
|
switch (c)
|
|
{
|
|
case '\t':
|
|
b.Append("\\t");
|
|
break;
|
|
case '\r':
|
|
b.Append("\\r");
|
|
break;
|
|
case '\n':
|
|
b.Append("\\n");
|
|
break;
|
|
case '"':
|
|
case '\\':
|
|
b.Append('\\');
|
|
b.Append(c);
|
|
break;
|
|
default:
|
|
b.Append("\\u");
|
|
b.Append(((int) c).ToString("X4", NumberFormatInfo.InvariantInfo));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (runIndex != -1) b.Append(s, runIndex, s.Length - runIndex);
|
|
b.Append('\"');
|
|
}
|
|
|
|
public static implicit operator string(RealWorldTerrainJsonValue val)
|
|
{
|
|
return val.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Type of value
|
|
/// </summary>
|
|
public enum ValueType
|
|
{
|
|
DOUBLE,
|
|
LONG,
|
|
STRING,
|
|
BOOLEAN,
|
|
NULL
|
|
}
|
|
}
|
|
} |