修复cpf.json编译报错问题
This commit is contained in:
parent
095e414085
commit
12ecbfa97c
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 别名,标记于字段或属性上的特性
|
||||
/// Alias,Characteristics marked on fields or property
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class AliasAttribute : Attribute
|
||||
{
|
||||
internal string _name { get; set; }
|
||||
/// <summary>
|
||||
/// Structural aliases
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public AliasAttribute(string name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 被标记的元素,在序列化或反序列化时时将被忽略
|
||||
/// Marked elements are ignored when serialized or deserialized
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class IgnoreKeyAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 当被标记元素的值为默认值时,序列化时将忽略其元素
|
||||
/// When the value of the tagged element is the default, its element is ignored when serialized
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class |
|
||||
AttributeTargets.Struct)]
|
||||
public class IgnoreDefaultValueAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 对Model进行Json反序列化时指定一个构造函数
|
||||
/// Specify a constructor for Json deserialization of Model
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Constructor)]
|
||||
public class JsonDeserializeCtorAttribute : Attribute
|
||||
{
|
||||
internal object[] _args;
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化时的指定构造函数以及参数,args必须和构造函数参数匹配
|
||||
/// Deserializing the specified constructor and parameters, args must match the constructor parameters
|
||||
/// </summary>
|
||||
/// <param name="args">该构造函数的参数,The parameters of the constructor</param>
|
||||
public JsonDeserializeCtorAttribute(params object[] args)
|
||||
{
|
||||
_args = args;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 序列化仅包含此元素,和Ignore相反
|
||||
/// Serialization contains only this element, as opposed to Ignore
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class JsonOnlyIncludeAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 元素排序,标记于字段或属性上的特性
|
||||
/// Element sort, a feature marked on a field or property
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class JsonOrderAttribute: Attribute
|
||||
{
|
||||
internal ushort _orderNum { get; set; }
|
||||
/// <summary>
|
||||
/// JsonOrder
|
||||
/// </summary>
|
||||
/// <param name="orderNum">Order number</param>
|
||||
public JsonOrderAttribute(ushort orderNum)
|
||||
{
|
||||
_orderNum = orderNum;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 对Model的值格式化器特性,可标注于字段,属性,结构或类上,(字段/属性) 优先级大于 (结构/类)
|
||||
/// Value formatter features of Model can be labeled on fields, properties, structures or classes with priority of
|
||||
/// (fields/properties) over (structures/classes)
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class |
|
||||
AttributeTargets.Struct)]
|
||||
public abstract class ValueFormatAttribute : Attribute
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static MethodInfo _WriteValueFormat = typeof(ValueFormatAttribute).GetMethod(nameof(WriteValueFormat));
|
||||
internal static MethodInfo _ReadValueFormat = typeof(ValueFormatAttribute).GetMethod(nameof(ReadValueFormat));
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 序列化时 - Model的Value的格式化器
|
||||
/// Serialization time - Value formatter for Model
|
||||
/// </summary>
|
||||
/// <param name="value">需要被格式化的源元素数据,Source element data that needs to be formatted</param>
|
||||
/// <param name="type">值的类型,The type of the value</param>
|
||||
/// <param name="handler">用于提供一些配置选项,Used to provide some configuration options</param>
|
||||
/// <param name="isValueFormat">决定最终是否进行值格式化,Determines whether the value is ultimately formatted</param>
|
||||
/// <returns>格式化后的结果,Formatted results</returns>
|
||||
public virtual string WriteValueFormat(object value,Type type, JsonSerializerHandler handler, out bool isValueFormat)
|
||||
{
|
||||
isValueFormat = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 反序列化时 - Model的Value的格式化器
|
||||
/// When deserializing - Value formatter for Model
|
||||
/// </summary>
|
||||
/// <param name="value">从Json字符串中读取的匹配字符串,Matched strings read from Json strings</param>
|
||||
/// <param name="type">值的类型,The type of the value</param>
|
||||
/// <param name="handler">用于提供一些配置选项,Used to provide some configuration options</param>
|
||||
/// <param name="isValueFormat">决定最终是否进行值格式化,Determines whether the value is ultimately formatted</param>
|
||||
/// <returns>格式化后的结果,Formatted results</returns>
|
||||
public virtual object ReadValueFormat(string value,Type type, JsonDeserializeHandler handler, out bool isValueFormat)
|
||||
{
|
||||
isValueFormat = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
using CPF.Json.Deserialize;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型解析错误
|
||||
/// Json Deserialization TypeResolution Exception
|
||||
/// </summary>
|
||||
public class JsonDeserializationTypeResolutionException : Exception
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static ConstructorInfo _JsonDeserializationTypeResolutionExceptionMsgCtor =
|
||||
typeof(JsonDeserializationTypeResolutionException).GetConstructor(
|
||||
BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(string) }, null);
|
||||
|
||||
internal static ConstructorInfo _JsonDeserializationTypeResolutionExceptionCtor =
|
||||
typeof(JsonDeserializationTypeResolutionException).GetConstructor(
|
||||
BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(JsonReader), typeof(Type) }, null);
|
||||
#endregion
|
||||
|
||||
|
||||
internal JsonDeserializationTypeResolutionException() : base("Json deserialization type parsing error")
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonDeserializationTypeResolutionException(string msg) : base(
|
||||
$"Json deserialization type parsing error : {msg}")
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonDeserializationTypeResolutionException(Type t) : base(
|
||||
$"Json deserialization {t.Name} type parsing error")
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonDeserializationTypeResolutionException(JsonReader reader, Type t) : base(
|
||||
$"Json deserialization {t.Name} type parsing error ,An error occurred on symbol {reader.Length - reader.Remaining-1} , it's { reader[reader.Length - reader.Remaining-1]}")
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonDeserializationTypeResolutionException(JsonReader reader, Type t, string msg) : base(
|
||||
$"Json deserialization {t.Name} type parsing error ,An error occurred on symbol {reader.Length - reader.Remaining-1} , {msg}")
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonDeserializationTypeResolutionException(Type t, string msg) : base(
|
||||
$"Json deserialization {t.Name} type parsing error , {msg}")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 不受支持的解析类型
|
||||
/// Unsupported parse type
|
||||
/// </summary>
|
||||
public class JsonNoSupportedDeserializeTypeException : Exception
|
||||
{
|
||||
internal JsonNoSupportedDeserializeTypeException(string msg) : base("Json Deserialize Unsupported type : " + msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal JsonNoSupportedDeserializeTypeException(Type t) : base("Json Deserialize Unsupported type : " + t.Name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal JsonNoSupportedDeserializeTypeException(Type t, string msg) : base("Json Deserialize Unsupported type : " + t.Name + " , " + msg)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
using CPF.Json.Deserialize;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误的json字符
|
||||
/// Json Wrong Character
|
||||
/// </summary>
|
||||
public class JsonWrongCharacterException : Exception
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static ConstructorInfo _JsonWrongCharacterExceptionCtor =
|
||||
typeof(JsonWrongCharacterException).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
|
||||
new[] { typeof(JsonReader) }, null);
|
||||
#endregion
|
||||
|
||||
internal JsonWrongCharacterException() : base("Incorrect JSON format")
|
||||
{
|
||||
}
|
||||
|
||||
internal JsonWrongCharacterException(string msg) : base("Incorrect JSON format : " + msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal JsonWrongCharacterException(int index) : base(
|
||||
$"Incorrect JSON format : An error occurred on symbol {index} ")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal JsonWrongCharacterException(int index, string correctString) : base(
|
||||
$"Incorrect JSON format : An error occurred on symbol {index} , {correctString}")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal JsonWrongCharacterException(int index, char correctChar, char errorChar) : base(
|
||||
$"Incorrect JSON format : An error occurred on symbol {index} , It should be {correctChar}, but it's actually {errorChar}")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal JsonWrongCharacterException(JsonReader reader) : this(
|
||||
reader.Length - reader.Remaining)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
internal JsonWrongCharacterException( JsonReader reader, string correctString) : this(
|
||||
reader.Length - reader.Remaining, correctString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
internal JsonWrongCharacterException(JsonReader reader, char correctChar) : this(
|
||||
reader.Length - reader.Remaining, correctChar,
|
||||
reader[reader.Length - reader.Remaining])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
73
CPF/Json/Formatter.cs
Normal file
73
CPF/Json/Formatter.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal static class Formatter
|
||||
{
|
||||
public static string Indent = " ";
|
||||
|
||||
public static void AppendIndent(StringBuilder sb, int count)
|
||||
{
|
||||
for (; count > 0; --count) sb.Append(Indent);
|
||||
}
|
||||
|
||||
public static string PrettyPrint(string input)
|
||||
{
|
||||
var output = new StringBuilder();
|
||||
int depth = 0;
|
||||
int len = input.Length;
|
||||
char[] chars = input.ToCharArray();
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
char ch = chars[i];
|
||||
|
||||
if (ch == '\"') // found string span
|
||||
{
|
||||
bool str = true;
|
||||
while (str)
|
||||
{
|
||||
output.Append(ch);
|
||||
ch = chars[++i];
|
||||
if (ch == '\\')
|
||||
{
|
||||
output.Append(ch);
|
||||
ch = chars[++i];
|
||||
}
|
||||
else if (ch == '\"')
|
||||
str = false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case '{':
|
||||
case '[':
|
||||
output.Append(ch);
|
||||
output.AppendLine();
|
||||
AppendIndent(output, ++depth);
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
output.AppendLine();
|
||||
AppendIndent(output, --depth);
|
||||
output.Append(ch);
|
||||
break;
|
||||
case ',':
|
||||
output.Append(ch);
|
||||
output.AppendLine();
|
||||
AppendIndent(output, depth);
|
||||
break;
|
||||
case ':':
|
||||
output.Append(" : ");
|
||||
break;
|
||||
default:
|
||||
if (!char.IsWhiteSpace(ch))
|
||||
output.Append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return output.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class BaseTypeResolve: DefaultJsonResolve
|
||||
{
|
||||
[FuncLable(FuncType.BaseType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static Exception ReadException(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (reader.ReadNullOrObjLeft())
|
||||
return null;
|
||||
if (reader.ReadBoolObjRight())
|
||||
return new Exception();
|
||||
|
||||
string source = null, message = null, helpLink = null;
|
||||
|
||||
int i = 1;
|
||||
char c = ' ';
|
||||
while (i-- > 0)
|
||||
{
|
||||
reader.ReadQuotes();
|
||||
switch (handler.Option.JsonCharacterReadState)
|
||||
{
|
||||
case JsonCharacterReadStateEnum.None:
|
||||
c = reader.GetChar();
|
||||
break;
|
||||
case JsonCharacterReadStateEnum.InitialUpper:
|
||||
c = char.ToUpper(reader.GetChar());
|
||||
break;
|
||||
case JsonCharacterReadStateEnum.InitialLower:
|
||||
c = char.ToLower(reader.GetChar());
|
||||
break;
|
||||
}
|
||||
switch (c)
|
||||
{
|
||||
case 'S':
|
||||
c = reader.GetChar();
|
||||
if (c == 'o' && reader.StrCompair("urce\""))
|
||||
{
|
||||
reader.ReadColon();
|
||||
source = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
}
|
||||
else if (c == 't' && reader.StrCompair("ackTrace\""))
|
||||
{
|
||||
//只读
|
||||
reader.ReadColon();
|
||||
PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
break;
|
||||
case 'M':
|
||||
{
|
||||
if (reader.StrCompair("essage\""))
|
||||
{
|
||||
reader.ReadColon();
|
||||
message = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
break;
|
||||
}
|
||||
case 'H':
|
||||
{
|
||||
if ( reader.StrCompair("elpLink\""))
|
||||
{
|
||||
reader.ReadColon();
|
||||
helpLink = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
}
|
||||
else
|
||||
throw new Exception();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Exception();
|
||||
}
|
||||
if (reader.ReadBoolComma())
|
||||
i++;
|
||||
}
|
||||
|
||||
var exception = message != null ? new Exception(message) : new Exception();
|
||||
|
||||
exception.Source = source;
|
||||
exception.HelpLink = helpLink;
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.BaseType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static Type ReadType(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
var typeName = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
return typeName != null ? Type.GetType(typeName) : null;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class SpecialConditionsResolve : DefaultJsonResolve
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static MethodInfo _ReadAvoidNull = typeof(SpecialConditionsResolve).GetMethod(nameof(ReadAvoidNull), BindingFlags.NonPublic | BindingFlags.Static);
|
||||
internal static MethodInfo _ReadNullable = typeof(SpecialConditionsResolve).GetMethod(nameof(ReadNullable), BindingFlags.NonPublic | BindingFlags.Static);
|
||||
internal static MethodInfo _ReadEnum = typeof(SpecialConditionsResolve).GetMethod(nameof(ReadEnum), BindingFlags.NonPublic | BindingFlags.Static);
|
||||
#endregion
|
||||
|
||||
//---------Avoid
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void ReadAvoidNull(JsonReader reader)
|
||||
{
|
||||
char c = reader.BeforAnnotation();
|
||||
if (c == 'n' && reader.StrCompair("ull"))
|
||||
return;
|
||||
if (c == '{' && reader.GetChar() == '}')
|
||||
return;
|
||||
throw new JsonWrongCharacterException(reader);
|
||||
}
|
||||
|
||||
//---------T?
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static T? ReadNullable<T>(JsonReader reader, JsonDeserializeHandler handler) where T : struct
|
||||
{
|
||||
var c = reader.BeforAnnotation();
|
||||
if (c == 'n')
|
||||
{
|
||||
if (reader.StrCompair("ull"))
|
||||
return null;
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(T?));
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.RollbackChar();
|
||||
return (T?)ResolveProvider<T>.InvokeGet(reader, handler);
|
||||
}
|
||||
}
|
||||
|
||||
//---------Enum
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static object ReadEnum(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
var c = reader.BeforAnnotation();
|
||||
var t = handler.Types.Dequeue();
|
||||
if (c == '"')
|
||||
{
|
||||
reader.RollbackChar();
|
||||
var str = reader.ReadString();
|
||||
return Enum.Parse(t, str);
|
||||
}
|
||||
|
||||
if (c >= '0' && c <= '9')// byte、sbyte、short、ushort、int、uint、long 、ulong default ->int
|
||||
{
|
||||
reader.RollbackChar();
|
||||
var basicType = Enum.GetUnderlyingType(t);
|
||||
if (basicType == typeof(long))
|
||||
return Enum.ToObject(t, PrimitiveResolve.ReadLong(reader, handler));
|
||||
else if (basicType == typeof(ulong))
|
||||
return Enum.ToObject(t, PrimitiveResolve.ReadULong(reader, handler));
|
||||
else if (basicType == typeof(uint))
|
||||
return Enum.ToObject(t, PrimitiveResolve.ReadUInt(reader, handler));
|
||||
else
|
||||
return Enum.ToObject(t, PrimitiveResolve.ReadInt(reader, handler));
|
||||
}
|
||||
throw new JsonDeserializationTypeResolutionException(reader, t);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,414 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data;
|
||||
using System.Dynamic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class SpecialTypeResolve : DefaultJsonResolve
|
||||
{
|
||||
//---------Special
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static DataTable ReadDataTable(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
//[{ \"Id\":1 , \"Name\":\"ss\" }]
|
||||
if (reader.ReadNullOrArrayLeft())
|
||||
return null;
|
||||
DataTable dt = new DataTable();
|
||||
|
||||
int moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
reader.ReadObjLeft();
|
||||
DataRow dr = dt.NewRow();
|
||||
int move = 1;
|
||||
while (move-- > 0)
|
||||
{
|
||||
string columnName = PrimitiveResolve.ReadEscapeString(reader,handler);
|
||||
reader.ReadColon();
|
||||
DataColumn column = dt.Columns[columnName];
|
||||
if (column == null)
|
||||
{
|
||||
column = new DataColumn(columnName, typeof(object));
|
||||
dt.Columns.Add(column);
|
||||
}
|
||||
|
||||
object rowValue = PrimitiveResolve.ReadObject(reader, handler);
|
||||
dr[columnName] = rowValue;
|
||||
|
||||
if (reader.ReadBoolComma())
|
||||
move++;
|
||||
}
|
||||
dr.EndEdit();
|
||||
dt.Rows.Add(dr);
|
||||
|
||||
reader.ReadObjRight();
|
||||
if (reader.ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
|
||||
reader.ReadArrayRight();
|
||||
return dt;
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static DBNull ReadDBNull(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
char c = reader.BeforAnnotation();
|
||||
if (c == 'n' && reader.StrCompair("ull"))
|
||||
return DBNull.Value;
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(DBNull));
|
||||
}
|
||||
|
||||
private static ResolveDelegate<byte[]> byteArray;
|
||||
private static readonly object ObjLock = new object();
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static byte[] ReadBytes(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
char c = reader.BeforAnnotation();
|
||||
if (c == 'n' && reader.StrCompair("ull"))
|
||||
return null;
|
||||
else if (c == '[')
|
||||
{
|
||||
reader.RollbackChar();
|
||||
if (byteArray == null)
|
||||
{
|
||||
lock (ObjLock)
|
||||
{
|
||||
if (byteArray == null)
|
||||
byteArray = BuildFactory.Build<byte[]>(DeserializeBuildTypeEnum.Array, typeof(byte[]));
|
||||
}
|
||||
}
|
||||
return byteArray(reader, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.RollbackChar();
|
||||
return Convert.FromBase64String(PrimitiveResolve.ReadEscapeString(reader,handler));
|
||||
}
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static Guid ReadGuid(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
var c = reader.BeforAnnotation();
|
||||
if (c == '"')
|
||||
{
|
||||
if (reader.Remaining > 36)
|
||||
{
|
||||
// 1314FAD4-7505-439D-ABD2-DBD89242928C
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
//
|
||||
// Guid is guaranteed to be a 36 character string
|
||||
|
||||
// Bytes are in a different order than you might expect
|
||||
// For: 35 91 8b c9 - 19 6d - 40 ea - 97 79 - 88 9d 79 b7 53 f0
|
||||
// Get: C9 8B 91 35 6D 19 EA 40 97 79 88 9D 79 B7 53 F0
|
||||
// Ix: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
var asStruct = new GuidStruct
|
||||
{
|
||||
B03 = ReadGuidByte(reader),
|
||||
B02 = ReadGuidByte(reader),
|
||||
B01 = ReadGuidByte(reader),
|
||||
B00 = ReadGuidByte(reader)
|
||||
};
|
||||
|
||||
c = reader.GetChar();
|
||||
if (c != '-')
|
||||
throw new JsonWrongCharacterException(reader, "Guid format error");
|
||||
|
||||
asStruct.B05 = ReadGuidByte(reader);
|
||||
asStruct.B04 = ReadGuidByte(reader);
|
||||
|
||||
c = reader.GetChar();
|
||||
if (c != '-')
|
||||
throw new JsonWrongCharacterException(reader, "Guid format error");
|
||||
|
||||
asStruct.B07 = ReadGuidByte(reader);
|
||||
asStruct.B06 = ReadGuidByte(reader);
|
||||
|
||||
c = reader.GetChar();
|
||||
if (c != '-')
|
||||
throw new JsonWrongCharacterException(reader, "Guid format error");
|
||||
|
||||
asStruct.B08 = ReadGuidByte(reader);
|
||||
asStruct.B09 = ReadGuidByte(reader);
|
||||
|
||||
c = reader.GetChar();
|
||||
if (c != '-')
|
||||
throw new JsonWrongCharacterException(reader, "Guid format error");
|
||||
|
||||
asStruct.B10 = ReadGuidByte(reader);
|
||||
asStruct.B11 = ReadGuidByte(reader);
|
||||
asStruct.B12 = ReadGuidByte(reader);
|
||||
asStruct.B13 = ReadGuidByte(reader);
|
||||
asStruct.B14 = ReadGuidByte(reader);
|
||||
asStruct.B15 = ReadGuidByte(reader);
|
||||
if (reader.GetChar() == '"')
|
||||
return asStruct.Value;
|
||||
}
|
||||
}
|
||||
throw new JsonDeserializationTypeResolutionException(reader, typeof(Guid));
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static Uri ReadUri(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
char c = reader.BeforAnnotation();
|
||||
if (c == 'n' && reader.StrCompair("ull"))
|
||||
return null;
|
||||
else
|
||||
{
|
||||
reader.RollbackChar();
|
||||
return new Uri(PrimitiveResolve.ReadEscapeString(reader,handler));
|
||||
}
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static NameValueCollection ReadNameValueCollection(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (reader.ReadNullOrObjLeft())
|
||||
return null;
|
||||
|
||||
NameValueCollection nameValueCollection = new NameValueCollection();
|
||||
|
||||
int moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
var key = PrimitiveResolve.ReadEscapeString( reader, handler);
|
||||
reader.ReadColon();
|
||||
var value = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
nameValueCollection.Add(key, value);
|
||||
if (reader.ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
reader.ReadObjRight();
|
||||
return nameValueCollection;
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static StringDictionary ReadStringDictionary(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (reader.ReadNullOrObjLeft())
|
||||
return null;
|
||||
|
||||
StringDictionary nameValueCollection = new StringDictionary();
|
||||
|
||||
int moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
var key = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
reader.ReadColon();
|
||||
var value = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
nameValueCollection.Add(key, value);
|
||||
if (reader.ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
reader.ReadObjRight();
|
||||
return nameValueCollection;
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static ExpandoObject ReadExpandoObject(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (reader.ReadNullOrObjLeft())
|
||||
return null;
|
||||
|
||||
ExpandoObject obj = new ExpandoObject();
|
||||
var dic = (IDictionary<string, object>)obj;
|
||||
|
||||
int moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
var key = PrimitiveResolve.ReadEscapeString(reader, handler);
|
||||
reader.ReadColon();
|
||||
var value = PrimitiveResolve.ReadObject(reader, handler);
|
||||
dic.Add(key, value);
|
||||
if (reader.ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
reader.ReadObjRight();
|
||||
return obj;
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static StringBuilder ReadStringBuilder(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
var c = reader.BeforAnnotation();
|
||||
if (c == '"')
|
||||
{
|
||||
int start = reader.Length - reader.Remaining;
|
||||
int length = 0;
|
||||
StringBuilder charBufferSb = new StringBuilder();
|
||||
while (reader.Remaining > 0)
|
||||
{
|
||||
c = reader.GetChar();
|
||||
if (c == '"')//end
|
||||
{
|
||||
if (length > 0)
|
||||
{
|
||||
if (reader.Json != null)
|
||||
charBufferSb.Append(reader.Json, start, length);
|
||||
else
|
||||
charBufferSb.Append(reader.Buffer, start, length);
|
||||
}
|
||||
return charBufferSb;
|
||||
}
|
||||
|
||||
if (c != '\\')
|
||||
{
|
||||
++length;
|
||||
continue;
|
||||
}
|
||||
if (length > 0)
|
||||
{
|
||||
if (reader.Json != null)
|
||||
charBufferSb.Append(reader.Json, start, length);
|
||||
else
|
||||
charBufferSb.Append(reader.Buffer, start, length);
|
||||
start += length;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
string s = "a\\\\b";
|
||||
string s = "a\\u005cb";
|
||||
*/
|
||||
start += 2;
|
||||
if (reader.Remaining < 1)
|
||||
throw new JsonDeserializationTypeResolutionException(reader, typeof(string));
|
||||
|
||||
c = reader.GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '"': charBufferSb.Append('"'); continue;
|
||||
case '\\': charBufferSb.Append('\\'); continue;
|
||||
case '/': charBufferSb.Append('/'); continue;
|
||||
case 'b': charBufferSb.Append('\b'); continue;
|
||||
case 'f': charBufferSb.Append('\f'); continue;
|
||||
case 'n': charBufferSb.Append('\n'); continue;
|
||||
case 'r': charBufferSb.Append('\r'); continue;
|
||||
case 't': charBufferSb.Append('\t'); continue;
|
||||
case 'u':
|
||||
{ // \\uXXXX
|
||||
if (reader.Remaining > 4)//4+'"'
|
||||
{
|
||||
int idx = charBufferSb.Length;
|
||||
charBufferSb.Append(reader.GetChar());
|
||||
charBufferSb.Append(reader.GetChar());
|
||||
charBufferSb.Append(reader.GetChar());
|
||||
charBufferSb.Append(reader.GetChar());
|
||||
int unicode = (((((charBufferSb[idx].CharToNumber() * 16) + charBufferSb[++idx].CharToNumber()) * 16) + charBufferSb[++idx].CharToNumber()) * 16) + charBufferSb[++idx].CharToNumber();
|
||||
charBufferSb.Remove(idx - 3, 4);
|
||||
charBufferSb.Append((char)unicode);
|
||||
|
||||
start += 4;
|
||||
continue;
|
||||
}
|
||||
throw new JsonWrongCharacterException(reader, "It should be four hexadecimal digits , such as \\uFFFF");
|
||||
}
|
||||
default:
|
||||
throw new JsonWrongCharacterException(reader, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == 'n' && reader.StrCompair("ull"))
|
||||
return null;
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(reader, typeof(string));
|
||||
|
||||
}
|
||||
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static BitArray ReadBitArray(JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (reader.ReadNullOrArrayLeft())
|
||||
return null;
|
||||
|
||||
if (reader.ReadBoolArrayRight())
|
||||
return new BitArray(0);
|
||||
|
||||
bool[] values = new bool[reader.GetArrayLength(handler)];
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
values[i] = PrimitiveResolve.ReadBool(reader, handler);
|
||||
if (i != values.Length - 1)
|
||||
reader.ReadComma();
|
||||
}
|
||||
reader.ReadArrayRight();
|
||||
return new BitArray(values);
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
private static byte ReadGuidByte(JsonReader reader)
|
||||
{
|
||||
int a = reader.GetChar();
|
||||
|
||||
if (!((a >= '0' && a <= '9') || (a >= 'A' && a <= 'F') || (a >= 'a' && a <= 'f')))
|
||||
throw new JsonWrongCharacterException(reader, "Guid format error");
|
||||
|
||||
int b = reader.GetChar();
|
||||
|
||||
if (!((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')))
|
||||
throw new JsonWrongCharacterException(reader, "Guid format error");
|
||||
|
||||
if (a <= '9')
|
||||
a -= '0';
|
||||
else
|
||||
{
|
||||
if (a <= 'F')
|
||||
a -= ('A' - 10);
|
||||
else
|
||||
a -= ('a' - 10);
|
||||
}
|
||||
|
||||
if (b <= '9')
|
||||
b -= '0';
|
||||
else
|
||||
{
|
||||
if (b <= 'F')
|
||||
b -= ('A' - 10);
|
||||
else
|
||||
b -= ('a' - 10);
|
||||
}
|
||||
|
||||
return (byte)(a * 16 + b);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,576 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class TimeSpanResolve : DefaultJsonResolve
|
||||
{
|
||||
[FuncLable(FuncType.SameType)]
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static unsafe TimeSpan ReadTimeSpan( JsonReader reader, JsonDeserializeHandler handler)
|
||||
{
|
||||
/*
|
||||
\"P10675199DT2H48M5.4775807S\" => ISO
|
||||
\"10675199.02:48:05.4775807\" => Microsoft
|
||||
*/
|
||||
reader.ReadQuotes();
|
||||
char* ip = reader.Pointer;
|
||||
char c = ip[0];
|
||||
if (c == '-')
|
||||
c = ip[1];
|
||||
|
||||
if (c == 'P')
|
||||
return _ReadISO8601TimeSpan(reader);
|
||||
else
|
||||
return ReadMicrosoftTimeSpan(reader);
|
||||
}
|
||||
|
||||
static readonly ulong MinTicks = (ulong)-TimeSpan.MinValue.Ticks;
|
||||
static readonly ulong MaxTicks = (ulong)TimeSpan.MaxValue.Ticks;
|
||||
|
||||
static readonly double[] DivideFractionBy =
|
||||
{
|
||||
10,
|
||||
100,
|
||||
1000,
|
||||
10000,
|
||||
100000,
|
||||
1000000,
|
||||
10000000,
|
||||
100000000
|
||||
};
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
static unsafe TimeSpan ReadMicrosoftTimeSpan(JsonReader reader)
|
||||
{
|
||||
char* ip = reader.Pointer;
|
||||
int start = reader.Remaining;
|
||||
int strLen = -1;
|
||||
for (int z = 0; z < reader.Remaining; z++)
|
||||
{
|
||||
if (ip[z] == '"')
|
||||
{
|
||||
strLen = z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strLen < 1)
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan));
|
||||
|
||||
reader.Pointer += strLen + 1;// "
|
||||
reader.Remaining -= strLen + 1;// "
|
||||
|
||||
int days, hours, minutes, seconds, fraction;
|
||||
days = hours = minutes = seconds = fraction = 0;
|
||||
|
||||
bool isNegative, pastDays, pastHours, pastMinutes, pastSeconds;
|
||||
isNegative = pastDays = pastHours = pastMinutes = pastSeconds = false;
|
||||
|
||||
var ixOfLastPeriod = -1;
|
||||
var part = 0;
|
||||
|
||||
int i;
|
||||
|
||||
if (ip[0] == '-')
|
||||
{
|
||||
isNegative = true;
|
||||
i = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for (; i < strLen; i++)
|
||||
{
|
||||
var c = ip[i];
|
||||
if (c == '.')
|
||||
{
|
||||
ixOfLastPeriod = i;
|
||||
|
||||
if (!pastDays)
|
||||
{
|
||||
days = part;
|
||||
part = 0;
|
||||
pastDays = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pastSeconds)
|
||||
{
|
||||
seconds = part;
|
||||
part = 0;
|
||||
pastSeconds = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan));
|
||||
}
|
||||
|
||||
if (c == ':')
|
||||
{
|
||||
if (!pastHours)
|
||||
{
|
||||
hours = part;
|
||||
part = 0;
|
||||
pastHours = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pastMinutes)
|
||||
{
|
||||
minutes = part;
|
||||
part = 0;
|
||||
pastMinutes = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan));
|
||||
}
|
||||
|
||||
if (c < '0' || c > '9')
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan));
|
||||
}
|
||||
|
||||
part *= 10;
|
||||
part += c - '0';
|
||||
}
|
||||
|
||||
if (!pastSeconds)
|
||||
{
|
||||
seconds = part;
|
||||
pastSeconds = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fraction = part;
|
||||
}
|
||||
|
||||
if (!pastHours || !pastMinutes || !pastSeconds)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Missing required portion of TimeSpan");
|
||||
}
|
||||
|
||||
var msInt = 0;
|
||||
if (fraction != 0)
|
||||
{
|
||||
var sizeOfFraction = strLen - (ixOfLastPeriod + 1);
|
||||
|
||||
if (sizeOfFraction > 7)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Fractional part of TimeSpan too large");
|
||||
}
|
||||
|
||||
var fracOfSecond = part / DivideFractionBy[sizeOfFraction - 1];
|
||||
var ms = fracOfSecond * 1000.0;
|
||||
msInt = (int)ms;
|
||||
if (ms > msInt)
|
||||
return TimeSpan.Parse(reader.SubString(reader.Length - start, strLen));
|
||||
}
|
||||
|
||||
var ret = new TimeSpan(days, hours, minutes, seconds, msInt);
|
||||
if (isNegative)
|
||||
{
|
||||
ret = ret.Negate();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
static unsafe TimeSpan _ReadISO8601TimeSpan(JsonReader reader)
|
||||
{
|
||||
const ulong ticksPerDay = 864000000000;
|
||||
|
||||
const ulong ticksPerWeek = ticksPerDay * 7;
|
||||
const ulong ticksPerMonth = ticksPerDay * 30;
|
||||
const ulong ticksPerYear = ticksPerDay * 365;
|
||||
|
||||
// Format goes like so:
|
||||
// - (-)P(([n]Y)([n]M)([n]D))(T([n]H)([n]M)([n]S))
|
||||
// - P[n]W
|
||||
char* ip = reader.Pointer;
|
||||
int len = -1;
|
||||
for (int i = 0; i < reader.Remaining; i++)
|
||||
{
|
||||
if (ip[i] == '"')
|
||||
{
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 1)
|
||||
throw new JsonWrongCharacterException(reader);
|
||||
|
||||
reader.Pointer += len + 1;
|
||||
reader.Remaining -= len + 1;
|
||||
|
||||
var ix = 0;
|
||||
var isNegative = false;
|
||||
|
||||
var c = ip[ix];
|
||||
if (c == '-')
|
||||
{
|
||||
isNegative = true;
|
||||
ix++;
|
||||
}
|
||||
|
||||
if (ix >= len)
|
||||
{
|
||||
throw new JsonWrongCharacterException("Expected P, instead TimeSpan string ended");
|
||||
}
|
||||
|
||||
c = ip[ix];
|
||||
if (c != 'P')
|
||||
{
|
||||
throw new JsonWrongCharacterException("Expected P, found " + c.ToString());
|
||||
}
|
||||
|
||||
ix++; // skip 'P'
|
||||
|
||||
var hasTimePart = ISO8601TimeSpan_ReadDatePart(ip, len, ref ix, out long year, out long month, out long week, out long day);
|
||||
|
||||
if (week != -1 && (year != -1 || month != -1 || day != -1))
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Week part of TimeSpan defined along with one or more of year, month, or day");
|
||||
}
|
||||
|
||||
if (week != -1 && hasTimePart)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "TimeSpans with a week defined cannot also have a time defined");
|
||||
}
|
||||
|
||||
if (year == -1) year = 0;
|
||||
if (month == -1) month = 0;
|
||||
if (week == -1) week = 0;
|
||||
if (day == -1) day = 0;
|
||||
|
||||
ulong timeTicks;
|
||||
|
||||
if (hasTimePart)
|
||||
{
|
||||
ix++; // skip 'T'
|
||||
ISO8601TimeSpan_ReadTimePart(ip, len, ref ix, out timeTicks);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeTicks = 0;
|
||||
}
|
||||
|
||||
ulong ticks = 0;
|
||||
if (year != 0)
|
||||
{
|
||||
ticks += ((ulong)year) * ticksPerYear;
|
||||
}
|
||||
|
||||
if (month != 0)
|
||||
{
|
||||
// .NET (via XmlConvert) converts months to years
|
||||
// This isn't inkeeping with the spec, but of the bad choices... I choose this one
|
||||
var yearsFromMonths = ((ulong)month) / 12;
|
||||
var monthsAfterYears = ((ulong)month) % 12;
|
||||
ticks += yearsFromMonths * ticksPerYear + monthsAfterYears * ticksPerMonth;
|
||||
}
|
||||
|
||||
if (week != 0)
|
||||
{
|
||||
// ISO8601 defines weeks as 7 days, so don't convert weeks to months or years (even if that may seem more sensible)
|
||||
ticks += ((ulong)week) * ticksPerWeek;
|
||||
}
|
||||
|
||||
ticks += ((ulong)day) * ticksPerDay + timeTicks;
|
||||
|
||||
if (ticks >= MaxTicks && !isNegative)
|
||||
{
|
||||
return TimeSpan.MaxValue;
|
||||
}
|
||||
|
||||
if (ticks >= MinTicks && isNegative)
|
||||
{
|
||||
return TimeSpan.MinValue;
|
||||
}
|
||||
|
||||
var ret = new TimeSpan((long)ticks);
|
||||
if (isNegative)
|
||||
{
|
||||
ret = ret.Negate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
static unsafe bool ISO8601TimeSpan_ReadDatePart(char* ip, int strLen, ref int ix, out long year, out long month, out long week, out long day)
|
||||
{
|
||||
year = month = week = day = -1;
|
||||
|
||||
bool yearSeen, monthSeen, weekSeen, daySeen;
|
||||
yearSeen = monthSeen = weekSeen = daySeen = false;
|
||||
|
||||
while (ix != strLen)
|
||||
{
|
||||
if (ip[ix] == 'T')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var part = ISO8601TimeSpan_ReadPart(ip, strLen, ref ix, out int whole, out int fraction, out int fracLen);
|
||||
|
||||
if (fracLen != 0)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Fractional values are not supported in the year, month, day, or week parts of an ISO8601 TimeSpan");
|
||||
}
|
||||
|
||||
if (part == 'Y')
|
||||
{
|
||||
if (yearSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Year part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
if (monthSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Year part of TimeSpan seen after month already parsed");
|
||||
}
|
||||
|
||||
if (daySeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Year part of TimeSpan seen after day already parsed");
|
||||
}
|
||||
|
||||
year = whole;
|
||||
yearSeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part == 'M')
|
||||
{
|
||||
if (monthSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Month part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
if (daySeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Month part of TimeSpan seen after day already parsed");
|
||||
}
|
||||
|
||||
month = whole;
|
||||
monthSeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part == 'W')
|
||||
{
|
||||
if (weekSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Week part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
week = whole;
|
||||
weekSeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part == 'D')
|
||||
{
|
||||
if (daySeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Day part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
day = whole;
|
||||
daySeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Expected Y, M, W, or D but found: " + part);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
static unsafe char ISO8601TimeSpan_ReadPart(char* ip, int strLen, ref int ix, out int whole, out int fraction, out int fracLen)
|
||||
{
|
||||
var part = 0;
|
||||
while (true)
|
||||
{
|
||||
var c = ip[ix];
|
||||
|
||||
if (c == '.' || c == ',')
|
||||
{
|
||||
whole = part;
|
||||
break;
|
||||
}
|
||||
|
||||
ix++;
|
||||
if (c < '0' || c > '9' || ix == strLen)
|
||||
{
|
||||
whole = part;
|
||||
fraction = 0;
|
||||
fracLen = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
part *= 10;
|
||||
part += c - '0';
|
||||
}
|
||||
|
||||
var ixOfPeriod = ix;
|
||||
|
||||
ix++; // skip the '.' or ','
|
||||
part = 0;
|
||||
while (true)
|
||||
{
|
||||
var c = ip[ix];
|
||||
|
||||
ix++;
|
||||
if (c < '0' || c > '9' || ix == strLen)
|
||||
{
|
||||
fraction = part;
|
||||
fracLen = ix - 1 - (ixOfPeriod + 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
part *= 10;
|
||||
part += c - '0';
|
||||
}
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
static unsafe void ISO8601TimeSpan_ReadTimePart(char* str, int strLen, ref int ix, out ulong ticks)
|
||||
{
|
||||
const ulong ticksPerHour = 36000000000;
|
||||
const ulong ticksPerMinute = 600000000;
|
||||
const ulong ticksPerSecond = 10000000;
|
||||
|
||||
ticks = 0;
|
||||
|
||||
bool hourSeen, minutesSeen, secondsSeen;
|
||||
hourSeen = minutesSeen = secondsSeen = false;
|
||||
|
||||
var fracSeen = false;
|
||||
|
||||
while (ix != strLen)
|
||||
{
|
||||
if (fracSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Expected Time part of TimeSpan to end");
|
||||
}
|
||||
|
||||
char part = ISO8601TimeSpan_ReadPart(str, strLen, ref ix, out int whole, out int fraction, out int fracLen);
|
||||
|
||||
if (fracLen != 0)
|
||||
{
|
||||
fracSeen = true;
|
||||
}
|
||||
|
||||
if (part == 'H')
|
||||
{
|
||||
if (hourSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Hour part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
if (minutesSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Hour part of TimeSpan seen after minutes already parsed");
|
||||
}
|
||||
|
||||
if (secondsSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Hour part of TimeSpan seen after seconds already parsed");
|
||||
}
|
||||
|
||||
ticks += (ulong)whole * ticksPerHour + ISO8601TimeSpan_FractionToTicks(9, fraction * 36, fracLen);
|
||||
hourSeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part == 'M')
|
||||
{
|
||||
if (minutesSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Minute part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
if (secondsSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Minute part of TimeSpan seen after seconds already parsed");
|
||||
}
|
||||
|
||||
ticks += (ulong)whole * ticksPerMinute + ISO8601TimeSpan_FractionToTicks(8, fraction * 6, fracLen);
|
||||
minutesSeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part == 'S')
|
||||
{
|
||||
if (secondsSeen)
|
||||
{
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Seconds part of TimeSpan seen twice");
|
||||
}
|
||||
|
||||
ticks += (ulong)whole * ticksPerSecond + ISO8601TimeSpan_FractionToTicks(7, fraction, fracLen);
|
||||
secondsSeen = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(typeof(TimeSpan), "Expected H, M, or S but found: " + part);
|
||||
}
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
static ulong ISO8601TimeSpan_FractionToTicks(int maxLen, int fraction, int fracLen)
|
||||
{
|
||||
if (fracLen == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fracLen > maxLen)
|
||||
{
|
||||
fraction /= (int)Pow10(fracLen - maxLen);
|
||||
fracLen = maxLen;
|
||||
}
|
||||
|
||||
return (ulong)(fraction * Pow10(maxLen - fracLen));
|
||||
}
|
||||
static readonly long[] PowersOf10 = {
|
||||
1L,
|
||||
10L,
|
||||
100L,
|
||||
1000L,
|
||||
10000L,
|
||||
100000L,
|
||||
1000000L,
|
||||
10000000L,
|
||||
100000000L
|
||||
};
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static long Pow10(int power)
|
||||
{
|
||||
if (power < PowersOf10.Length)
|
||||
return PowersOf10[power];
|
||||
return (long)Math.Pow(10, power);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class DefaultJsonResolve : JsonResolveBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class DeserializeObjectJump
|
||||
{
|
||||
private static SpinLock _spinLock = new SpinLock();
|
||||
|
||||
private static readonly Dictionary<Type, Func<string, JsonDeserializeHandler, object>> JumpStringConvertDics =
|
||||
new Dictionary<Type, Func<string, JsonDeserializeHandler, object>>();
|
||||
|
||||
private static readonly Dictionary<Type, Func<StreamReader, JsonDeserializeHandler, object>> JumpStreamConvertDics =
|
||||
new Dictionary<Type, Func<StreamReader, JsonDeserializeHandler, object>>();
|
||||
|
||||
internal static object GetThreadSafetyJumpFunc(string json, Type t, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (JumpStringConvertDics.TryGetValue(t, out var fc))
|
||||
return fc(json, handler);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
bool i = false;
|
||||
_spinLock.Enter(ref i);
|
||||
if (!JumpStringConvertDics.TryGetValue(t, out fc))
|
||||
{
|
||||
fc = GenerateJumpStringConvertFunc(t);
|
||||
JumpStringConvertDics.Add(t, fc);
|
||||
}
|
||||
return fc(json, handler);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_spinLock.Exit();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
internal static object GetThreadSafetyJumpFunc(StreamReader stream, Type t, JsonDeserializeHandler handler)
|
||||
{
|
||||
if (JumpStreamConvertDics.TryGetValue(t, out var fc))
|
||||
return fc(stream, handler);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
bool i = false;
|
||||
_spinLock.Enter(ref i);
|
||||
if (!JumpStreamConvertDics.TryGetValue(t, out fc))
|
||||
{
|
||||
fc = GenerateJumpStreamConvertFunc(t);
|
||||
JumpStreamConvertDics.Add(t, fc);
|
||||
}
|
||||
return fc(stream, handler);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_spinLock.Exit();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
internal static Func<string, JsonDeserializeHandler, object> GenerateJumpStringConvertFunc(Type t)
|
||||
{
|
||||
var genericType = typeof(ResolveProvider<>).MakeGenericType(t);
|
||||
var jsonEx = Expression.Parameter(typeof(string), "json");
|
||||
var handlerEx = Expression.Parameter(typeof(JsonDeserializeHandler), "handler");
|
||||
var body = Expression.Convert(Expression.Call(genericType.GetMethod("Convert",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Static,null, new Type[] { typeof(string), typeof(JsonDeserializeHandler) },null), jsonEx, handlerEx), typeof(object));
|
||||
return Expression.Lambda<Func<string, JsonDeserializeHandler, object>>(body, jsonEx, handlerEx).Compile();
|
||||
}
|
||||
internal static Func<StreamReader, JsonDeserializeHandler, object> GenerateJumpStreamConvertFunc(Type t)
|
||||
{
|
||||
var genericType = typeof(ResolveProvider<>).MakeGenericType(t);
|
||||
var jsonEx = Expression.Parameter(typeof(StreamReader), "reader");
|
||||
var handlerEx = Expression.Parameter(typeof(JsonDeserializeHandler), "handler");
|
||||
var body = Expression.Convert(Expression.Call(genericType.GetMethod("Convert", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static ,null,new Type[] { typeof(StreamReader), typeof(JsonDeserializeHandler) },null), jsonEx, handlerEx), typeof(object));
|
||||
return Expression.Lambda<Func<StreamReader, JsonDeserializeHandler, object>>(body, jsonEx, handlerEx).Compile();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.Array)]
|
||||
internal class ArrayBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type type)
|
||||
{
|
||||
Type arrayItemType = type.GetElementType();
|
||||
Expression[] methodListCall = new Expression[11];
|
||||
LabelTarget returnTarget = Expression.Label(type, "returnLable");
|
||||
/*
|
||||
if (reader.ReadNullOrArrayLeft())
|
||||
return null;
|
||||
*/
|
||||
Expression ifReadNullOrArrayLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrArrayLeft), Expression.Return(returnTarget, Expression.Constant(null, type)));
|
||||
methodListCall[0] = ifReadNullOrArrayLeftReturnNull;
|
||||
|
||||
/*
|
||||
int arrayLength=reader._GetArrayLength;
|
||||
T[] array=new [arrayLength];
|
||||
*/
|
||||
ParameterExpression arrayLength = Expression.Variable(typeof(int), "arrayLength");
|
||||
methodListCall[1] = Expression.Assign(arrayLength, Expression.Call(ExpressionMembers.Reader, JsonReader._GetArrayLength, ExpressionMembers.JsonDeserializeHandler));
|
||||
NewExpression aryCtor = Expression.New(type.GetConstructors()[0], arrayLength);
|
||||
ParameterExpression array = Expression.Variable(type, "array");
|
||||
methodListCall[2] = Expression.Assign(array, aryCtor);
|
||||
|
||||
/*
|
||||
if(arrayLength==0)
|
||||
goto ReadArrayRightLabel;
|
||||
*/
|
||||
LabelTarget readArrayRightLabel = Expression.Label(typeof(void), "ReadArrayRightLabel");
|
||||
methodListCall[3] = Expression.IfThen(Expression.Equal(arrayLength, Expression.Constant(0)), Expression.Goto(readArrayRightLabel));
|
||||
|
||||
/*
|
||||
int moveNext=1;
|
||||
*/
|
||||
methodListCall[4] = ExpressionMembers.MoveNextAssignOne;
|
||||
|
||||
/*
|
||||
int idx=0;
|
||||
*/
|
||||
ParameterExpression idx = Expression.Variable(typeof(int), "idx");
|
||||
methodListCall[5] = Expression.Assign(idx, Expression.Constant(0));
|
||||
|
||||
/*
|
||||
while(moveNext-->0)
|
||||
{}
|
||||
*/
|
||||
LabelTarget loopBreak = Expression.Label("loopBreak");
|
||||
LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
|
||||
ReturnFunc<Expression>(() =>
|
||||
{
|
||||
Expression[] methodCall = new Expression[3];
|
||||
/*
|
||||
ary[idx]=item;
|
||||
*/
|
||||
methodCall[0] = Expression.Assign(Expression.ArrayAccess(array, idx), ExpressionMembers.GetMethodCall(arrayItemType));
|
||||
|
||||
/*
|
||||
if(reader.ReadBoolComma()==true)
|
||||
moveNext++;
|
||||
*/
|
||||
methodCall[1] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;
|
||||
|
||||
/*
|
||||
idx++;
|
||||
*/
|
||||
methodCall[2] = Expression.PostIncrementAssign(idx);
|
||||
return Expression.Block(methodCall); ;
|
||||
})
|
||||
, Expression.Break(loopBreak)));
|
||||
methodListCall[6] = Expression.Block(loopExpression, Expression.Label(loopBreak));
|
||||
|
||||
/*
|
||||
ReadArrayRightLabel:
|
||||
reader.ReadArrayRight()
|
||||
*/
|
||||
methodListCall[7] = Expression.Label(readArrayRightLabel);
|
||||
methodListCall[8] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadArrayRight);
|
||||
|
||||
/*
|
||||
return list;
|
||||
*/
|
||||
GotoExpression returnExpression = Expression.Return(returnTarget, array);
|
||||
LabelExpression returnLabel = Expression.Label(returnTarget, array);
|
||||
methodListCall[9] = returnExpression;
|
||||
methodListCall[10] = returnLabel;
|
||||
|
||||
return Expression.Block(new[] { arrayLength, array, idx, ExpressionMembers.MoveNext }, methodListCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class BuildFactory
|
||||
{
|
||||
static BuildFactory()
|
||||
{
|
||||
var types = DeserializeBootTable.Table.ExpressionBuildTypes;
|
||||
foreach (var item in types)
|
||||
{
|
||||
ExpressionBuildTypeAttribute expressionBuildTypeAttribute = (ExpressionBuildTypeAttribute)item.GetCustomAttributes(false).First(e => e.GetType() == typeof(ExpressionBuildTypeAttribute));
|
||||
BuildMethodDics.Add(expressionBuildTypeAttribute._deserializeBuildType, item.GetMethod("Build", BindingFlags.Static | BindingFlags.NonPublic));
|
||||
}
|
||||
DeserializeBootTable.Table.ExpressionBuildTypes = null;
|
||||
}
|
||||
|
||||
internal static Dictionary<Type, Expression> DEBUGSURVEY = new Dictionary<Type, Expression>();
|
||||
|
||||
static Dictionary<DeserializeBuildTypeEnum, MethodInfo> BuildMethodDics = new Dictionary<DeserializeBuildTypeEnum, MethodInfo>();
|
||||
internal static ResolveDelegate<T> Build<T>(DeserializeBuildTypeEnum buildTypeEnum, params object[] objs)
|
||||
{
|
||||
ParameterExpression[] pars = { ExpressionMembers.Reader, ExpressionMembers.JsonDeserializeHandler };
|
||||
|
||||
BlockExpression body = (BlockExpression)BuildMethodDics[buildTypeEnum].Invoke(null, objs);
|
||||
|
||||
#if DEBUG
|
||||
Type t = typeof(T);
|
||||
DEBUGSURVEY.Add(t, body);
|
||||
#endif
|
||||
|
||||
#if VIEW && NET45
|
||||
var methodBuilder = typeBuilder.DefineMethod($"Deserialize_{typeof(T).Name}", System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public, typeof(T), new Type[] { typeof(JsonReader), typeof(JsonDeserializeHandler) });
|
||||
|
||||
Expression.Lambda<ResolveDelegate<T>>(
|
||||
body, pars).CompileToMethod(methodBuilder);
|
||||
#endif
|
||||
|
||||
ResolveDelegate<T> action = Expression.Lambda<ResolveDelegate<T>>(body, pars).Compile();
|
||||
return action;
|
||||
}
|
||||
|
||||
#if VIEW && NET45
|
||||
#if DEBUG
|
||||
static string suffix = "_Debug";
|
||||
#else
|
||||
static string suffix = "_Release";
|
||||
#endif
|
||||
static string name = $"Deserialize_CodeView{suffix}";
|
||||
static System.Reflection.Emit.AssemblyBuilder assemblyBuilder = System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(new System.Reflection.AssemblyName(name), System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave);
|
||||
static System.Reflection.Emit.ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name, name + ".dll");
|
||||
static System.Reflection.Emit.TypeBuilder typeBuilder = moduleBuilder.DefineType("Program");
|
||||
|
||||
|
||||
#endif
|
||||
internal static void Save()
|
||||
{
|
||||
#if VIEW && NET45
|
||||
typeBuilder.CreateType();
|
||||
assemblyBuilder.Save(name + ".dll");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal enum DeserializeBuildTypeEnum
|
||||
{
|
||||
Dictionary,
|
||||
Collection,
|
||||
KeyValueObject,
|
||||
CtorInject,
|
||||
Array,
|
||||
KeyValuePair,
|
||||
Dynamic,
|
||||
WrongGenericKey,
|
||||
MultiArray,
|
||||
Lazy
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.Collection)]
|
||||
internal class CollectionBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type defindType, Type instanceType, Type convertType,Type arrayItemType)
|
||||
{
|
||||
/*
|
||||
//defind:IEnumerable<string> new: List<string> convert: List<string>
|
||||
IEnumerable<string> li = new List<string>();
|
||||
List<string> list = (List<string>)li;
|
||||
|
||||
//defind:ArrayList new:ArrayList convert: IList/ArrayList
|
||||
ArrayList v = new ArrayList();
|
||||
var df = (IList)v;
|
||||
*/
|
||||
|
||||
Expression[] methodListCall = new Expression[9];
|
||||
|
||||
LabelTarget returnTarget = Expression.Label(defindType, "returnLable");
|
||||
Expression ifReadNullOrArrayLeftReturnNull;
|
||||
if (!defindType.IsValueType)
|
||||
{
|
||||
/*
|
||||
if (reader.ReadNullOrArrayLeft())
|
||||
return null;
|
||||
*/
|
||||
ifReadNullOrArrayLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrArrayLeft), Expression.Return(returnTarget, Expression.Constant(null, defindType)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ifReadNullOrArrayLeftReturnNull = Expression.Call(ExpressionMembers.Reader,JsonReader._ReadArrayLeft);
|
||||
}
|
||||
methodListCall[0] = ifReadNullOrArrayLeftReturnNull;
|
||||
|
||||
/*
|
||||
List<> list =new List<>();
|
||||
*/
|
||||
NewExpression listCtor = Expression.New(instanceType);
|
||||
ParameterExpression list = Expression.Variable(defindType, "list");
|
||||
methodListCall[1] = Expression.Assign(list, listCtor);
|
||||
|
||||
/*
|
||||
if(reader.ReadBoolArrayRight)
|
||||
return list;
|
||||
*/
|
||||
methodListCall[2] = (Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolArrayRight), Expression.Return(returnTarget, list)));
|
||||
|
||||
/*
|
||||
ICollection<int> iCollec = (ICollection<int>)list;
|
||||
iCollec.Add(ReadInt())
|
||||
*/
|
||||
MethodInfo iCollecAdd = convertType.GetMethod("Add",BindingFlags.Public|BindingFlags.Instance);
|
||||
|
||||
ParameterExpression iCollec = Expression.Variable(convertType, "iDic");
|
||||
methodListCall[3] = Expression.Assign(iCollec, Expression.Convert(list, convertType));
|
||||
|
||||
/*
|
||||
int moveNext=1;
|
||||
*/
|
||||
methodListCall[4] = ExpressionMembers.MoveNextAssignOne;
|
||||
|
||||
/*
|
||||
while(moveNext-->0)
|
||||
{}
|
||||
*/
|
||||
LabelTarget loopBreak = Expression.Label("loopBreak");
|
||||
LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
|
||||
ReturnFunc<Expression>(() =>
|
||||
{
|
||||
Expression[] methodCall = new Expression[2];
|
||||
/*
|
||||
list.Add(item);
|
||||
*/
|
||||
methodCall[0] = Expression.Call(iCollec, iCollecAdd, ExpressionMembers.GetMethodCall(arrayItemType));
|
||||
/*
|
||||
if(reader.ReadBoolComma()==true)
|
||||
moveNext++;
|
||||
*/
|
||||
methodCall[1] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;
|
||||
|
||||
return Expression.Block(methodCall); ;
|
||||
})
|
||||
, Expression.Break(loopBreak)));
|
||||
methodListCall[5] = Expression.Block(loopExpression, Expression.Label(loopBreak));
|
||||
|
||||
/*
|
||||
reader.ReadArrayRight()
|
||||
*/
|
||||
methodListCall[6] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadArrayRight);
|
||||
|
||||
/*
|
||||
return list;
|
||||
*/
|
||||
GotoExpression returnExpression = Expression.Return(returnTarget, list);
|
||||
LabelExpression returnLabel = Expression.Label(returnTarget, list);
|
||||
methodListCall[7] = returnExpression;
|
||||
methodListCall[8] = returnLabel;
|
||||
|
||||
return Expression.Block(new[] { iCollec, list, ExpressionMembers.MoveNext }, methodListCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.CtorInject)]
|
||||
internal class CtorInjectBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type type, Type injectType, ConstructorInfo ctr)
|
||||
{
|
||||
LabelTarget returnTarget = Expression.Label(type, "returnLable");
|
||||
|
||||
ParameterExpression inject = Expression.Variable(injectType, "inject");
|
||||
|
||||
if (!type.IsValueType)
|
||||
return Expression.Block(new[] { inject },
|
||||
|
||||
Expression.Assign(inject, ExpressionMembers.GetMethodCall(injectType)),//inject = Read<T>(); T-->
|
||||
Expression.IfThenElse(
|
||||
Expression.Equal(inject, Expression.Constant(null, injectType)),
|
||||
Expression.Return(returnTarget, Expression.Constant(null, type)),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.New(ctr, inject), type))),
|
||||
Expression.Label(returnTarget, Expression.Constant(null, type))
|
||||
);
|
||||
|
||||
return Expression.Block(new[] { inject },
|
||||
Expression.Assign(inject, ExpressionMembers.GetMethodCall(injectType)),
|
||||
Expression.Return(returnTarget, Expression.Convert(Expression.New(ctr, inject), type)),
|
||||
Expression.Label(returnTarget, Expression.Convert(Expression.New(ctr, inject), type)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.Dictionary)]
|
||||
internal class DictionaryBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type defindType, Type instanceType, Type convertType,Type keyType,Type valueType)
|
||||
{
|
||||
/*
|
||||
* defind:ExpandoObject new:ExpandoObject convert:IDictionary<string, object>
|
||||
ExpandoObject ss = new ExpandoObject();
|
||||
IDictionary<string, object> dic = (IDictionary<string, object>)ss;
|
||||
|
||||
hashtable
|
||||
*/
|
||||
|
||||
|
||||
Expression[] methodDictionaryCall = new Expression[9];
|
||||
|
||||
LabelTarget returnTarget = Expression.Label(defindType, "returnLable");
|
||||
Expression ifReadNullOrObjLeftReturnNull;
|
||||
|
||||
if (!defindType.IsValueType)
|
||||
/*
|
||||
if (reader.ReadNullOrObjLeft())
|
||||
return null;
|
||||
*/
|
||||
ifReadNullOrObjLeftReturnNull = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrObjLeft), Expression.Return(returnTarget, Expression.Constant(null, defindType)));
|
||||
else
|
||||
{
|
||||
ifReadNullOrObjLeftReturnNull= Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjLeft);
|
||||
}
|
||||
methodDictionaryCall[0] = ifReadNullOrObjLeftReturnNull;
|
||||
|
||||
/*
|
||||
Dictionary<> dictionary =new Dictionary<>();
|
||||
*/
|
||||
NewExpression dictionaryCtor = Expression.New(instanceType);
|
||||
ParameterExpression dictionary = Expression.Variable(defindType, "dictionary");
|
||||
methodDictionaryCall[1] = Expression.Assign(dictionary, dictionaryCtor);
|
||||
|
||||
/*
|
||||
if(reader.ReadBoolObjRight)
|
||||
return dictionary;
|
||||
*/
|
||||
methodDictionaryCall[2] = (Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight), Expression.Return(returnTarget, dictionary)));
|
||||
|
||||
/*
|
||||
IDictionary iDic = dictionary;
|
||||
IDictionary<,> iDic = dictionary;
|
||||
*/
|
||||
MethodInfo iDicAdd = convertType.GetMethod("Add");
|
||||
ParameterExpression iDic = Expression.Variable(convertType, "iDic");
|
||||
methodDictionaryCall[3] = Expression.Assign(iDic, Expression.Convert(dictionary, convertType));
|
||||
|
||||
/*
|
||||
int moveNext=2;
|
||||
*/
|
||||
methodDictionaryCall[4] = ExpressionMembers.MoveNextAssignOne;
|
||||
|
||||
ParameterExpression key = Expression.Variable(keyType, "key");
|
||||
ParameterExpression value = Expression.Variable(valueType, "value");
|
||||
|
||||
/*
|
||||
while(moveNext-->0)
|
||||
{}
|
||||
*/
|
||||
LabelTarget loopBreak = Expression.Label("loopBreak");
|
||||
LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
|
||||
ReturnFunc<Expression>(() =>
|
||||
{
|
||||
Expression[] methodCall = new Expression[5];
|
||||
|
||||
/*
|
||||
ReadKey()
|
||||
*/
|
||||
methodCall[0] = ExpressionMembers.GenerateKeyValuePairByReadKey(keyType, key);
|
||||
/*
|
||||
reader.ReadColon()
|
||||
*/
|
||||
methodCall[1] = (Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon));
|
||||
/*
|
||||
value = ResolveProvider<ValueType>.InvokeGet(reader, handler);
|
||||
*/
|
||||
methodCall[2] = (Expression.Assign(value, ExpressionMembers.GetMethodCall(valueType)));
|
||||
/*
|
||||
iDic.Add(key,value);
|
||||
*/
|
||||
methodCall[3] = (Expression.Call(iDic, iDicAdd, key, value));
|
||||
/*
|
||||
if(reader.ReadComma()==true)
|
||||
moveNext++;
|
||||
*/
|
||||
methodCall[4] = (ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement);
|
||||
|
||||
return Expression.Block(methodCall); ;
|
||||
})
|
||||
, Expression.Break(loopBreak)));
|
||||
methodDictionaryCall[5] = Expression.Block(loopExpression, Expression.Label(loopBreak));
|
||||
|
||||
/*
|
||||
reader.ReadObjRight();
|
||||
*/
|
||||
methodDictionaryCall[6] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight);
|
||||
|
||||
/*
|
||||
return dictionary
|
||||
*/
|
||||
GotoExpression returnExpression = Expression.Return(returnTarget, dictionary);
|
||||
LabelExpression returnLabel = Expression.Label(returnTarget, dictionary);
|
||||
methodDictionaryCall[7] = returnExpression;
|
||||
methodDictionaryCall[8] = returnLabel;
|
||||
|
||||
return Expression.Block(new[] { iDic, dictionary, key, value, ExpressionMembers.MoveNext }, methodDictionaryCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.Dynamic)]
|
||||
internal class DynamicBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type type)
|
||||
{
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
LabelTarget returnValueLable = Expression.Label(type, "returnValue");
|
||||
|
||||
var c = type.GetProperties();
|
||||
ParameterExpression[] ctorArgs = null;
|
||||
if (c.Length > 0)
|
||||
{
|
||||
ctorArgs = new ParameterExpression[c.Length];
|
||||
for (int i = 0; i < c.Length; i++)
|
||||
{
|
||||
ctorArgs[i] = Expression.Variable(c[i].PropertyType);
|
||||
if (c[i].PropertyType.IsValueType)
|
||||
methodCall.Add(Expression.Assign(ctorArgs[i], Expression.New(c[i].PropertyType)));
|
||||
else
|
||||
methodCall.Add(Expression.Assign(ctorArgs[i], Expression.Constant(null, c[i].PropertyType)));
|
||||
}
|
||||
}
|
||||
methodCall.Add(Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrObjLeft), Expression.Return(returnValueLable, Expression.Constant(null, type))));
|
||||
|
||||
methodCall.Add(Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight), Expression.Return(returnValueLable, c.Length == 0 ? Expression.New(type) : Expression.New(type.GetConstructors()[0], ctorArgs))));
|
||||
/*
|
||||
read.ReadLeftOrNull()
|
||||
return null
|
||||
if(_ReadBoolObjRight)
|
||||
reture new (default)
|
||||
int a;
|
||||
string b;
|
||||
i=2
|
||||
while(i-->0)
|
||||
{
|
||||
var s= readString;
|
||||
ReadColon()
|
||||
switch(s)
|
||||
case(s=='Name')
|
||||
b=readValue
|
||||
|
||||
case(s=='Age')
|
||||
a=readValue
|
||||
arrig=true
|
||||
if(!arrig)
|
||||
throw
|
||||
if(comma())
|
||||
i++;
|
||||
}
|
||||
readRight();
|
||||
return new dynamicModel(a,b)
|
||||
*/
|
||||
List<ParameterExpression> args = new List<ParameterExpression>() { };
|
||||
if (c.Length > 0)
|
||||
{
|
||||
ParameterExpression str = Expression.Variable(typeof(string), "str");
|
||||
LabelTarget whileBreak = Expression.Label();
|
||||
methodCall.Add(ExpressionMembers.MoveNextAssignOne);
|
||||
LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
|
||||
ReturnFunc<Expression>(() =>
|
||||
{
|
||||
Expression[] expressions = new Expression[5];
|
||||
expressions[0] = Expression.Assign(str, Expression.Call(ExpressionMembers.Reader, JsonReader._ReadString));
|
||||
expressions[1] = Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon);
|
||||
expressions[2] = Expression.Switch(str,
|
||||
ReturnFunc(() =>
|
||||
{
|
||||
SwitchCase[] switchCases = new SwitchCase[c.Length];
|
||||
for (int i = 0; i < c.Length; i++)
|
||||
{
|
||||
switchCases[i] = Expression.SwitchCase(
|
||||
Expression.Block(typeof(void),
|
||||
Expression.Assign(ctorArgs[i], ExpressionMembers.GetMethodCall(c[i].PropertyType)),
|
||||
ExpressionMembers.IsArriveAssignTrue
|
||||
)
|
||||
, Expression.Constant(c[i].Name, typeof(string)));
|
||||
}
|
||||
return switchCases;
|
||||
})
|
||||
);
|
||||
expressions[3] = Expression.IfThen(Expression.Equal(ExpressionMembers.IsArrive, Expression.Constant(false, typeof(bool))), Expression.Throw(Expression.New(JsonDeserializationTypeResolutionException._JsonDeserializationTypeResolutionExceptionMsgCtor, Expression.Constant("An error occurred parsing the dynamically typed key. The key does not match", typeof(string)))));
|
||||
expressions[4] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;
|
||||
return Expression.Block(expressions);
|
||||
}),
|
||||
Expression.Break(whileBreak)
|
||||
));
|
||||
methodCall.Add(loopExpression);
|
||||
methodCall.Add(Expression.Label(whileBreak));
|
||||
args.Add(str);
|
||||
args.AddRange(ctorArgs);
|
||||
}
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight));
|
||||
methodCall.Add(Expression.Return(returnValueLable, c.Length == 0 ? Expression.New(type) : Expression.New(type.GetConstructors()[0], ctorArgs)));
|
||||
methodCall.Add(Expression.Label(returnValueLable, Expression.Constant(null, type)));
|
||||
|
||||
|
||||
args.Add(ExpressionMembers.IsArrive);
|
||||
args.Add(ExpressionMembers.MoveNext);
|
||||
return Expression.Block(args, methodCall);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal static class ExpressionMembers
|
||||
{
|
||||
// -charVariable
|
||||
internal static readonly ParameterExpression CharVariable = Expression.Variable(typeof(char), "charVariable");
|
||||
|
||||
//- reader (FuncArgs)
|
||||
internal static readonly ParameterExpression Reader =
|
||||
Expression.Parameter(typeof(JsonReader), "reader");
|
||||
|
||||
//- reader.Remaining (FuncArgs.Member)
|
||||
internal static readonly MemberExpression Remaining =
|
||||
Expression.MakeMemberAccess(Reader, JsonReader._Remaining);
|
||||
|
||||
//- reader.GetChar() (FuncArgs.Func)
|
||||
internal static readonly Expression GetChar = Expression.Call(Reader,JsonReader._GetChar);
|
||||
|
||||
//- jsonDeserializeHandler (FuncArgs)
|
||||
internal static readonly ParameterExpression JsonDeserializeHandler =
|
||||
Expression.Parameter(typeof(JsonDeserializeHandler), "jsonDeserializeHandler");
|
||||
|
||||
//- jsonDeserializeHandler.jsonDeserializeOption (FuncArgs.Member)
|
||||
internal static readonly MemberExpression JsonDeserializeOption =
|
||||
Expression.MakeMemberAccess(JsonDeserializeHandler, Json.JsonDeserializeHandler. _Option
|
||||
);
|
||||
|
||||
//- jsonDeserializeHandler.jsonCharacterReadState
|
||||
internal static readonly MemberExpression JsonCharacterReadState =
|
||||
Expression.MakeMemberAccess(JsonDeserializeOption, Json.JsonDeserializeOption._JsonCharacterReadState);
|
||||
|
||||
//- jsonDeserializeOption.GlobalValueFormat
|
||||
internal static readonly MemberExpression GlobalValueFormat =
|
||||
Expression.MakeMemberAccess(JsonDeserializeOption, Json.JsonDeserializeOption._GlobalValueFormat);
|
||||
|
||||
//- jsonDeserializeOption.GlobalValueFormat!=null
|
||||
internal static readonly BinaryExpression GlobalValueFormatNotEqualNull = Expression.NotEqual(GlobalValueFormat,
|
||||
Expression.Constant(null, Json.JsonDeserializeOption._GlobalValueFormat.FieldType));
|
||||
|
||||
//- jsonDeserializeOption.GlobalKeyFormat
|
||||
internal static readonly MemberExpression GlobalKeyFormat =
|
||||
Expression.MakeMemberAccess(JsonDeserializeOption, Json.JsonDeserializeOption._GlobalKeyFormat);
|
||||
|
||||
//- jsonDeserializeOption.GlobalKeyFormat!=null
|
||||
internal static readonly BinaryExpression GlobalKeyFormatNotEqualNull = Expression.NotEqual(GlobalKeyFormat,
|
||||
Expression.Constant(null, Json.JsonDeserializeOption._GlobalKeyFormat.FieldType));
|
||||
|
||||
//- jsonDeserializeOption.GlobalKeyFormat==null
|
||||
internal static readonly BinaryExpression GlobalKeyFormatEqualNull = Expression.Equal(GlobalKeyFormat,
|
||||
Expression.Constant(null, Json.JsonDeserializeOption._GlobalKeyFormat.FieldType));
|
||||
|
||||
//- afterFormatKey
|
||||
internal static readonly ParameterExpression AfterFormatKey =
|
||||
Expression.Variable(typeof(string), "afterFormatKey");
|
||||
|
||||
//- moveNext (Func.LocalVariable)
|
||||
internal static readonly ParameterExpression MoveNext = Expression.Variable(typeof(int), "moveNext");
|
||||
|
||||
//- moveNext=1 (Func.LocalVariable.)
|
||||
internal static readonly BinaryExpression MoveNextAssignOne =
|
||||
Expression.Assign(MoveNext, Expression.Constant(1));
|
||||
|
||||
//- moveNext-->0
|
||||
internal static readonly BinaryExpression MoveNextDecrement =
|
||||
Expression.GreaterThan(Expression.PostDecrementAssign(MoveNext), Expression.Constant(0));
|
||||
|
||||
//- if(ReadBoolComma()==true) moveNext++;
|
||||
internal static readonly ConditionalExpression IfReadBoolCommaIsTrueSoMoveNextIncrement =
|
||||
Expression.IfThen(
|
||||
Expression.Equal(Expression.Call(Reader, JsonReader._ReadBoolComma),
|
||||
Expression.Constant(true, typeof(bool))),
|
||||
Expression.Assign(MoveNext, Expression.Increment(MoveNext)));
|
||||
|
||||
//- isArrive (Func.LocalVariable)
|
||||
internal static readonly ParameterExpression IsArrive = Expression.Variable(typeof(bool), "isArrive");
|
||||
|
||||
//- isArrive=true
|
||||
internal static readonly BinaryExpression IsArriveAssignTrue =
|
||||
Expression.Assign(IsArrive, Expression.Constant(true));
|
||||
|
||||
//- isArrive=false
|
||||
internal static readonly BinaryExpression IsArriveAssignFalse =
|
||||
Expression.Assign(IsArrive, Expression.Constant(false));
|
||||
|
||||
//- currentIdx
|
||||
internal static readonly ParameterExpression CurrentIdx = Expression.Variable(typeof(int), "currentIdx");
|
||||
|
||||
//- currentIdx= Length - reader.Remaining
|
||||
internal static readonly BinaryExpression CurrentIdxAssignReming = Expression.Assign(CurrentIdx,
|
||||
Expression.Subtract(Expression.MakeMemberAccess(Reader, JsonReader._Length), Remaining));
|
||||
|
||||
//- isValueFormat
|
||||
internal static readonly ParameterExpression IsValueFormat = Expression.Variable(typeof(bool), "isValueFormat");
|
||||
|
||||
//- isValueFormat==true
|
||||
internal static readonly BinaryExpression IsValueFormatEqualTrue =
|
||||
Expression.Equal(IsValueFormat, Expression.Constant(true, typeof(bool)));
|
||||
|
||||
//- valueLength
|
||||
internal static readonly ParameterExpression ValueLength = Expression.Variable(typeof(int), "valueLength");
|
||||
|
||||
//- valueLength=reader.Skipobj()
|
||||
internal static readonly BinaryExpression ValueLengthAssignSkipObj = Expression.Assign(ValueLength,
|
||||
Expression.Call(Reader, JsonReader._SkipObj, JsonDeserializeHandler));
|
||||
|
||||
//- reader.RemoveQuoteAndSubString(currentIdx,valueLength)
|
||||
internal static readonly Expression JsonRemoveQuoteAndSubstring =
|
||||
Expression.Call(Reader, JsonReader._RemoveQuoteAndSubString, CurrentIdx, ValueLength);
|
||||
|
||||
//- object formatResult = ValueFormat.ReadValueFormat( reader.Json.Substring(currentIdx,leng) ,out isValueFormat);
|
||||
internal static readonly ParameterExpression FormatResult = Expression.Variable(typeof(object), "formatResult");
|
||||
|
||||
internal static Expression GetMethodCall(Type type)
|
||||
{
|
||||
var realType = typeof(ResolveProvider<>).MakeGenericType(type);
|
||||
return Expression.Call(realType.GetMethod("InvokeGet", BindingFlags.NonPublic | BindingFlags.Static),
|
||||
Reader, JsonDeserializeHandler);
|
||||
}
|
||||
|
||||
internal static Expression GenerateKeyValuePairByReadKey(Type keyType, Expression keyPara)
|
||||
{
|
||||
List<Expression> lists = new List<Expression>();
|
||||
/*
|
||||
reader._ReadQuotes()
|
||||
*/
|
||||
if (keyType.IsPrimitive)
|
||||
lists.Add(Expression.Call(Reader, JsonReader._ReadQuotes));
|
||||
|
||||
/*
|
||||
key = ResolveProvider<KeyType>.InvokeGet(reader, handler);
|
||||
*/
|
||||
lists.Add(Expression.Assign(keyPara, GetMethodCall(keyType)));
|
||||
|
||||
/*
|
||||
if(getChar()!='"')
|
||||
throw new Ex
|
||||
*/
|
||||
if (keyType.IsPrimitive)
|
||||
lists.Add(Expression.IfThen(Expression.NotEqual(GetChar, Expression.Constant('"', typeof(char))),
|
||||
Expression.Throw(Expression.New(JsonWrongCharacterException._JsonWrongCharacterExceptionCtor, Reader)
|
||||
)));
|
||||
|
||||
return Expression.Block(lists);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,503 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.KeyValueObject)]
|
||||
internal class KeyValueObjectBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type type)
|
||||
{
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
LabelTarget returnValueLable = Expression.Label(type, "returnValue");
|
||||
|
||||
if (type.IsValueType)
|
||||
{
|
||||
/*
|
||||
ReadObjLeft()
|
||||
*/
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjLeft));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
if(_ReadNullOrObjLeft)
|
||||
return null;/return default(ValueType)
|
||||
*/
|
||||
Expression ifReadNullOrObjLeftReturnNull1 = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrObjLeft),
|
||||
Expression.Return(returnValueLable, Expression.Constant(null, type)
|
||||
));
|
||||
methodCall.Add(ifReadNullOrObjLeftReturnNull1);
|
||||
}
|
||||
|
||||
/*
|
||||
Model m=new Model();
|
||||
*/
|
||||
NewExpression newCtor = null;
|
||||
if (type.IsValueType)
|
||||
{
|
||||
List<Expression> ctorArgs = null;
|
||||
var ctor = type.GetValueTypeCtor(ref ctorArgs);
|
||||
if (ctor == null)
|
||||
newCtor = Expression.New(type);
|
||||
else
|
||||
newCtor = Expression.New(ctor, ctorArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type.IsInterface)
|
||||
{
|
||||
//newCtor = Expression.New((Type)typeof(InterfaceImplementation<>).MakeGenericType(type).GetField("Proxy").GetValue(null));
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Expression> ctorArgs = null;
|
||||
var ctor = type.GetClassCtor(ref ctorArgs);
|
||||
newCtor = Expression.New(ctor, ctorArgs);
|
||||
}
|
||||
}
|
||||
ParameterExpression newModel = Expression.Variable(type, "newModel");
|
||||
methodCall.Add(Expression.Assign(newModel, newCtor));
|
||||
|
||||
/*
|
||||
if(reader.ReadBoolObjRight)
|
||||
return m;
|
||||
*/
|
||||
methodCall.Add(Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight), Expression.Return(returnValueLable, newModel)));
|
||||
|
||||
/*
|
||||
int moveNext=2;
|
||||
*/
|
||||
methodCall.Add(ExpressionMembers.MoveNextAssignOne); //Add moveNext localVirbale
|
||||
|
||||
/*
|
||||
if(jsonDeserializeOption.IsFirstUpper)
|
||||
while(moveNext-->0)
|
||||
{ }
|
||||
else if(jsonDeserializeOption.IsFirstLower)
|
||||
while(moveNext-->0)
|
||||
{ }
|
||||
else
|
||||
while(moveNext-->0)
|
||||
{ }
|
||||
*/
|
||||
var charTries = type.GetCharTries();
|
||||
if (charTries.Childrens.Count > 0)
|
||||
methodCall.Add(GenerateWhile(newModel, type, charTries));
|
||||
|
||||
/*
|
||||
reader.ReadObjRight()
|
||||
*/
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight));
|
||||
|
||||
/*
|
||||
return newModel;
|
||||
*/
|
||||
methodCall.Add(Expression.Return(returnValueLable, newModel));
|
||||
methodCall.Add(Expression.Label(returnValueLable, newModel));
|
||||
|
||||
return Expression.Block(new[] { ExpressionMembers.AfterFormatKey, ExpressionMembers.CurrentIdx, ExpressionMembers.IsValueFormat, ExpressionMembers.ValueLength, ExpressionMembers.FormatResult, ExpressionMembers.CharVariable, ExpressionMembers.MoveNext, ExpressionMembers.IsArrive, newModel }, methodCall);
|
||||
}
|
||||
|
||||
private static BlockExpression GenerateWhile(ParameterExpression newModel, Type type, CharTries charTries)
|
||||
{
|
||||
//(state):0==The initial state does not change,1==Capital letters,2==Initial lowercase
|
||||
/*
|
||||
char c;
|
||||
while(moveNext-->0)
|
||||
{
|
||||
}
|
||||
*/
|
||||
ParameterExpression firstChar = Expression.Variable(typeof(char), "firstChar");
|
||||
LabelTarget tailOfMethod = Expression.Label(typeof(void), "tailOfMethod");
|
||||
LabelTarget whileBreak = Expression.Label();
|
||||
LoopExpression loopExpression = Expression.Loop(Expression.IfThenElse(ExpressionMembers.MoveNextDecrement,
|
||||
ReturnFunc<Expression>(() =>
|
||||
{
|
||||
Expression[] expressions = new Expression[6];
|
||||
/*
|
||||
isArrive=false;
|
||||
*/
|
||||
expressions[0] = ExpressionMembers.IsArriveAssignFalse;
|
||||
|
||||
/*
|
||||
2019-11-10 16:55:31,Add two configuration options of IgnoreJsonKeys and IsIgnoreExtraKeysInJSON
|
||||
*/
|
||||
expressions[1] = GenerateIgnoreKeys(type, tailOfMethod);
|
||||
|
||||
/*
|
||||
* if(handler.option.GlobalKeyFormat!=null)
|
||||
GenerateGlobalKeyFormat()
|
||||
else
|
||||
ReadKey()
|
||||
*/
|
||||
expressions[2] = Expression.IfThenElse(
|
||||
Expression.NotEqual(Expression.MakeMemberAccess(ExpressionMembers.JsonDeserializeOption, JsonDeserializeOption._GlobalKeyFormat), Expression.Constant(null, JsonDeserializeOption._GlobalKeyFormat.FieldType)),
|
||||
GenerateGlobalKeyFormat(type, newModel, tailOfMethod),
|
||||
GenerateKeyValueObjectReadKey(firstChar, charTries, newModel)
|
||||
);
|
||||
|
||||
/*
|
||||
if(!isArrive)
|
||||
throw
|
||||
*/
|
||||
expressions[3] = Expression.IfThen(Expression.Equal(ExpressionMembers.IsArrive, Expression.Constant(false, typeof(bool))), Expression.Throw(Expression.New(JsonDeserializationTypeResolutionException._JsonDeserializationTypeResolutionExceptionCtor, ExpressionMembers.Reader, type.IsInterface ? (Expression)Expression.Constant(type, typeof(Type)) : Expression.Call(newModel, type.GetMethod("GetType")))));
|
||||
|
||||
/*
|
||||
Label -> tailOfMethod:
|
||||
*/
|
||||
expressions[4] = Expression.Label(tailOfMethod);
|
||||
|
||||
/*
|
||||
if(reader.ReadComma()==true)
|
||||
moveNext++;
|
||||
*/
|
||||
expressions[5] = ExpressionMembers.IfReadBoolCommaIsTrueSoMoveNextIncrement;
|
||||
|
||||
return Expression.Block(expressions);
|
||||
})
|
||||
, Expression.Break(whileBreak)));
|
||||
return Expression.Block(new[] { firstChar }, loopExpression, Expression.Label(whileBreak));
|
||||
}
|
||||
|
||||
private static Expression GenerateIgnoreKeys(Type type, LabelTarget tailOfMethod)
|
||||
{
|
||||
#region
|
||||
/*
|
||||
if(jsonDeserializeHandler.Option.JsonCharacterReadState == JsonCharacterReadStateEnum.None && jsonDeserializeHandler.Option.GlobalKeyFormat == null)
|
||||
{
|
||||
string key = reader.ReadString();
|
||||
|
||||
if(IsIgnoreExtraKeysInJSON){
|
||||
if(TypeKeysCache<T>.NotContains(key))
|
||||
{
|
||||
reader.ReadColon();
|
||||
Reader.ReadObject();
|
||||
goto tailOfMethod;
|
||||
}
|
||||
|
||||
if(IgnoreJsonKeysHasValue)
|
||||
{
|
||||
if(IgnoreKey.Contains(key))
|
||||
{
|
||||
reader.ReadColon();
|
||||
Reader.ReadObject();
|
||||
goto tailOfMethod;
|
||||
}
|
||||
}
|
||||
|
||||
if(key!=null)
|
||||
Rollback(key.Length+2);
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
ParameterExpression key = Expression.Variable(typeof(string), "key");
|
||||
return Expression.IfThen(Expression.AndAlso(Expression.Equal(ExpressionMembers.JsonCharacterReadState, Expression.Constant(JsonCharacterReadStateEnum.None, typeof(JsonCharacterReadStateEnum))), ExpressionMembers.GlobalKeyFormatEqualNull),
|
||||
Expression.Block(new[] { key },
|
||||
//string key=reader.ReadString();
|
||||
Expression.Assign(key, Expression.Call(ExpressionMembers.Reader, JsonReader._ReadString)),
|
||||
//if(IsIgnoreExtraKeysInJSON)
|
||||
IfIsIgnoreExtraKeysInJsonThenSkipObject(key, type, tailOfMethod),
|
||||
//if(IgnoreJsonKeysHasValue)
|
||||
IfIgnoreJsonKeysHasValueThenSkipObject(key, tailOfMethod),
|
||||
//if(key!=null)
|
||||
Expression.IfThen(Expression.NotEqual(key, Expression.Constant(null, typeof(string))),
|
||||
//Rollback(key.Length+2);
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._Rollback, Expression.Add(Expression.Property(key, typeof(string).GetProperty("Length")), Expression.Constant(2, typeof(int))))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static Expression IfIsIgnoreExtraKeysInJsonThenSkipObject(ParameterExpression key, Type type, LabelTarget tailOfMethod)
|
||||
{
|
||||
return Expression.IfThen(Expression.Equal(Expression.MakeMemberAccess(ExpressionMembers.JsonDeserializeOption, JsonDeserializeOption._IsIgnoreExtraKeysInJSON), Expression.Constant(true, typeof(bool))),
|
||||
//if(TypeKeysCache<T>.NotContains(key))
|
||||
Expression.IfThen(Expression.Equal(Expression.Call(TypeUtils.GetContainsMethodInfo(type), key), Expression.Constant(true, typeof(bool))),
|
||||
/*
|
||||
reader.ReadColon();
|
||||
Reader.SkipObject();
|
||||
goto tailOfMethod;
|
||||
*/
|
||||
ReadColonAndSkipObjectAndGotoTailOfMethod(tailOfMethod)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static Expression IfIgnoreJsonKeysHasValueThenSkipObject(ParameterExpression key, LabelTarget tailOfMethod)
|
||||
{
|
||||
return Expression.IfThen(Expression.Equal(Expression.MakeMemberAccess(ExpressionMembers.JsonDeserializeOption, JsonDeserializeOption._IgnoreJsonKeysHasValue), Expression.Constant(true, typeof(bool))),
|
||||
//if(IgnoreKey.Contains(key))
|
||||
Expression.IfThen(Expression.Call(Expression.MakeMemberAccess(ExpressionMembers.JsonDeserializeOption, JsonDeserializeOption._IgnoreJsonKeys), JsonDeserializeOption._IgnoreJsonKeyContains, key),
|
||||
/*
|
||||
reader.ReadColon();
|
||||
Reader.SkipObject();
|
||||
goto tailOfMethod;
|
||||
*/
|
||||
ReadColonAndSkipObjectAndGotoTailOfMethod(tailOfMethod)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private static Expression ReadColonAndSkipObjectAndGotoTailOfMethod(LabelTarget tailOfMethod)
|
||||
{
|
||||
return Expression.Block(
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon),
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._SkipObj, ExpressionMembers.JsonDeserializeHandler),
|
||||
Expression.Goto(tailOfMethod)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static Expression GenerateGlobalKeyFormat(Type type, ParameterExpression newModel, LabelTarget tailOfMethod)
|
||||
{
|
||||
return Expression.Block(
|
||||
|
||||
/*
|
||||
var afterFormatKey = handler.option.GlobalKeyFormat.Invoke(reader.ReadString(),type)
|
||||
*/
|
||||
Expression.Assign(ExpressionMembers.AfterFormatKey,
|
||||
Expression.Call(ExpressionMembers.GlobalKeyFormat, JsonDeserializeOption._GlobalKeyFormatInvoke,
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadString), Expression.Constant(type, typeof(Type)))),
|
||||
|
||||
/*
|
||||
if(IsIgnoreExtraKeysInJSON){
|
||||
if(!modelKeys.Contains(afterFormatKey))
|
||||
{
|
||||
reader.ReadColon();
|
||||
Reader.ReadObject();
|
||||
goto zuihou;
|
||||
}
|
||||
if(IsOpenIgnoreKey)
|
||||
if(IgnoreKey.Contains(key))
|
||||
{
|
||||
reader.ReadColon();
|
||||
Reader.ReadObject();
|
||||
goto zuihou;
|
||||
}
|
||||
*/
|
||||
IfIsIgnoreExtraKeysInJsonThenSkipObject(ExpressionMembers.AfterFormatKey, type, tailOfMethod),
|
||||
IfIgnoreJsonKeysHasValueThenSkipObject(ExpressionMembers.AfterFormatKey, tailOfMethod),
|
||||
/*
|
||||
reader.ReadColon()
|
||||
*/
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon),
|
||||
/*
|
||||
Switch(afterFormatKey)
|
||||
case 'Name':
|
||||
ReadValue()....
|
||||
*/
|
||||
Expression.Switch(
|
||||
typeof(void),
|
||||
ExpressionMembers.AfterFormatKey,
|
||||
null, null,
|
||||
ReturnFunc(() =>
|
||||
{
|
||||
var members = type.GetModelMembers();
|
||||
SwitchCase[] switchCases = new SwitchCase[members.Count];
|
||||
for (int i = 0; i < members.Count; i++)
|
||||
{
|
||||
var item = members[i];
|
||||
switchCases[i] = Expression.SwitchCase(GenerateKeyValueObjectReadValue(item.Value, newModel), Expression.Constant(item.Key));
|
||||
|
||||
}
|
||||
return switchCases;
|
||||
})
|
||||
),
|
||||
/*
|
||||
isArrive=true;
|
||||
*/
|
||||
ExpressionMembers.IsArriveAssignTrue
|
||||
);
|
||||
}
|
||||
|
||||
private static Expression GenerateKeyValueObjectReadValue(MemberExtension member, ParameterExpression newModel)
|
||||
{
|
||||
if (!member.IsProperty || (member.IsProperty && member.PropertyInfo.CanWrite))
|
||||
{
|
||||
var valueFormatAttribute = member.MemberInfo.GetCustomAttribute<ValueFormatAttribute>() ?? member.MemberInfo.DeclaringType.GetCustomAttribute<ValueFormatAttribute>();
|
||||
if (valueFormatAttribute != null)//part
|
||||
{
|
||||
return (GenerateValueFormatCode(Expression.Constant(valueFormatAttribute, typeof(ValueFormatAttribute)), ValueFormatAttribute._ReadValueFormat, new[] { ExpressionMembers.JsonRemoveQuoteAndSubstring, Expression.Constant(member.Type, typeof(Type)), ExpressionMembers.JsonDeserializeHandler, ExpressionMembers.IsValueFormat }, newModel, member));
|
||||
}
|
||||
else //global
|
||||
{
|
||||
/*
|
||||
if( jsonDeserializeHandler.jsonDeserializeOption .globalValueFormat!=null)
|
||||
{
|
||||
}
|
||||
else
|
||||
model.N=ReadJson();
|
||||
*/
|
||||
return (Expression.IfThenElse(ExpressionMembers.GlobalValueFormatNotEqualNull, GenerateValueFormatCode(ExpressionMembers.GlobalValueFormat, JsonDeserializeOption._GlobalValueFormatInvoke, new[] { ExpressionMembers.JsonRemoveQuoteAndSubstring, Expression.Constant(member.Type, typeof(Type)), ExpressionMembers.JsonDeserializeHandler, ExpressionMembers.IsValueFormat }, newModel, member), Expression.Assign(Expression.MakeMemberAccess(newModel, member.MemberInfo), ExpressionMembers.GetMethodCall(member.Type))));
|
||||
}
|
||||
}
|
||||
else
|
||||
/* SkipObj(); */
|
||||
return (Expression.Call(ExpressionMembers.Reader, JsonReader._SkipObj, ExpressionMembers.JsonDeserializeHandler));
|
||||
}
|
||||
|
||||
private static BlockExpression GenerateValueFormatCode(Expression formatDeclareInstance, MethodInfo callFormat, Expression[] paras, ParameterExpression newModel, MemberExtension member)
|
||||
{
|
||||
Expression[] expressions = new Expression[6];
|
||||
/*
|
||||
reader.BeforAnnotation();
|
||||
reader.RollBackChar()
|
||||
*/
|
||||
expressions[0] = Expression.Call(ExpressionMembers.Reader, JsonReader._BeforAnnotation);
|
||||
expressions[1] = Expression.Call(ExpressionMembers.Reader, JsonReader._RollbackChar);
|
||||
/*
|
||||
currentIdx= Length - reader.Remaining
|
||||
*/
|
||||
expressions[2] = ExpressionMembers.CurrentIdxAssignReming;
|
||||
/*
|
||||
valueLength=reader.Skipobj()
|
||||
*/
|
||||
expressions[3] = (ExpressionMembers.ValueLengthAssignSkipObj);
|
||||
/*
|
||||
object formatResult = ValueFormat.ReadValueFormat( reader.Substring(currentIdx,valueLength) ,out isValueFormat);
|
||||
*/
|
||||
expressions[4] = (Expression.Assign(ExpressionMembers.FormatResult, Expression.Call(formatDeclareInstance, callFormat, paras)));
|
||||
/*
|
||||
if(isValueFormat==true)
|
||||
model.N=(Convert)obj;
|
||||
else
|
||||
reader.Rollback(valueLength)
|
||||
m.N=ReadJson();//string
|
||||
*/
|
||||
expressions[5] = (Expression.IfThenElse(ExpressionMembers.IsValueFormatEqualTrue, Expression.Assign(Expression.MakeMemberAccess(newModel, member.MemberInfo), Expression.Convert(ExpressionMembers.FormatResult, member.Type)), Expression.Block(Expression.Call(ExpressionMembers.Reader, JsonReader._Rollback, ExpressionMembers.ValueLength), Expression.Assign(Expression.MakeMemberAccess(newModel, member.MemberInfo), ExpressionMembers.GetMethodCall(member.Type)))));
|
||||
|
||||
return Expression.Block(expressions);
|
||||
}
|
||||
|
||||
private static Expression GenerateKeyValueObjectReadKey(ParameterExpression firstChar, CharTries charTries, ParameterExpression newModel)
|
||||
{
|
||||
|
||||
return
|
||||
Expression.IfThenElse(
|
||||
Expression.NotEqual(ExpressionMembers.JsonCharacterReadState, Expression.Constant(JsonCharacterReadStateEnum.IgnoreCase, typeof(JsonCharacterReadStateEnum))),
|
||||
GenerateKeyValueObjectReadKeyWithInitial(firstChar, charTries, newModel),
|
||||
GenerateKeyValueObjectReadKeyWithIgnoreCase(charTries, newModel));
|
||||
}
|
||||
|
||||
private static Expression GenerateKeyValueObjectReadKeyWithInitial(ParameterExpression firstChar, CharTries charTries, ParameterExpression newModel)
|
||||
{
|
||||
return Expression.Block(
|
||||
/*
|
||||
_ReadQuotes();
|
||||
*/
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadQuotes),
|
||||
/*
|
||||
switch (handler.Option.InitialReadState)
|
||||
{
|
||||
case InitialReadStateEnum.None:
|
||||
firstChar = reader.GetChar();
|
||||
break;
|
||||
case InitialReadStateEnum.Upper:
|
||||
firstChar = char.ToUpper(reader.GetChar());
|
||||
break;
|
||||
case InitialReadStateEnum.Lower:
|
||||
firstChar = char.ToLower(reader.GetChar());
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
Expression.Switch(typeof(void), ExpressionMembers.JsonCharacterReadState,
|
||||
null, null,
|
||||
Expression.SwitchCase(Expression.Assign(firstChar, ExpressionMembers.GetChar), Expression.Constant(JsonCharacterReadStateEnum.None, typeof(JsonCharacterReadStateEnum))),
|
||||
Expression.SwitchCase(Expression.Assign(firstChar, Expression.Call(typeof(char).GetMethod("ToUpper", new[] { typeof(char) }), ExpressionMembers.GetChar)), Expression.Constant(JsonCharacterReadStateEnum.InitialUpper, typeof(JsonCharacterReadStateEnum))),
|
||||
Expression.SwitchCase(Expression.Assign(firstChar, Expression.Call(typeof(char).GetMethod("ToLower", new[] { typeof(char) }), ExpressionMembers.GetChar)), Expression.Constant(JsonCharacterReadStateEnum.InitialLower, typeof(JsonCharacterReadStateEnum)))
|
||||
),
|
||||
/*
|
||||
Switch(firstChar)
|
||||
case 'N'
|
||||
Switch(getChar())
|
||||
case 'a'
|
||||
Switch(getChar())
|
||||
case 'm'
|
||||
Switch(getChar())
|
||||
case 'e'
|
||||
Switch(getChar())
|
||||
case '"':
|
||||
ReadValue()...
|
||||
*/
|
||||
GenerateSwitchCodeByChar(firstChar, charTries, newModel)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private static Expression GenerateKeyValueObjectReadKeyWithIgnoreCase(CharTries charTries, ParameterExpression newModel)
|
||||
{
|
||||
return Expression.Block(
|
||||
/*
|
||||
_ReadQuotes();
|
||||
*/
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadQuotes),
|
||||
|
||||
/*
|
||||
Switch(getChar())
|
||||
case 'N'
|
||||
Switch(getChar())
|
||||
case 'a'
|
||||
Switch(getChar())
|
||||
case 'm'
|
||||
Switch(getChar())
|
||||
case 'e'
|
||||
Switch(getChar())
|
||||
case '"':
|
||||
ReadValue()...
|
||||
*/
|
||||
GenerateSwitchCodeByChar(null, charTries, newModel, true)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private static SwitchExpression GenerateSwitchCodeByChar(ParameterExpression firstChar, CharTries charTries, ParameterExpression newModel, bool isToLower = false)
|
||||
{
|
||||
List<SwitchCase> switchCases = new List<SwitchCase>();
|
||||
|
||||
if (charTries.IsValue)
|
||||
{
|
||||
//case '"'
|
||||
var caseQuotes = Expression.SwitchCase(
|
||||
|
||||
Expression.Block(
|
||||
typeof(void),
|
||||
/*
|
||||
ReadColon();
|
||||
*/
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon),
|
||||
GenerateKeyValueObjectReadValue(charTries.Member, newModel),
|
||||
/*
|
||||
isArrive=true;
|
||||
*/
|
||||
ExpressionMembers.IsArriveAssignTrue
|
||||
)
|
||||
, Expression.Constant('"', typeof(char)));
|
||||
|
||||
switchCases.Add(caseQuotes);
|
||||
}
|
||||
|
||||
if (charTries.Childrens.Count > 0)
|
||||
{
|
||||
foreach (var item in charTries.Childrens)
|
||||
{
|
||||
char c = item.Val;
|
||||
SwitchCase caseOrdinary = Expression.SwitchCase( //When there are two duplicate case items, the expression takes the first one automatically
|
||||
GenerateSwitchCodeByChar(null, item, newModel, isToLower),
|
||||
Expression.Constant(isToLower ? char.ToLower(c) : c, typeof(char)));
|
||||
|
||||
switchCases.Add(caseOrdinary);
|
||||
}
|
||||
}
|
||||
|
||||
return Expression.Switch(isToLower ? Expression.Call(typeof(char).GetMethod("ToLower", new[] { typeof(char) }), ExpressionMembers.GetChar) : firstChar ?? ExpressionMembers.GetChar, switchCases.ToArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.KeyValuePair)]
|
||||
internal class KeyValuePairBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type type)
|
||||
{
|
||||
|
||||
Type keyType = type.GetGenericArguments()[0];
|
||||
Type valueType = type.GetGenericArguments()[1];
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
Type keyValuePairType = typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType);
|
||||
LabelTarget returnValueLable = Expression.Label(keyValuePairType, "returnValue");
|
||||
|
||||
ConstructorInfo ctor = keyValuePairType.GetConstructor(new[] { keyType, valueType });
|
||||
ParameterExpression key = Expression.Variable(keyType, "key");
|
||||
ParameterExpression value = Expression.Variable(valueType, "value");
|
||||
|
||||
/*
|
||||
ReadObjLeft()
|
||||
*/
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjLeft));
|
||||
/*
|
||||
if(reader.ReadBoolObjRight)
|
||||
return new KeyValuePair<,>(default,default);
|
||||
*/
|
||||
methodCall.Add(
|
||||
Expression.IfThen(
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolObjRight),
|
||||
Expression.Return(returnValueLable, Expression.New(ctor, keyType.IsValueType ? (Expression)Expression.New(keyType) : Expression.Constant(null, keyType), valueType.IsValueType ? (Expression)Expression.New(valueType) : Expression.Constant(null, valueType)))));
|
||||
|
||||
/*
|
||||
ReadKey()
|
||||
*/
|
||||
methodCall.Add(ExpressionMembers.GenerateKeyValuePairByReadKey(keyType, key));
|
||||
|
||||
/*
|
||||
reader.ReadColon()
|
||||
*/
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadColon));
|
||||
|
||||
/*
|
||||
value = ResolveProvider<ValueType>.InvokeGet(reader, handler);
|
||||
*/
|
||||
methodCall.Add(Expression.Assign(value, ExpressionMembers.GetMethodCall(valueType)));
|
||||
|
||||
/*
|
||||
reader.ReadObjRight();
|
||||
*/
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight));
|
||||
|
||||
/*
|
||||
return new KeyValuePair<,>(key,value);
|
||||
*/
|
||||
methodCall.Add(Expression.Return(returnValueLable, Expression.New(ctor, key, value)));
|
||||
methodCall.Add(Expression.Label(returnValueLable, Expression.New(ctor, key, value)));
|
||||
|
||||
return Expression.Block(new[] { key, value }, methodCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.Lazy)]
|
||||
internal class LazyBuild : ExpressionJsonResolve
|
||||
{
|
||||
#region pregenerated metas
|
||||
static MethodInfo _TransitionFunc = typeof(LazyBuild).GetMethod(nameof(TransitionFunc), BindingFlags.Static | BindingFlags.NonPublic);
|
||||
#endregion
|
||||
|
||||
internal static BlockExpression Build(Type type)
|
||||
{
|
||||
LabelTarget returnTarget = Expression.Label(type, "returnLable");
|
||||
Type elementType = type.GetGenericArguments()[0];
|
||||
ParameterExpression element = Expression.Variable(elementType, "element");
|
||||
var ctr = type.GetAppointTypeCtor(typeof(Func<>).MakeGenericType(elementType));
|
||||
return Expression.Block(new[] { element },
|
||||
Expression.IfThenElse(
|
||||
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolNull),
|
||||
Expression.Return(returnTarget, Expression.Constant(null, type)),
|
||||
Expression.Block(
|
||||
Expression.Assign(element, ExpressionMembers.GetMethodCall(elementType)), //inject = Read<T>(); T-->)
|
||||
Expression.Return(returnTarget, Expression.New(ctr, Expression.Call(_TransitionFunc.MakeGenericMethod(elementType), element)))
|
||||
)),
|
||||
Expression.Label(returnTarget, Expression.Constant(null, type))
|
||||
);
|
||||
}
|
||||
|
||||
private static Func<T> TransitionFunc<T>(T t)
|
||||
{
|
||||
return () => t;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.MultiArray)]
|
||||
internal class MultiArrayBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type multiType, Type sawtoothType, int rank)
|
||||
{
|
||||
LabelTarget returnValueLable = Expression.Label(multiType, "returnValue");
|
||||
List<ParameterExpression> lambdaVariables = new List<ParameterExpression>();
|
||||
Expression[] exs = new Expression[3];
|
||||
|
||||
ParameterExpression sawtoothAry = Expression.Variable(sawtoothType);
|
||||
lambdaVariables.Add(sawtoothAry);
|
||||
/*
|
||||
int[][][] sawtoothAry= InvokeGet<int[][][]>();
|
||||
*/
|
||||
exs[0] = Expression.Assign(sawtoothAry, ExpressionMembers.GetMethodCall(sawtoothType));
|
||||
|
||||
/*
|
||||
if(sawtoothAry==null)
|
||||
return null;
|
||||
else
|
||||
...
|
||||
*/
|
||||
exs[1] = Expression.IfThenElse(
|
||||
Expression.Equal(sawtoothAry, Expression.Constant(null, sawtoothType)),
|
||||
Expression.Return(returnValueLable, Expression.Constant(null, multiType)),
|
||||
ReturnFunc<Expression>(() =>
|
||||
{
|
||||
List<Expression> expressions = new List<Expression>();
|
||||
|
||||
/*
|
||||
var index0_Length = sawtoothAry.Length;
|
||||
var index1_Length = sawtoothAry[0].Length;
|
||||
var index2_Length = sawtoothAry[0][0].Length;
|
||||
|
||||
var a = 0;
|
||||
var b = 0;
|
||||
var c = 0;
|
||||
*/
|
||||
ParameterExpression[] arrayLengthVariables = new ParameterExpression[rank];
|
||||
ParameterExpression[] forVariables = new ParameterExpression[rank];
|
||||
for (int i = 0; i < arrayLengthVariables.Length; i++)
|
||||
{
|
||||
arrayLengthVariables[i] = Expression.Variable(typeof(int));
|
||||
expressions.Add(Expression.Assign(arrayLengthVariables[i], Expression.MakeMemberAccess(GetIndexAccessBySawtoothAry(sawtoothAry, GetExpressionConstantZero(i).ToArray()), typeof(Array).GetProperty("Length"))));
|
||||
|
||||
forVariables[i] = Expression.Variable(typeof(int));
|
||||
}
|
||||
lambdaVariables.AddRange(arrayLengthVariables);
|
||||
|
||||
/*
|
||||
int[,,] multiAry=new multiAry(index0_Length,index1_Length,index2_Length)
|
||||
*/
|
||||
ParameterExpression multiAry = Expression.Variable(multiType);
|
||||
lambdaVariables.Add(multiAry);
|
||||
|
||||
expressions.Add(Expression.Assign(multiAry, Expression.New(multiType.GetConstructors()[0], arrayLengthVariables)));
|
||||
|
||||
/*
|
||||
for (int a = 0; a < index0_Length; a++)
|
||||
{
|
||||
for (int b = 0; b < index1_Length; b++)
|
||||
{
|
||||
for (int c = 0; c < index2_Length; c++)
|
||||
{
|
||||
multiAry[a,b,c] = sawtoothAry[a][b][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
Expression forMain = null;
|
||||
for (int i = arrayLengthVariables.Length - 1; i >= 0; i--)
|
||||
{
|
||||
Expression content = null;
|
||||
if (forMain == null)
|
||||
{
|
||||
/*
|
||||
sawtoothAry[a][b][c];
|
||||
*/
|
||||
Expression sawtoothAryAccess = GetIndexAccessBySawtoothAry(sawtoothAry, forVariables);
|
||||
/*
|
||||
multiAry[a,b,c] = sawtoothAry[a][b][c];
|
||||
*/
|
||||
content = Expression.Assign(Expression.ArrayAccess(multiAry, forVariables), sawtoothAryAccess);
|
||||
}
|
||||
else
|
||||
content = forMain;
|
||||
|
||||
forMain = ExpressionHelper.For(forVariables[i], Expression.LessThan(forVariables[i], arrayLengthVariables[i]), Expression.PostIncrementAssign(forVariables[i]),
|
||||
content
|
||||
);
|
||||
}
|
||||
expressions.Add(forMain);
|
||||
|
||||
/*
|
||||
return multiAry
|
||||
*/
|
||||
expressions.Add(Expression.Return(returnValueLable, multiAry));
|
||||
|
||||
return Expression.Block(expressions);
|
||||
}));
|
||||
|
||||
exs[2] = Expression.Label(returnValueLable, Expression.Constant(null, multiType));
|
||||
|
||||
return Expression.Block(lambdaVariables.ToArray(), exs);
|
||||
}
|
||||
|
||||
internal static IEnumerable<Expression> GetExpressionConstantZero(int num)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
yield return Expression.Constant(0);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Expression GetIndexAccessBySawtoothAry(ParameterExpression sawtoothAry, Expression[] indexs)
|
||||
{
|
||||
if (!indexs.Any())
|
||||
return sawtoothAry;
|
||||
Expression lastAccess = null;
|
||||
foreach (var t in indexs)
|
||||
{
|
||||
lastAccess = Expression.ArrayAccess(lastAccess ?? sawtoothAry, t);
|
||||
}
|
||||
return lastAccess;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
[ExpressionBuildType(DeserializeBuildTypeEnum.WrongGenericKey)]
|
||||
internal class WrongGenericKeyBuild : ExpressionJsonResolve
|
||||
{
|
||||
internal static BlockExpression Build(Type type)
|
||||
{
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
LabelTarget returnValueLable = Expression.Label(type, "returnValue");
|
||||
/*
|
||||
if(_ReadNullOrObjLeft)
|
||||
return null;/return default(ValueType)
|
||||
*/
|
||||
Expression ifReadNullOrObjLeftReturnNull1 = Expression.IfThen(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadNullOrObjLeft),
|
||||
Expression.Return(returnValueLable, Expression.Constant(null, type)
|
||||
));
|
||||
methodCall.Add(ifReadNullOrObjLeftReturnNull1);
|
||||
|
||||
/*
|
||||
reader.ReadObjRight()
|
||||
*/
|
||||
methodCall.Add(Expression.Call(ExpressionMembers.Reader, JsonReader._ReadObjRight));
|
||||
|
||||
/*
|
||||
return new dictionary<,>;
|
||||
*/
|
||||
methodCall.Add(Expression.Return(returnValueLable, Expression.New(type)));
|
||||
methodCall.Add(Expression.Label(returnValueLable, Expression.New(type)));
|
||||
return Expression.Block(methodCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class ExpressionJsonResolve : JsonResolveBase
|
||||
{
|
||||
internal static T ReturnFunc<T>(Func<T> f) => f();
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Json Array
|
||||
/// </summary>
|
||||
public class JArray : List<object>
|
||||
{
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Json Object
|
||||
/// </summary>
|
||||
public class JObject : Dictionary<string, object>
|
||||
{
|
||||
public object this[int index] { get { return base[index.ToString()]; }set { base[index.ToString()] = value; } }
|
||||
public object this[long index] { get { return base[index.ToString()]; } set { base[index.ToString()] = value; } }
|
||||
public object this[Guid index] { get { return base[index.ToString()]; } set { base[index.ToString()] = value; } }
|
||||
public object this[DateTime index] { get { return base[index.ToString()]; } set { base[index.ToString()] = value; } }
|
||||
public object this[float index] { get { return base[index.ToString()]; } set { base[index.ToString()] = value; } }
|
||||
public object this[double index] { get { return base[index.ToString()]; } set { base[index.ToString()] = value; } }
|
||||
}
|
||||
}
|
@ -1,765 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal unsafe class JsonReader
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static FieldInfo _Json =
|
||||
typeof(JsonReader).GetField(nameof(Json), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
internal static FieldInfo _Buffer =
|
||||
typeof(JsonReader).GetField(nameof(Buffer), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
internal static FieldInfo _Length =
|
||||
typeof(JsonReader).GetField(nameof(Length), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
internal static FieldInfo _Remaining =
|
||||
typeof(JsonReader).GetField(nameof(Remaining), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
internal static MethodInfo _RollbackChar = GetMethodInfo(nameof(RollbackChar));
|
||||
|
||||
internal static MethodInfo _Rollback = GetMethodInfo(nameof(Rollback));
|
||||
|
||||
internal static MethodInfo _ReadObjLeft = GetMethodInfo(nameof(ReadObjLeft));
|
||||
|
||||
internal static MethodInfo _ReadNullOrObjLeft = GetMethodInfo(nameof(ReadNullOrObjLeft));
|
||||
|
||||
internal static MethodInfo _ReadObjRight = GetMethodInfo(nameof(ReadObjRight));
|
||||
|
||||
internal static MethodInfo _ReadBoolObjRight = GetMethodInfo(nameof(ReadBoolObjRight));
|
||||
|
||||
internal static MethodInfo _ReadBoolComma = GetMethodInfo(nameof(ReadBoolComma));
|
||||
|
||||
internal static MethodInfo _ReadComma = GetMethodInfo(nameof(ReadComma));
|
||||
|
||||
internal static MethodInfo _ReadColon = GetMethodInfo(nameof(ReadColon));
|
||||
|
||||
internal static MethodInfo _ReadQuotes = GetMethodInfo(nameof(ReadQuotes));
|
||||
|
||||
internal static MethodInfo _ReadArrayLeft = GetMethodInfo(nameof(ReadArrayLeft));
|
||||
|
||||
internal static MethodInfo _ReadNullOrArrayLeft = GetMethodInfo(nameof(ReadNullOrArrayLeft));
|
||||
|
||||
internal static MethodInfo _ReadArrayRight = GetMethodInfo(nameof(ReadArrayRight));
|
||||
|
||||
internal static MethodInfo _ReadBoolArrayRight = GetMethodInfo(nameof(ReadBoolArrayRight));
|
||||
|
||||
internal static MethodInfo _ReadEnd = GetMethodInfo(nameof(ReadEnd));
|
||||
|
||||
internal static MethodInfo _BeforAnnotation = GetMethodInfo(nameof(BeforAnnotation));
|
||||
|
||||
internal static MethodInfo _ReadAnnotation = GetMethodInfo(nameof(ReadAnnotation));
|
||||
|
||||
internal static MethodInfo _ReadString = GetMethodInfo(nameof(ReadString));
|
||||
|
||||
internal static MethodInfo _ReadBoolNull = GetMethodInfo(nameof(ReadBoolNull));
|
||||
|
||||
internal static MethodInfo _SkipObj = GetMethodInfo(nameof(SkipObj));
|
||||
|
||||
internal static MethodInfo _GetArrayLength = GetMethodInfo(nameof(GetArrayLength));
|
||||
|
||||
internal static MethodInfo _RemoveQuoteAndSubString = GetMethodInfo(nameof(RemoveQuoteAndSubString));
|
||||
|
||||
internal static MethodInfo _GetChar = GetMethodInfo(nameof(GetChar));
|
||||
#endregion
|
||||
|
||||
internal StringBuilder CharBufferSb;
|
||||
internal string Json;
|
||||
internal char[] Buffer;
|
||||
internal int Length;
|
||||
internal char* Pointer;
|
||||
internal int Remaining;
|
||||
|
||||
|
||||
internal JsonReader(string json, char* c)
|
||||
{
|
||||
Json = json;
|
||||
Length = json.Length;
|
||||
Pointer = c;
|
||||
Remaining = Length;
|
||||
CharBufferSb = null;
|
||||
Buffer = null;
|
||||
}
|
||||
|
||||
internal JsonReader(char[] buffer,int length, char* c)
|
||||
{
|
||||
Buffer = buffer;
|
||||
Length = length;
|
||||
Pointer = c;
|
||||
Remaining = Length;
|
||||
CharBufferSb = null;
|
||||
Json = null;
|
||||
}
|
||||
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal string SubString(int start, int length)
|
||||
{
|
||||
if (Json != null)
|
||||
return Json.Substring(start, length);
|
||||
else//char[]
|
||||
return new string(Buffer, start, length);
|
||||
}
|
||||
|
||||
internal char this[int idx]
|
||||
{
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
if (Json != null)
|
||||
return Json[idx];
|
||||
else
|
||||
return Buffer[idx];
|
||||
}
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal char GetChar()
|
||||
{
|
||||
var c = *Pointer;
|
||||
Pointer++;
|
||||
Remaining--;
|
||||
return c;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal int GetInt()
|
||||
{
|
||||
var i = *(int*)Pointer;
|
||||
Pointer += 2;
|
||||
Remaining -= 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal long GetLong()
|
||||
{
|
||||
var i = *(long*)Pointer;
|
||||
Pointer += 4;
|
||||
Remaining -= 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void RollbackChar()
|
||||
{
|
||||
Pointer--;
|
||||
Remaining++;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void RollbackInt()
|
||||
{
|
||||
Pointer -= 2;
|
||||
Remaining += 2;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void Rollback(int num)
|
||||
{
|
||||
Pointer -= num;
|
||||
Remaining += num;
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadObjLeft()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != '{')
|
||||
throw new JsonWrongCharacterException(this, '{');
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool ReadNullOrObjLeft()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == 'n' && StrCompair("ull"))
|
||||
return true;
|
||||
if (c == '{')
|
||||
return false;
|
||||
throw new JsonWrongCharacterException(this, '{');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadObjRight()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != '}')
|
||||
throw new JsonWrongCharacterException(this, '}');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool ReadBoolObjRight()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == '}') return true;
|
||||
|
||||
RollbackChar();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool ReadBoolComma()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == ',') return true;
|
||||
|
||||
RollbackChar();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadComma()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != ',')
|
||||
throw new JsonWrongCharacterException(this, ',');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadColon()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != ':')
|
||||
throw new JsonWrongCharacterException(this, ':');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadQuotes()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != '"')
|
||||
throw new JsonWrongCharacterException(this, '"');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadArrayLeft()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != '[')
|
||||
throw new JsonWrongCharacterException(this, '[');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool ReadNullOrArrayLeft()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == 'n' && StrCompair("ull"))
|
||||
return true;
|
||||
if (c == '[')
|
||||
return false;
|
||||
throw new JsonWrongCharacterException(this, '[');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadArrayRight()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c != ']')
|
||||
throw new JsonWrongCharacterException(this, ']');
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool ReadBoolArrayRight()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == ']') return true;
|
||||
|
||||
RollbackChar();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool ReadBoolNull()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == 'n' && StrCompair("ull"))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
RollbackChar();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadEnd()
|
||||
{
|
||||
if (Remaining > 0)
|
||||
ReadAnnotation();
|
||||
else if (Remaining < 0)
|
||||
throw new JsonWrongCharacterException();
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal char BeforAnnotation()
|
||||
{
|
||||
var c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '/':
|
||||
{
|
||||
if (Remaining == 0)
|
||||
throw new JsonWrongCharacterException();
|
||||
c = GetChar();
|
||||
if (c == '*')
|
||||
{
|
||||
var lastChar = ' ';
|
||||
while (Remaining > 0)
|
||||
{
|
||||
lastChar = c;
|
||||
c = GetChar();
|
||||
if (c == '/') // /* * */ , /* ***/////
|
||||
if (lastChar == '*')
|
||||
{
|
||||
if (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
|
||||
return BeforAnnotation();
|
||||
return c;
|
||||
}
|
||||
|
||||
throw new JsonWrongCharacterException("Json is incomplete"); //json不完整
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '/')
|
||||
{
|
||||
while (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == '\r' || c == '\n')
|
||||
{
|
||||
if (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
|
||||
return BeforAnnotation();
|
||||
return c;
|
||||
}
|
||||
|
||||
throw new JsonWrongCharacterException("Json is incomplete"); //json不完整
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonWrongCharacterException();
|
||||
}
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
case ' ':
|
||||
if (Remaining > 0)
|
||||
return BeforAnnotation();
|
||||
else
|
||||
throw new JsonWrongCharacterException("Json is incomplete"); //json不完整
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void ReadAnnotation()
|
||||
{
|
||||
var c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '/':
|
||||
{
|
||||
if (Remaining == 0)
|
||||
throw new JsonWrongCharacterException();
|
||||
c = GetChar();
|
||||
if (c == '*')
|
||||
{
|
||||
var lastChar = ' ';
|
||||
while (Remaining > 0)
|
||||
{
|
||||
lastChar = c;
|
||||
c = GetChar();
|
||||
if (c == '/') // /* * */ , /* ***/////
|
||||
if (lastChar == '*')
|
||||
{
|
||||
if (Remaining > 0)
|
||||
ReadAnnotation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '/')
|
||||
{
|
||||
while (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == '\r' || c == '\n')
|
||||
{
|
||||
if (Remaining > 0)
|
||||
ReadAnnotation();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t':
|
||||
case ' ':
|
||||
if (Remaining > 0)
|
||||
ReadAnnotation();
|
||||
return;
|
||||
}
|
||||
|
||||
throw new JsonWrongCharacterException();
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal string ReadString()
|
||||
{
|
||||
//Currently, this method is only used for dynamic read keys and enums because it does not allow special characters
|
||||
var c = BeforAnnotation();
|
||||
if (c == '"')
|
||||
{
|
||||
var idx = Length - Remaining;
|
||||
var leng = 0;
|
||||
var isCorrectFormat = false;
|
||||
while (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == '"')
|
||||
{
|
||||
isCorrectFormat = true;
|
||||
break;
|
||||
}
|
||||
|
||||
leng++;
|
||||
}
|
||||
|
||||
if (isCorrectFormat)
|
||||
if (leng == 0)
|
||||
return string.Empty;
|
||||
else
|
||||
return this.SubString(idx, leng);
|
||||
}
|
||||
else if (c == 'n' && StrCompair("ull"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal int SkipObj(JsonDeserializeHandler handler)
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
var start = Remaining;
|
||||
switch (c)
|
||||
{
|
||||
case 'f':
|
||||
if (Remaining > 3)
|
||||
if (StrCompair("alse"))
|
||||
goto Return;
|
||||
break;
|
||||
case 't':
|
||||
if (Remaining > 2)
|
||||
if (StrCompair("rue"))
|
||||
goto Return;
|
||||
break;
|
||||
case 'n':
|
||||
if (Remaining > 2)
|
||||
if (StrCompair("ull"))
|
||||
goto Return;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
{
|
||||
SkipNumber();
|
||||
goto Return;
|
||||
}
|
||||
case '[':
|
||||
{
|
||||
if (ReadBoolArrayRight())
|
||||
goto Return;
|
||||
var moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
SkipObj(handler);
|
||||
if (ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
|
||||
ReadArrayRight();
|
||||
goto Return;
|
||||
}
|
||||
case '{':
|
||||
{
|
||||
if (ReadBoolObjRight())
|
||||
goto Return;
|
||||
var moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
SkipString();
|
||||
ReadColon();
|
||||
SkipObj(handler);
|
||||
if (ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
|
||||
ReadObjRight();
|
||||
goto Return;
|
||||
}
|
||||
case '"':
|
||||
{
|
||||
RollbackChar();
|
||||
SkipString();
|
||||
goto Return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonWrongCharacterException(this);
|
||||
Return:
|
||||
return start + 1 - Remaining;
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void SkipString()
|
||||
{
|
||||
var c = BeforAnnotation();
|
||||
if (c == '"')
|
||||
while (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c == '"')
|
||||
return;
|
||||
if (c != '\\')
|
||||
continue;
|
||||
c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '"': continue;
|
||||
case '\\': continue;
|
||||
case '/': continue;
|
||||
case 'b': continue;
|
||||
case 'f': continue;
|
||||
case 'n': continue;
|
||||
case 'r': continue;
|
||||
case 't': continue;
|
||||
case 'u':
|
||||
{
|
||||
c = GetChar();
|
||||
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
||||
c = GetChar();
|
||||
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
||||
c = GetChar();
|
||||
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
||||
c = GetChar();
|
||||
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == 'n' && StrCompair("ull")) return;
|
||||
|
||||
throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal void SkipNumber()
|
||||
{
|
||||
var seenDecimal = false;
|
||||
var seenExponent = false;
|
||||
char c;
|
||||
while (Remaining > 0)
|
||||
{
|
||||
c = GetChar();
|
||||
if (c >= '0' && c <= '9') continue;
|
||||
|
||||
if (c == '.' && !seenDecimal)
|
||||
{
|
||||
seenDecimal = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((c == 'e' || c == 'E') && !seenExponent)
|
||||
{
|
||||
c = GetChar();
|
||||
seenExponent = true;
|
||||
seenDecimal = true;
|
||||
|
||||
c = GetChar();
|
||||
if (c == '-' || c == '+' || c >= '0' && c <= '9') continue;
|
||||
throw new JsonWrongCharacterException(this, "Expected -, or a digit");
|
||||
}
|
||||
|
||||
RollbackChar();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal int GetArrayLength(JsonDeserializeHandler handler)
|
||||
{
|
||||
//ReadObjLeft();
|
||||
if (ReadBoolArrayRight())
|
||||
{
|
||||
RollbackChar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
var start = Remaining;
|
||||
var elements = 0;
|
||||
var moveNext = 1;
|
||||
while (moveNext-- > 0)
|
||||
{
|
||||
++elements;
|
||||
SkipObj(handler);
|
||||
if (ReadBoolComma())
|
||||
moveNext++;
|
||||
}
|
||||
|
||||
ReadArrayRight();
|
||||
Rollback(start - Remaining);
|
||||
return elements;
|
||||
throw new JsonWrongCharacterException("Array character error");
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal bool StrCompair(string str)
|
||||
{
|
||||
if (Remaining < str.Length)
|
||||
return false;
|
||||
//2,3,4,5,6,7,8,9
|
||||
fixed (char* p = str)
|
||||
{
|
||||
var o = p;
|
||||
switch (str.Length)
|
||||
{
|
||||
case 2:
|
||||
if (*(int*)Pointer != *(int*)o) return false;
|
||||
goto True;
|
||||
case 3:
|
||||
if (*(int*)Pointer != *(int*)o) return false;
|
||||
if (*(Pointer + 2) != *(o + 2)) return false;
|
||||
goto True;
|
||||
case 4:
|
||||
if (*(long*)Pointer != *(long*)o) return false;
|
||||
goto True;
|
||||
case 5:
|
||||
if (*(long*)Pointer != *(long*)o) return false;
|
||||
if (*(Pointer + 4) != *(o + 4)) return false;
|
||||
goto True;
|
||||
case 6:
|
||||
if (*(long*)Pointer != *(long*)o) return false;
|
||||
if (*(int*)(Pointer + 4) != *(int*)(o + 4)) return false;
|
||||
goto True;
|
||||
case 7:
|
||||
if (*(long*)Pointer != *(long*)o) return false;
|
||||
if (*(int*)(Pointer + 4) != *(int*)(o + 4)) return false;
|
||||
if (*(Pointer + 6) != *(o + 6)) return false;
|
||||
goto True;
|
||||
case 8:
|
||||
if (*(long*)Pointer != *(long*)o) return false;
|
||||
if (*(long*)(Pointer + 4) != *(long*)(o + 4)) return false;
|
||||
goto True;
|
||||
case 9:
|
||||
if (*(long*)Pointer != *(long*)o) return false;
|
||||
if (*(long*)(Pointer + 4) != *(long*)(o + 4)) return false;
|
||||
if (*(Pointer + 8) != *(o + 8)) return false;
|
||||
goto True;
|
||||
default:
|
||||
throw new Exception("Check the code,StrCompair no current length ");
|
||||
}
|
||||
}
|
||||
|
||||
True:
|
||||
Remaining -= str.Length;
|
||||
Pointer += str.Length;
|
||||
return true;
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal string RemoveQuoteAndSubString(int idx, int length)
|
||||
{
|
||||
if (this[idx] == 'n')
|
||||
return null;
|
||||
return this.SubString(idx + 1, length - 2); //remove \" \"
|
||||
}
|
||||
|
||||
private static MethodInfo GetMethodInfo(string name)
|
||||
{
|
||||
return typeof(JsonReader).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class JsonResolveBase
|
||||
{
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 对Model进行Json反序列化时全局值格式化器
|
||||
/// Global value formatter for Json deserialization of Model
|
||||
/// </summary>
|
||||
/// <param name="jsonFragment">Json字符串中的片段,Fragments in the Json string</param>
|
||||
/// <param name="elementType">该jsonFragment所对应的类型,The type corresponding to the jsonFragment</param>
|
||||
/// <param name="jsonDeserializeHandler">提供一些选项进行访问,Provides options for access</param>
|
||||
/// <param name="isValueFormat">决定最终是否进行值格式化,Determines whether the value is ultimately formatted</param>
|
||||
/// <returns></returns>
|
||||
public delegate object JsonDeserializeGlobalValueFormatDelegate(string jsonFragment, Type elementType, JsonDeserializeHandler jsonDeserializeHandler, out bool isValueFormat);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Json Deserialize Handler
|
||||
/// </summary>
|
||||
public class JsonDeserializeHandler
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static FieldInfo _Types =
|
||||
typeof(JsonDeserializeHandler).GetField(nameof(Types), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
internal static FieldInfo _Option =
|
||||
typeof(JsonDeserializeHandler).GetField(nameof(Option), BindingFlags.Instance | BindingFlags.Public);
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Json Serializer Option
|
||||
/// </summary>
|
||||
public JsonDeserializeOption Option = null;
|
||||
|
||||
internal Queue<Type> Types = new Queue<Type>();
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 反序列化全局配置项
|
||||
/// Deserialized global configuration's options
|
||||
/// </summary>
|
||||
public class JsonDeserializeOption
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static readonly FieldInfo _JsonCharacterReadState = typeof(JsonDeserializeOption).GetField(nameof(JsonCharacterReadState));
|
||||
internal static readonly MethodInfo _GlobalKeyFormatInvoke = typeof(Func<string, Type, string>).GetMethod("Invoke");
|
||||
internal static readonly FieldInfo _GlobalKeyFormat = typeof(JsonDeserializeOption).GetField(nameof(GlobalKeyFormat));
|
||||
internal static readonly MethodInfo _GlobalValueFormatInvoke = typeof(JsonDeserializeGlobalValueFormatDelegate).GetMethod("Invoke");
|
||||
internal static readonly FieldInfo _GlobalValueFormat = typeof(JsonDeserializeOption).GetField(nameof(GlobalValueFormat));
|
||||
internal static readonly FieldInfo _IgnoreJsonKeys = typeof(JsonDeserializeOption).GetField(nameof(IgnoreJsonKeys));
|
||||
internal static readonly FieldInfo _IsIgnoreExtraKeysInJSON = typeof(JsonDeserializeOption).GetField(nameof(IsIgnoreExtraKeysInJSON));
|
||||
internal static readonly PropertyInfo _IgnoreJsonKeysHasValue = typeof(JsonDeserializeOption).GetProperty(nameof(IgnoreJsonKeysHasValue), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
internal static readonly MethodInfo _IgnoreJsonKeyContains = typeof(HashSet<string>).GetMethod("Contains");
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 对Model的全局Key格式化器
|
||||
/// Read the first letter of Key in Model: default, capitalization, lowercase
|
||||
/// </summary>
|
||||
public Func<string, Type, string> GlobalKeyFormat;
|
||||
|
||||
/// <summary>
|
||||
/// 对Model的全局Value格式化器
|
||||
/// Global Value Formatter for Model
|
||||
/// </summary>
|
||||
public JsonDeserializeGlobalValueFormatDelegate GlobalValueFormat;
|
||||
|
||||
/// <summary>
|
||||
/// 对Model中的字符读取状态:默认、首字母大写、首字母小写、忽略大小写
|
||||
/// Read status for characters in the Model: Default, Initial uppercase, Initial lowercase, Ignore case
|
||||
/// </summary>
|
||||
public JsonCharacterReadStateEnum JsonCharacterReadState = JsonCharacterReadStateEnum.None;
|
||||
|
||||
/// <summary>
|
||||
/// 在对Model进行反序列化时,当JsonCharacterReadState为默认值时,忽略JSON字符中指定的Key
|
||||
/// When deserializing a model, the key specified in the JSON character is ignored when the JsonCharacterReadState is the default
|
||||
/// </summary>
|
||||
public HashSet<string> IgnoreJsonKeys;
|
||||
|
||||
/// <summary>
|
||||
/// 在对Model进行反序列化时,当JsonCharacterReadState为默认值时,是否忽略JSON字符中多余的Key
|
||||
/// When deserializing the model, whether to ignore the extra key in the JSON character when JsonCharacterReadState is the default value
|
||||
/// </summary>
|
||||
public bool IsIgnoreExtraKeysInJSON;
|
||||
|
||||
internal bool IgnoreJsonKeysHasValue => IgnoreJsonKeys != null && IgnoreJsonKeys.Count > 0;
|
||||
}
|
||||
}
|
@ -1,459 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class ResolveFind<T>
|
||||
{
|
||||
internal static ResolveDelegate<T> Find()
|
||||
{
|
||||
Type t = typeof(T);
|
||||
return FindTypeIsDefaultImplemented(t) ?? FindTypeIsMeetDefaultCondition(t) ?? FindTypeIsDefaultImplementedBaseType(t) ?? FindTypeIsDefaultImplementedInterface(t) ?? DefaultResolve(t);
|
||||
}
|
||||
|
||||
private static ResolveDelegate<T> FindTypeIsDefaultImplemented(Type t)
|
||||
{
|
||||
if (DeserializeBootTable.Table.DefaultSameTypes.TryGetValue(t, out var member))
|
||||
return GenerateLambdaCall(member);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ResolveDelegate<T> FindTypeIsMeetDefaultCondition(Type t)
|
||||
{
|
||||
return IsArray(t) ?? IsEnum(t) ?? IsDynamic(t);
|
||||
}
|
||||
|
||||
private static ResolveDelegate<T> FindTypeIsDefaultImplementedBaseType(Type t)
|
||||
{
|
||||
var baseTypes = t.GetTypeAndBaseTypes();
|
||||
|
||||
//Avoid
|
||||
if (DeserializeBootTable.Table.DefaultAvoidTypes.Intersect(baseTypes).Any())
|
||||
return GenerateLambdaCall(SpecialConditionsResolve._ReadAvoidNull);
|
||||
|
||||
//BaseType
|
||||
foreach (var item in DeserializeBootTable.Table.DefaultImplementedBaseType)
|
||||
{
|
||||
var implementedType = item.Key;
|
||||
foreach (var baseType in baseTypes)
|
||||
{
|
||||
if (baseType == implementedType)
|
||||
{
|
||||
return GenerateLambdaCall(item.Value.MethodInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ResolveDelegate<T> FindTypeIsDefaultImplementedInterface(Type t)
|
||||
{
|
||||
var intserfaces = t.GetInterfaces().ToList();
|
||||
if (t.IsInterface)
|
||||
intserfaces.Add(t);
|
||||
|
||||
foreach (var item in DeserializeBootTable.Table.DefaultImplementedInterfaces)
|
||||
{
|
||||
var implementedInterfaces = item.Key;
|
||||
foreach (var objInterface in intserfaces)
|
||||
{
|
||||
if (objInterface == implementedInterfaces)
|
||||
{
|
||||
return GenerateLambdaCall(item.Value.MethodInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ResolveDelegate<T> DefaultResolve(Type t)
|
||||
{
|
||||
Func<ResolveDelegate<T>> func = TypeIsDictionary(t) ?? TypeIsCollection(t) ?? TypeIsSpecial(t);
|
||||
if (func != null)
|
||||
return func();
|
||||
return BuildFactory.Build<T>(DeserializeBuildTypeEnum.KeyValueObject, t);
|
||||
}
|
||||
|
||||
private static Func<ResolveDelegate<T>> TypeIsCollection(Type t)
|
||||
{
|
||||
return TypeIsCollectionInterface(t) ?? TypeIsCollectionType(t);
|
||||
}
|
||||
private static Func<ResolveDelegate<T>> TypeIsDictionary(Type t)
|
||||
{
|
||||
return TypeIsDictionaryInterface(t) ?? TypeIsDictionaryType(t);
|
||||
}
|
||||
private static Func<ResolveDelegate<T>> TypeIsSpecial(Type t)
|
||||
{
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = t.GetGenericTypeDefinition();
|
||||
if (genericTypeDefinition == typeof(Nullable<>))
|
||||
return () => GenerateLambdaCall(SpecialConditionsResolve._ReadNullable.MakeGenericMethod(t.GetGenericArguments()[0]));
|
||||
else if (genericTypeDefinition == typeof(Lazy<>))
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Lazy, t);
|
||||
}
|
||||
else if (genericTypeDefinition == typeof(Lookup<,>))
|
||||
{
|
||||
|
||||
}
|
||||
else if (genericTypeDefinition == typeof(KeyValuePair<,>))
|
||||
{
|
||||
var keyType = t.GetGenericArguments()[0];
|
||||
var func = IsWrongKeyType(keyType);
|
||||
if (func != null)
|
||||
return () => func;
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.KeyValuePair, t);
|
||||
}
|
||||
else if (genericTypeDefinition == typeof(ILookup<,>))
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Func<ResolveDelegate<T>> TypeIsCollectionInterface(Type t)
|
||||
{
|
||||
if (t == typeof(IEnumerable) || t == typeof(ICollection) || t == typeof(IList))
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Collection, t, typeof(List<object>), typeof(List<object>), typeof(object));
|
||||
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = t.GetGenericTypeDefinition();
|
||||
var arrayItemType = t.GetGenericArguments()[0];
|
||||
|
||||
if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>))
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Collection, t, typeof(List<>).MakeGenericType(arrayItemType), typeof(List<>).MakeGenericType(arrayItemType), arrayItemType);
|
||||
#if !Net4
|
||||
if (genericTypeDefinition == typeof(IReadOnlyList<>) || genericTypeDefinition == typeof(IReadOnlyCollection<>))
|
||||
{
|
||||
var ctor = typeof(ReadOnlyCollection<>).MakeGenericType(arrayItemType).GetCtorByParameterInterfaceType(typeof(IList<>).MakeGenericType(arrayItemType));
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, typeof(ReadOnlyCollection<>).MakeGenericType(arrayItemType), ctor);
|
||||
}
|
||||
#endif
|
||||
if (genericTypeDefinition == typeof(ISet<>))
|
||||
{
|
||||
var ctor = typeof(HashSet<>).MakeGenericType(arrayItemType).GetCtorByParameterInterfaceType(typeof(IEnumerable<>).MakeGenericType(arrayItemType));
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, typeof(HashSet<>).MakeGenericType(arrayItemType), ctor);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static Func<ResolveDelegate<T>> TypeIsDictionaryInterface(Type t)
|
||||
{
|
||||
if (t == typeof(IDictionary))
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Dictionary, t, typeof(Dictionary<string, object>), typeof(Dictionary<string, object>), typeof(string), typeof(object));
|
||||
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
Type[] args = t.GetGenericArguments();
|
||||
if (args.Length != 2)
|
||||
return null;
|
||||
var genericTypeDefinition = t.GetGenericTypeDefinition();
|
||||
var keyType = args[0];
|
||||
var valueType = args[1];
|
||||
|
||||
if (genericTypeDefinition == typeof(IDictionary<,>))
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Dictionary, t, typeof(Dictionary<,>).MakeGenericType(keyType, valueType), t, keyType, valueType);
|
||||
#if !Net4
|
||||
if (genericTypeDefinition == typeof(IReadOnlyDictionary<,>))
|
||||
{
|
||||
var ctor = typeof(ReadOnlyDictionary<,>).MakeGenericType(keyType, valueType).GetCtorByParameterInterfaceType(typeof(IDictionary<,>).MakeGenericType(keyType, valueType));
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, typeof(ReadOnlyDictionary<,>).MakeGenericType(keyType, valueType), ctor);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static Func<ResolveDelegate<T>> TypeIsCollectionType(Type t)
|
||||
{
|
||||
if (t.IsInterface)
|
||||
return null;
|
||||
|
||||
var intserfaces = t.GetInterfaces();
|
||||
|
||||
bool hasIEnumerableGeneric = false;
|
||||
bool hasICollectionGeneric = false;
|
||||
bool hasICollection = false;
|
||||
bool hasIList = false;
|
||||
|
||||
Type arrayItemType = null;
|
||||
Type iCollectionGenericType = null;
|
||||
Type iEnumerableGenericType = null;
|
||||
foreach (var item in intserfaces)
|
||||
{
|
||||
if (item.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = item.GetGenericTypeDefinition();
|
||||
|
||||
if (genericTypeDefinition == typeof(IEnumerable<>))
|
||||
{
|
||||
hasIEnumerableGeneric = true;
|
||||
arrayItemType = item.GetGenericArguments()[0];
|
||||
iEnumerableGenericType = item;
|
||||
}
|
||||
else if (genericTypeDefinition == typeof(ICollection<>))
|
||||
{
|
||||
hasICollectionGeneric = true;
|
||||
arrayItemType = item.GetGenericArguments()[0];
|
||||
iCollectionGenericType = item;
|
||||
}
|
||||
}
|
||||
else if (item == typeof(ICollection))
|
||||
hasICollection = true;
|
||||
else if (item == typeof(IList))
|
||||
hasIList = true;
|
||||
}
|
||||
|
||||
if (hasICollectionGeneric)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(iCollectionGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, firstCtor.ParameterType, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0) //如果空的构造函数,则调用接口Add方法
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Collection, t, t, iCollectionGenericType, arrayItemType);
|
||||
}
|
||||
else //如果构造函数为iCollectionGenericType,则注入iCollectionGenericType
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, iCollectionGenericType, ctor);
|
||||
}
|
||||
|
||||
if (hasIEnumerableGeneric && hasICollection)
|
||||
{
|
||||
var ctor = t.GetAppointTypeCtor(iEnumerableGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, firstCtor.ParameterType, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, iEnumerableGenericType, ctor);
|
||||
}
|
||||
|
||||
if (hasIList)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(typeof(IList));
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, firstCtor.ParameterType, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0) //如果空的构造函数,则调用接口Add方法
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Collection, t, t, typeof(IList), typeof(object));
|
||||
}
|
||||
else //如果构造函数为iCollectionGenericType,则注入iCollectionGenericType
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, typeof(IList), ctor);
|
||||
}
|
||||
|
||||
if (hasICollection)
|
||||
{
|
||||
var ctor = t.GetAppointTypeCtor(typeof(ICollection));
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, firstCtor.ParameterType, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, typeof(ICollection), ctor);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
private static Func<ResolveDelegate<T>> TypeIsDictionaryType(Type t)
|
||||
{
|
||||
if (t.IsInterface)
|
||||
return null;
|
||||
|
||||
var intserfaces = t.GetInterfaces();
|
||||
|
||||
bool hasIDictionaryGeneric = false;
|
||||
bool hasIDictionary = false;
|
||||
Type iDictionaryGenericType = null;
|
||||
|
||||
Type keyType = null;
|
||||
Type valueType = null;
|
||||
foreach (var item in intserfaces)
|
||||
{
|
||||
if (item.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = item.GetGenericTypeDefinition();
|
||||
if (genericTypeDefinition == typeof(IDictionary<,>))
|
||||
{
|
||||
iDictionaryGenericType = item;
|
||||
hasIDictionaryGeneric = true;
|
||||
keyType = item.GetGenericArguments()[0];
|
||||
valueType = item.GetGenericArguments()[1];
|
||||
}
|
||||
}
|
||||
if (item == typeof(IDictionary))
|
||||
hasIDictionary = true;
|
||||
}
|
||||
|
||||
if (hasIDictionaryGeneric)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(iDictionaryGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (TypeIsDictionary(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, firstCtor.ParameterType, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => IsWrongKeyType(keyType) ?? BuildFactory.Build<T>(DeserializeBuildTypeEnum.Dictionary, t, t, iDictionaryGenericType, keyType, valueType);
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, iDictionaryGenericType, ctor);
|
||||
}
|
||||
if (hasIDictionary)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(typeof(IDictionary));
|
||||
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (TypeIsDictionary(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, firstCtor.ParameterType, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.Dictionary, t, t, typeof(IDictionary), typeof(string), typeof(object));
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Build<T>(DeserializeBuildTypeEnum.CtorInject, t, typeof(IDictionary), ctor);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ResolveDelegate<T> IsArray(Type t)
|
||||
{
|
||||
if (t.IsArray)
|
||||
{
|
||||
int rank = t.GetArrayRank();
|
||||
if (rank == 1)
|
||||
return BuildFactory.Build<T>(DeserializeBuildTypeEnum.Array, t);
|
||||
else
|
||||
{
|
||||
Type sawtoothType = t.GetElementType();
|
||||
int i = rank;
|
||||
while (i-- > 0)
|
||||
{
|
||||
var obj = Array.CreateInstance(sawtoothType, 0);
|
||||
sawtoothType = obj.GetType();
|
||||
}
|
||||
return BuildFactory.Build<T>(DeserializeBuildTypeEnum.MultiArray, t, sawtoothType, rank);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static ResolveDelegate<T> IsEnum(Type t)
|
||||
{
|
||||
if (t.IsEnum)
|
||||
return GenerateLambdaCallWithEnqueueType(SpecialConditionsResolve._ReadEnum, t);
|
||||
return null;
|
||||
}
|
||||
private static ResolveDelegate<T> IsDynamic(Type t)
|
||||
{
|
||||
if (t.IsAnonymousType())
|
||||
return BuildFactory.Build<T>(DeserializeBuildTypeEnum.Dynamic, t);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static ResolveDelegate<T> IsWrongKeyType(Type keyType)
|
||||
{
|
||||
if (keyType.IsWrongKey())
|
||||
return BuildFactory.Build<T>(DeserializeBuildTypeEnum.WrongGenericKey);
|
||||
return null;
|
||||
}
|
||||
private static ResolveDelegate<T> GenerateLambdaCall(MethodInfo methodInfo)
|
||||
{
|
||||
ParameterExpression readerArg = Expression.Parameter(typeof(JsonReader), "reader");
|
||||
ParameterExpression handlerArg = Expression.Parameter(typeof(JsonDeserializeHandler), "handler");
|
||||
var body = Expression.Call(methodInfo, readerArg, handlerArg);
|
||||
return Expression.Lambda<ResolveDelegate<T>>(body, readerArg, handlerArg).Compile();
|
||||
}
|
||||
private static ResolveDelegate<T> GenerateLambdaCallWithEnqueueType(MethodInfo methodInfo, Type t)
|
||||
{
|
||||
ParameterExpression readerArg = Expression.Parameter(typeof(JsonReader), "reader");
|
||||
ParameterExpression handlerArg = Expression.Parameter(typeof(JsonDeserializeHandler), "handler");
|
||||
MemberExpression option = Expression.MakeMemberAccess(handlerArg, JsonDeserializeHandler._Types);
|
||||
LabelTarget label = Expression.Label(t);
|
||||
var body = Expression.Block(Expression.Call(option, typeof(Queue<Type>).GetMethod("Enqueue"), Expression.Constant(t, typeof(Type)))
|
||||
, Expression.Return(label, Expression.Convert(Expression.Call(methodInfo, readerArg, handlerArg), t)),
|
||||
Expression.Label(label, Expression.Convert(Expression.Call(methodInfo, readerArg, handlerArg), t))
|
||||
);
|
||||
return Expression.Lambda<ResolveDelegate<T>>(body, readerArg, handlerArg).Compile();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class ResolveProvider<T>
|
||||
{
|
||||
internal static ResolveDelegate<T> Get = ResolveFind<T>.Find();
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static unsafe T Convert(string json, JsonDeserializeHandler handler)
|
||||
{
|
||||
fixed (char* c = json)
|
||||
{
|
||||
JsonReader reader = new JsonReader(json, c);
|
||||
T result = Get(reader, handler);
|
||||
reader.ReadEnd();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static unsafe T Convert(StreamReader streamReader, JsonDeserializeHandler handler)
|
||||
{
|
||||
//peek() => call ReadBuffer(); =>call internal origin stream byte[] copy local byte[] -> default utf8 convert -> generate char[]
|
||||
streamReader.Peek();
|
||||
char[] buf = StreamOperate.GetStreamReaderCharBuffer(streamReader);
|
||||
int len = StreamOperate.GetStreamReaderCharLen(streamReader);
|
||||
fixed (char* c = buf)
|
||||
{
|
||||
JsonReader reader = new JsonReader(buf,len, c);
|
||||
T result = Get(reader, handler);
|
||||
reader.ReadEnd();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal static T InvokeGet(JsonReader reader, JsonDeserializeHandler jsonDeserializeHandler)
|
||||
{
|
||||
return Get(reader, jsonDeserializeHandler);
|
||||
}
|
||||
}
|
||||
internal delegate T ResolveDelegate<T>(JsonReader jsonReader, JsonDeserializeHandler handler);
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal class BootTable
|
||||
{
|
||||
internal Dictionary<Type, MethodInfo> DefaultSameTypes = new Dictionary<Type, MethodInfo>();
|
||||
internal List<KeyValuePair<Type, MethodInfoOrder>> DefaultImplementedInterfaces = new List<KeyValuePair<Type, MethodInfoOrder>>();
|
||||
internal List<KeyValuePair<Type, MethodInfoOrder>> DefaultImplementedBaseType = new List<KeyValuePair<Type, MethodInfoOrder>>();
|
||||
|
||||
internal HashSet<Type> DefaultAvoidTypes;
|
||||
internal List<Type> ExpressionBuildTypes = new List<Type>();
|
||||
|
||||
public BootTable(BootTableTypeEnum bootTableTypeEnum)
|
||||
{
|
||||
Type normalBaseType = null;
|
||||
Type expressBaseTypes = null;
|
||||
switch (bootTableTypeEnum)
|
||||
{
|
||||
case BootTableTypeEnum.DeserializeResolve:
|
||||
normalBaseType = typeof(Deserialize.DefaultJsonResolve);
|
||||
expressBaseTypes = typeof(Deserialize.ExpressionJsonResolve);
|
||||
break;
|
||||
case BootTableTypeEnum.SerializerLogic:
|
||||
normalBaseType = typeof(Serializer.DefaultJsonFormatter);
|
||||
expressBaseTypes = typeof(Serializer.ExpressionJsonFormatter);
|
||||
break;
|
||||
}
|
||||
var normalMethods = new List<MethodInfo>();
|
||||
|
||||
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
||||
{
|
||||
if (type.BaseType == expressBaseTypes)
|
||||
ExpressionBuildTypes.Add(type);
|
||||
if (type.BaseType == normalBaseType)
|
||||
normalMethods.AddRange(type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic));
|
||||
}
|
||||
|
||||
foreach (var item in normalMethods)
|
||||
{
|
||||
var atr = item.GetCustomAttribute<FuncLableAttribute>();
|
||||
if (atr == null)
|
||||
continue;
|
||||
|
||||
Type t = null;
|
||||
switch (bootTableTypeEnum)
|
||||
{
|
||||
case BootTableTypeEnum.DeserializeResolve:
|
||||
t = item.ReturnType;
|
||||
break;
|
||||
case BootTableTypeEnum.SerializerLogic:
|
||||
t = item.GetParameters()[0].ParameterType;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (atr._Type)
|
||||
{
|
||||
case FuncType.SameType:
|
||||
DefaultSameTypes.Add(t, item);
|
||||
break;
|
||||
case FuncType.BaseType:
|
||||
DefaultImplementedBaseType.Add(new KeyValuePair<Type, MethodInfoOrder>(t, new MethodInfoOrder(item, atr._Priority)));
|
||||
break;
|
||||
case FuncType.Interface:
|
||||
DefaultImplementedInterfaces.Add(new KeyValuePair<Type, MethodInfoOrder>(t, new MethodInfoOrder(item, atr._Priority)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
DefaultImplementedBaseType = DefaultImplementedBaseType.OrderBy(e => e.Value.Priority).ToList();
|
||||
DefaultImplementedInterfaces = DefaultImplementedInterfaces.OrderBy(e => e.Value.Priority).ToList();
|
||||
|
||||
|
||||
DefaultAvoidTypes = new HashSet<Type>() {
|
||||
typeof(Process),
|
||||
typeof(Delegate),
|
||||
typeof(Thread),
|
||||
typeof(Task)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal enum BootTableTypeEnum
|
||||
{
|
||||
SerializerLogic,
|
||||
DeserializeResolve
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal static class CharHelper
|
||||
{
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static int CharToNumber(this char x)
|
||||
{
|
||||
if ('0' <= x && x <= '9')
|
||||
return x - '0';
|
||||
if ('a' <= x && x <= 'f')
|
||||
return x - 'a' + 10;
|
||||
if ('A' <= x && x <= 'F')
|
||||
return x - 'A' + 10;
|
||||
|
||||
throw new JsonWrongCharacterException("The code unit format is incorrect");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal class CharTries
|
||||
{
|
||||
internal char Val;
|
||||
internal MemberExtension Member;
|
||||
internal bool IsPeak;
|
||||
internal bool IsValue;
|
||||
internal CharTries Parent;
|
||||
internal List<CharTries> Childrens;
|
||||
|
||||
internal CharTries() {
|
||||
Childrens = new List<CharTries>();
|
||||
IsValue = false;
|
||||
}
|
||||
|
||||
internal void Insert(string str,MemberExtension mem)
|
||||
{
|
||||
CharTries charTries = this;
|
||||
foreach (var c in str)
|
||||
{
|
||||
var @case = charTries.Childrens.Find(e => e.Val == c);
|
||||
if (@case == null)
|
||||
{
|
||||
@case = new CharTries() { Val = c, Parent=charTries };
|
||||
charTries.Childrens.Add(@case);
|
||||
}
|
||||
charTries = @case;
|
||||
}
|
||||
charTries.IsValue = true;
|
||||
charTries.Member = mem;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace CPF.Json.Deserialize
|
||||
{
|
||||
internal static class DeserializeBootTable
|
||||
{
|
||||
internal static BootTable Table = new BootTable(BootTableTypeEnum.DeserializeResolve);
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal class ExpressionHelper
|
||||
{
|
||||
internal static Expression For(ParameterExpression loopVar, Expression condition, Expression increment, Expression loopContent)
|
||||
{
|
||||
var initAssign = Expression.Assign(loopVar, Expression.Constant(0));
|
||||
|
||||
var breakLabel = Expression.Label("LoopBreak");
|
||||
|
||||
var loop = Expression.Block(new[] { loopVar },
|
||||
initAssign,
|
||||
Expression.Loop(
|
||||
Expression.IfThenElse(
|
||||
condition,
|
||||
Expression.Block(
|
||||
loopContent,
|
||||
increment
|
||||
),
|
||||
Expression.Break(breakLabel)
|
||||
),
|
||||
breakLabel)
|
||||
);
|
||||
|
||||
return loop;
|
||||
}
|
||||
|
||||
internal static Expression ForEach(Expression enumerable, ParameterExpression loopVar, Func<ParameterExpression, Expression> loopContentAc)
|
||||
{
|
||||
var elementType = loopVar.Type;
|
||||
var enumerableType = typeof(IEnumerable<>).MakeGenericType(elementType);
|
||||
var enumeratorType = typeof(IEnumerator<>).MakeGenericType(elementType);
|
||||
|
||||
var enumeratorVar = Expression.Variable(enumeratorType, "enumerator");
|
||||
var getEnumeratorCall = Expression.Call(enumerable, enumerableType.GetMethod("GetEnumerator"));
|
||||
var enumeratorAssign = Expression.Assign(enumeratorVar, getEnumeratorCall);
|
||||
var enumeratorDispose = Expression.Call(enumeratorVar, typeof(IDisposable).GetMethod("Dispose"));
|
||||
|
||||
// The MoveNext method's actually on IEnumerator, not IEnumerator<T>
|
||||
var moveNextCall = Expression.Call(enumeratorVar, typeof(IEnumerator).GetMethod("MoveNext"));
|
||||
|
||||
var breakLabel = Expression.Label("LoopBreak");
|
||||
|
||||
var trueConstant = Expression.Constant(true);
|
||||
|
||||
var loop =
|
||||
Expression.Loop(
|
||||
Expression.IfThenElse(
|
||||
Expression.Equal(moveNextCall, trueConstant),
|
||||
Expression.Block(
|
||||
new[] { loopVar },
|
||||
Expression.Assign(loopVar, Expression.Property(enumeratorVar, "Current")),
|
||||
loopContentAc(loopVar)),
|
||||
Expression.Break(breakLabel)),
|
||||
breakLabel);
|
||||
|
||||
var tryFinally =
|
||||
Expression.TryFinally(
|
||||
loop,
|
||||
enumeratorDispose);
|
||||
|
||||
var body =
|
||||
Expression.Block(
|
||||
new[] { enumeratorVar },
|
||||
enumeratorAssign,
|
||||
tryFinally);
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using CPF.Json.Deserialize;
|
||||
using CPF.Json.Serializer;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal class ExpressionBuildTypeAttribute : Attribute
|
||||
{
|
||||
internal DeserializeBuildTypeEnum _deserializeBuildType;
|
||||
|
||||
internal SerializerBuildTypeEnum _serializerBuildTypeEnum;
|
||||
|
||||
internal ExpressionBuildTypeAttribute(DeserializeBuildTypeEnum buildType)
|
||||
{
|
||||
_deserializeBuildType = buildType;
|
||||
}
|
||||
|
||||
internal ExpressionBuildTypeAttribute(SerializerBuildTypeEnum buildType)
|
||||
{
|
||||
_serializerBuildTypeEnum = buildType;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
internal class FuncLableAttribute : Attribute
|
||||
{
|
||||
public FuncType _Type;
|
||||
public int _Priority;
|
||||
public FuncLableAttribute(FuncType funcType)
|
||||
{
|
||||
_Type = funcType;
|
||||
}
|
||||
|
||||
public FuncLableAttribute(FuncType funcType, int priority)
|
||||
{
|
||||
_Type = funcType;
|
||||
_Priority = priority;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal enum FuncType
|
||||
{
|
||||
SameType,
|
||||
BaseType,
|
||||
Interface
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Pack = 1)]
|
||||
internal struct GuidStruct
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal Guid Value;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public byte B00;
|
||||
[FieldOffset(1)]
|
||||
public byte B01;
|
||||
[FieldOffset(2)]
|
||||
public byte B02;
|
||||
[FieldOffset(3)]
|
||||
public byte B03;
|
||||
[FieldOffset(4)]
|
||||
public byte B04;
|
||||
[FieldOffset(5)]
|
||||
public byte B05;
|
||||
|
||||
[FieldOffset(6)]
|
||||
public byte B06;
|
||||
[FieldOffset(7)]
|
||||
public byte B07;
|
||||
[FieldOffset(8)]
|
||||
public byte B08;
|
||||
[FieldOffset(9)]
|
||||
public byte B09;
|
||||
|
||||
[FieldOffset(10)]
|
||||
public byte B10;
|
||||
[FieldOffset(11)]
|
||||
public byte B11;
|
||||
|
||||
[FieldOffset(12)]
|
||||
public byte B12;
|
||||
[FieldOffset(13)]
|
||||
public byte B13;
|
||||
[FieldOffset(14)]
|
||||
public byte B14;
|
||||
[FieldOffset(15)]
|
||||
public byte B15;
|
||||
|
||||
public GuidStruct(Guid invisibleMembers)
|
||||
: this()
|
||||
{
|
||||
Value = invisibleMembers;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 对Model中的字符读取状态:默认、首字母大写、首字母小写、忽略大小写
|
||||
/// Read status for characters in the Model: Default, Initial uppercase, Initial lowercase, Ignore case
|
||||
/// </summary>
|
||||
public enum JsonCharacterReadStateEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认
|
||||
/// Default
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// 首字母大写
|
||||
/// Initial uppercase
|
||||
/// </summary>
|
||||
InitialUpper,
|
||||
/// <summary>
|
||||
/// 首字母小写
|
||||
/// Initial lowercase
|
||||
/// </summary>
|
||||
InitialLower,
|
||||
/// <summary>
|
||||
/// 仅反序列化时使用,忽略大小写
|
||||
/// Used only for deserialization ,Ignore case
|
||||
/// </summary>
|
||||
IgnoreCase
|
||||
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal class MemberExtension
|
||||
{
|
||||
internal Type Type { get; set; }
|
||||
internal string Name { get; set; }
|
||||
internal MemberInfo MemberInfo { get; set; }
|
||||
internal FieldInfo FieldInfo { get; set; }
|
||||
internal PropertyInfo PropertyInfo { get; set; }
|
||||
internal bool IsProperty { get; set; }
|
||||
internal int OrderNum { get; set; }
|
||||
|
||||
internal MemberExtension(PropertyInfo pro)
|
||||
{
|
||||
MemberInfo = pro;
|
||||
PropertyInfo = pro;
|
||||
Name = pro.Name;
|
||||
IsProperty = true;
|
||||
Type = pro.PropertyType;
|
||||
}
|
||||
|
||||
internal MemberExtension(FieldInfo pro)
|
||||
{
|
||||
MemberInfo = pro;
|
||||
FieldInfo = pro;
|
||||
Name = pro.Name;
|
||||
IsProperty = false;
|
||||
Type = pro.FieldType;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal class MethodInfoOrder
|
||||
{
|
||||
internal MethodInfo MethodInfo;
|
||||
internal int Priority;
|
||||
public MethodInfoOrder(MethodInfo methodInfo)
|
||||
{
|
||||
MethodInfo = methodInfo;
|
||||
}
|
||||
public MethodInfoOrder(MethodInfo methodInfo,int priority)
|
||||
{
|
||||
MethodInfo = methodInfo;
|
||||
Priority = priority;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class RemoveWriterHelper
|
||||
{
|
||||
internal static MethodInfo _RemoveDictionaryKey = typeof(RemoveWriterHelper).GetMethod(nameof(RemoveDictionaryKey), BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(JsonSerializerHandler) }, null);
|
||||
internal static void RemoveDictionaryKey(JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.stringBuilder != null)
|
||||
{
|
||||
if (handler.stringBuilder.Length < 3)
|
||||
return;
|
||||
int startIndex = 0;
|
||||
int leng = -1;
|
||||
for (int i = handler.stringBuilder.Length - 2 - 1; i >= 0; i--)
|
||||
{
|
||||
if (handler.stringBuilder[i] == '"')
|
||||
{
|
||||
startIndex = i;
|
||||
leng = handler.stringBuilder.Length - i;
|
||||
|
||||
if (i - 1 > 0)
|
||||
{
|
||||
if (handler.stringBuilder[i - 1] == ',')
|
||||
{
|
||||
startIndex = startIndex - 1;
|
||||
leng = leng + 1;
|
||||
}
|
||||
}
|
||||
handler.stringBuilder.Remove(startIndex, leng);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = StreamOperate.GetStreamWriterCharLen(handler.streamWriter);
|
||||
if (length < 3)
|
||||
return;
|
||||
char[] buf = StreamOperate.GetStreamWriterCharBuffer(handler.streamWriter);
|
||||
int startIndex = 0;
|
||||
int leng = -1;
|
||||
for (int i = length - 2 - 1; i >= 0; i--)
|
||||
{
|
||||
if (buf[i] == '"')
|
||||
{
|
||||
startIndex = i;
|
||||
leng = length - i;
|
||||
|
||||
if (i - 1 > 0)
|
||||
{
|
||||
if (buf[i - 1] == ',')
|
||||
{
|
||||
startIndex = startIndex - 1;
|
||||
leng = leng + 1;
|
||||
}
|
||||
}
|
||||
handler.streamWriter.Remove(startIndex, leng);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static MethodInfo _RemoveArrayItem = typeof(RemoveWriterHelper).GetMethod(nameof(RemoveArrayItem), BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(JsonSerializerHandler) }, null);
|
||||
internal static void RemoveArrayItem(JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.stringBuilder != null)
|
||||
{
|
||||
if (handler.stringBuilder.Length <= 1)
|
||||
return;
|
||||
if (handler.stringBuilder[handler.stringBuilder.Length - 1] == '[')
|
||||
return;
|
||||
if (handler.stringBuilder[handler.stringBuilder.Length - 1] == ':')
|
||||
RemoveDictionaryKey(handler);
|
||||
else
|
||||
handler.stringBuilder.Remove(handler.stringBuilder.Length - 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = StreamOperate.GetStreamWriterCharLen(handler.streamWriter);
|
||||
if (length <= 1)
|
||||
return;
|
||||
char[] buf = StreamOperate.GetStreamWriterCharBuffer(handler.streamWriter);
|
||||
if (buf[length - 1] == '[')
|
||||
return;
|
||||
if (buf[length - 1] == ':')
|
||||
RemoveDictionaryKey(handler);
|
||||
else
|
||||
handler.streamWriter.Remove(length - 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
internal static MethodInfo _RemoveKeyAndAddIndex = typeof(RemoveWriterHelper).GetMethod(nameof(RemoveKeyAndAddIndex), BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(JsonSerializerHandler), typeof(Stack<int>) }, null);
|
||||
internal static void RemoveKeyAndAddIndex(JsonSerializerHandler handler, Stack<int> commaIndexs)
|
||||
{
|
||||
if (handler.stringBuilder != null)
|
||||
{
|
||||
StringBuilder sb = handler.stringBuilder;
|
||||
if (sb.Length < 3)
|
||||
return;
|
||||
int startIndex = 0;
|
||||
int leng = -1;
|
||||
for (int i = sb.Length - 2 - 1; i >= 0; i--)
|
||||
{
|
||||
if (sb[i] == '"')
|
||||
{
|
||||
startIndex = i;
|
||||
leng = sb.Length - i;
|
||||
|
||||
sb.Remove(startIndex, leng);
|
||||
commaIndexs.Push(sb.Length - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = StreamOperate.GetStreamWriterCharLen(handler.streamWriter);
|
||||
if (length < 3)
|
||||
return;
|
||||
int startIndex = 0;
|
||||
char[] buf = StreamOperate.GetStreamWriterCharBuffer(handler.streamWriter);
|
||||
int leng = -1;
|
||||
for (int i = length - 2 - 1; i >= 0; i--)
|
||||
{
|
||||
if (buf[i] == '"')
|
||||
{
|
||||
startIndex = i;
|
||||
leng = length - i;
|
||||
|
||||
handler.streamWriter.Remove(startIndex, leng);
|
||||
commaIndexs.Push(length - leng - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static MethodInfo _RemoveLastComma = typeof(RemoveWriterHelper).GetMethod(nameof(RemoveLastComma), BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(JsonSerializerHandler) }, null);
|
||||
internal static void RemoveLastComma(JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.stringBuilder != null)
|
||||
{
|
||||
StringBuilder sb = handler.stringBuilder;
|
||||
if (sb[sb.Length - 1] == ',')
|
||||
sb.Remove(sb.Length - 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = StreamOperate.GetStreamWriterCharLen(handler.streamWriter);
|
||||
char[] buf = StreamOperate.GetStreamWriterCharBuffer(handler.streamWriter);
|
||||
if (buf[length - 1] == ',')
|
||||
handler.streamWriter.Remove(length - 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
internal static MethodInfo _DeleteComma = typeof(RemoveWriterHelper).GetMethod(nameof(DeleteComma), BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(JsonSerializerHandler), typeof(Stack<int>) }, null);
|
||||
internal static void DeleteComma(JsonSerializerHandler handler, Stack<int> lists)
|
||||
{
|
||||
if (handler.stringBuilder != null)
|
||||
{
|
||||
StringBuilder sb = handler.stringBuilder;
|
||||
if (lists.Count > 0)
|
||||
{
|
||||
RemoveLastComma(handler);
|
||||
|
||||
var lastCommaIndex = lists.Peek();
|
||||
|
||||
if (lastCommaIndex >= sb.Length - 1)
|
||||
{
|
||||
lists.Pop();
|
||||
}
|
||||
}
|
||||
while (lists.Count > 0)
|
||||
{
|
||||
var index = lists.Pop();
|
||||
sb.Remove(index + 1, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lists.Count > 0)
|
||||
{
|
||||
RemoveLastComma(handler);
|
||||
|
||||
var lastCommaIndex = lists.Peek();
|
||||
|
||||
if (lastCommaIndex >= StreamOperate.GetStreamWriterCharLen(handler.streamWriter) - 1)
|
||||
{
|
||||
lists.Pop();
|
||||
}
|
||||
}
|
||||
while (lists.Count > 0)
|
||||
{
|
||||
var index = lists.Pop();
|
||||
handler.streamWriter.Remove(index + 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal static class SerializerBootTable
|
||||
{
|
||||
internal static BootTable Table = new BootTable(BootTableTypeEnum.SerializerLogic);
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal static class StreamOperate
|
||||
{
|
||||
internal static Func<StreamReader, char[]> GetStreamReaderCharBuffer = BuildStreamReaderCharBufferFunc();
|
||||
internal static Func<StreamReader, int> GetStreamReaderCharLen = BuildStreamReaderCharLenFunc();
|
||||
|
||||
|
||||
static Func<StreamReader, char[]> BuildStreamReaderCharBufferFunc()
|
||||
{
|
||||
var instance = Expression.Parameter(typeof(StreamReader));
|
||||
var info = typeof(StreamReader).GetField("_charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamReader).GetField("charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var buf = Expression.MakeMemberAccess(instance, info);
|
||||
return Expression.Lambda<Func<StreamReader, char[]>>(buf, new[] { instance }).Compile();
|
||||
}
|
||||
static Func<StreamReader, int> BuildStreamReaderCharLenFunc()
|
||||
{
|
||||
var instance = Expression.Parameter(typeof(StreamReader));
|
||||
var info = typeof(StreamReader).GetField("_charLen", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamReader).GetField("charLen", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var len = Expression.MakeMemberAccess(instance, info);
|
||||
return Expression.Lambda<Func<StreamReader, int>>(len, new[] { instance }).Compile();
|
||||
}
|
||||
|
||||
|
||||
internal static Func<StreamWriter, char[]> GetStreamWriterCharBuffer = BuildStreamWriterCharBufferFunc();
|
||||
internal static Func<StreamWriter, int> GetStreamWriterCharLen = BuildStreamWriterCharPosFunc();
|
||||
internal static Action<StreamWriter, int> SetStreamWriterCharLen = BuildSetStreamWriterCharPosFunc();
|
||||
|
||||
|
||||
static Func<StreamWriter, char[]> BuildStreamWriterCharBufferFunc()
|
||||
{
|
||||
var instance = Expression.Parameter(typeof(StreamWriter));
|
||||
var info = typeof(StreamWriter).GetField("_charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamWriter).GetField("charBuffer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var buf = Expression.MakeMemberAccess(instance, info);
|
||||
return Expression.Lambda<Func<StreamWriter, char[]>>(buf, new[] { instance }).Compile();
|
||||
}
|
||||
static Func<StreamWriter, int> BuildStreamWriterCharPosFunc()
|
||||
{
|
||||
var instance = Expression.Parameter(typeof(StreamWriter));
|
||||
var info = typeof(StreamWriter).GetField("_charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamWriter).GetField("charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var pos = Expression.MakeMemberAccess(instance, info);
|
||||
return Expression.Lambda<Func<StreamWriter, int>>(pos, new[] { instance }).Compile();
|
||||
}
|
||||
static Action<StreamWriter, int> BuildSetStreamWriterCharPosFunc()
|
||||
{
|
||||
var instance = Expression.Parameter(typeof(StreamWriter));
|
||||
var num = Expression.Parameter(typeof(int));
|
||||
var info = typeof(StreamWriter).GetField("_charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? typeof(StreamWriter).GetField("charPos", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
var pos = Expression.MakeMemberAccess(instance, info);
|
||||
var assign = Expression.Assign(pos, num);
|
||||
return Expression.Lambda<Action<StreamWriter, int>>(assign, new[] { instance, num }).Compile();
|
||||
}
|
||||
|
||||
|
||||
internal unsafe static void Remove(this StreamWriter streamWriter, int start, int length)
|
||||
{
|
||||
int pos = GetStreamWriterCharLen(streamWriter);
|
||||
SetStreamWriterCharLen(streamWriter, pos - length);
|
||||
if (start + length == pos)
|
||||
return;
|
||||
char[] buf = GetStreamWriterCharBuffer(streamWriter);
|
||||
Array.Copy(buf, start + length, buf, start, pos - (start + length));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,434 +0,0 @@
|
||||
using CPF.Json.Deserialize;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal enum ReadMemberStateEnum
|
||||
{
|
||||
All,
|
||||
CanRead,
|
||||
CanWrite
|
||||
}
|
||||
|
||||
internal static class TypeKeysCache<T>
|
||||
{
|
||||
internal static string[] Keys = typeof(T).GetModelMembers().Select(e => e.Key).ToArray();
|
||||
internal static bool NotContains(string key) => !Keys.Contains(key);
|
||||
}
|
||||
|
||||
internal static class TypeUtils
|
||||
{
|
||||
internal static MethodInfo GetContainsMethodInfo(Type t)
|
||||
{
|
||||
return typeof(TypeKeysCache<>).MakeGenericType(t).GetMethod("NotContains", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
}
|
||||
|
||||
internal static bool IsAnonymousType(this Type type)
|
||||
{
|
||||
return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
|
||||
&& type.Name.Contains("AnonymousType")
|
||||
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
|
||||
&& (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
|
||||
}
|
||||
|
||||
internal static List<KeyValuePair<string, MemberExtension>> GetModelMembers(this Type type, ReadMemberStateEnum readMemberStateEnum = ReadMemberStateEnum.All)
|
||||
{
|
||||
List<KeyValuePair<string, MemberExtension>> list = new List<KeyValuePair<string, MemberExtension>>();
|
||||
List<KeyValuePair<string, MemberExtension>> jsonOnlyIncludeLists = new List<KeyValuePair<string, MemberExtension>>();
|
||||
Type ignoreAttribute = typeof(IgnoreKeyAttribute);
|
||||
List<PropertyInfo> pors = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
|
||||
if (type.IsInterface)
|
||||
{
|
||||
Type[] interfaces = type.GetInterfaces();
|
||||
if (interfaces.Length > 0)
|
||||
{
|
||||
foreach (var item in interfaces)
|
||||
{
|
||||
pors.AddRange(item.GetProperties());
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var item in pors)
|
||||
{
|
||||
if (item.IsDefined(ignoreAttribute, false))
|
||||
continue;
|
||||
if (item.GetIndexParameters().Length > 0)
|
||||
continue;
|
||||
if (readMemberStateEnum == ReadMemberStateEnum.CanRead)
|
||||
{
|
||||
if (!item.CanRead)
|
||||
continue;
|
||||
}
|
||||
else if (readMemberStateEnum == ReadMemberStateEnum.CanWrite)
|
||||
{
|
||||
if (!item.CanWrite)
|
||||
continue;
|
||||
}
|
||||
var mem = new MemberExtension(item);
|
||||
|
||||
//alias
|
||||
AliasAttribute alias = item.GetCustomAttribute<AliasAttribute>(false);
|
||||
var name = alias != null ? alias._name : mem.Name;
|
||||
|
||||
//order
|
||||
JsonOrderAttribute order = item.GetCustomAttribute<JsonOrderAttribute>(false);
|
||||
mem.OrderNum = order?._orderNum ?? ushort.MaxValue + 1;
|
||||
|
||||
//jsonOnlyIncludeAttribute
|
||||
JsonOnlyIncludeAttribute jsonMember = item.GetCustomAttribute<JsonOnlyIncludeAttribute>(false);
|
||||
if (jsonMember != null)
|
||||
jsonOnlyIncludeLists.Add(new KeyValuePair<string, MemberExtension>(name, mem));
|
||||
|
||||
list.Add(new KeyValuePair<string, MemberExtension>(name, mem));
|
||||
}
|
||||
|
||||
FieldInfo[] fils = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (var item in fils)
|
||||
{
|
||||
if (item.IsDefined(ignoreAttribute, false))
|
||||
continue;
|
||||
var mem = new MemberExtension(item);
|
||||
|
||||
//alias
|
||||
AliasAttribute alias = item.GetCustomAttribute<AliasAttribute>(false);
|
||||
var name = alias != null ? alias._name : mem.Name;
|
||||
|
||||
//order
|
||||
JsonOrderAttribute order = item.GetCustomAttribute<JsonOrderAttribute>(false);
|
||||
mem.OrderNum = order?._orderNum ?? ushort.MaxValue + 1;
|
||||
|
||||
//jsonOnlyIncludeAttribute
|
||||
JsonOnlyIncludeAttribute jsonMember = item.GetCustomAttribute<JsonOnlyIncludeAttribute>(false);
|
||||
if (jsonMember != null)
|
||||
jsonOnlyIncludeLists.Add(new KeyValuePair<string, MemberExtension>(name, mem));
|
||||
|
||||
list.Add(new KeyValuePair<string, MemberExtension>(name, mem));
|
||||
}
|
||||
|
||||
if (jsonOnlyIncludeLists.Count > 0)
|
||||
{
|
||||
jsonOnlyIncludeLists = jsonOnlyIncludeLists.OrderBy(e => e.Value.OrderNum).ToList();
|
||||
return jsonOnlyIncludeLists;
|
||||
}
|
||||
|
||||
list = list.OrderBy(e => e.Value.OrderNum).ToList();
|
||||
return list;
|
||||
}
|
||||
|
||||
internal static CharTries GetCharTries(this Type type)
|
||||
{
|
||||
CharTries charTries = new CharTries() { IsPeak = true };
|
||||
type.GetModelMembers(ReadMemberStateEnum.All).ForEach(
|
||||
e =>
|
||||
charTries.Insert(e.Key, e.Value)
|
||||
);
|
||||
return charTries;
|
||||
}
|
||||
|
||||
internal static List<Type> GetTypeAndBaseTypes(this Type type)
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
if (type != null)
|
||||
{
|
||||
types.Add(type);
|
||||
types.AddRange(GetBaseTypes(type));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
internal static List<Type> GetBaseTypes(this Type type)
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
if (type != null)
|
||||
{
|
||||
if (type.BaseType != null && type.BaseType != typeof(object))
|
||||
{
|
||||
types.Add(type.BaseType);
|
||||
types.AddRange(GetBaseTypes(type.BaseType));
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
internal static List<MemberInfo> GetAllInterfaceMembers(this Type type)
|
||||
{
|
||||
if (!type.IsInterface) throw new Exception("Expected interface, found: " + type);
|
||||
var pending = new Stack<Type>();
|
||||
pending.Push(type);
|
||||
var ret = new List<MemberInfo>();
|
||||
while (pending.Count > 0)
|
||||
{
|
||||
var current = pending.Pop();
|
||||
|
||||
ret.AddRange(current.GetMembers());
|
||||
|
||||
if (current.BaseType != null)
|
||||
{
|
||||
pending.Push(current.BaseType);
|
||||
}
|
||||
|
||||
foreach (var x in current.GetInterfaces())
|
||||
{
|
||||
pending.Push(x);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
internal static ConstructorInfo GetValueTypeCtor(this Type type, ref List<Expression> args)
|
||||
{
|
||||
|
||||
var cs = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (var item in cs)
|
||||
{
|
||||
var pars = item.GetParameters();
|
||||
JsonDeserializeCtorAttribute jsonDeserializeCtorAttribute = item.GetCustomAttribute<JsonDeserializeCtorAttribute>();
|
||||
if (jsonDeserializeCtorAttribute != null)
|
||||
{
|
||||
args = new List<Expression>();
|
||||
|
||||
for (int i = 0; i < jsonDeserializeCtorAttribute._args.Length; i++)
|
||||
{
|
||||
args.Add(Expression.Constant(jsonDeserializeCtorAttribute._args[i], pars[i].ParameterType));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static ConstructorInfo GetClassCtor(this Type type, ref List<Expression> args)
|
||||
{
|
||||
var cs = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
ConstructorInfo attrCtor = null, publicNoArgsCtor = null, privateNoArgsCtor = null, publicArgsCtor = null, privateArgsCtor = null;
|
||||
List<Expression> attrCtorArgs = null; ParameterInfo[] publicArgsCtorParas = null, privateArgsCtorParas = null;
|
||||
foreach (var item in cs)
|
||||
{
|
||||
var pars = item.GetParameters();
|
||||
JsonDeserializeCtorAttribute jsonDeserializeCtorAttribute = item.GetCustomAttribute<JsonDeserializeCtorAttribute>();
|
||||
if (jsonDeserializeCtorAttribute != null)
|
||||
{
|
||||
attrCtorArgs = new List<Expression>();
|
||||
attrCtor = item;
|
||||
|
||||
for (int i = 0; i < jsonDeserializeCtorAttribute._args.Length; i++)
|
||||
{
|
||||
attrCtorArgs.Add(Expression.Constant(jsonDeserializeCtorAttribute._args[i], pars[i].ParameterType));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (item.IsPublic)
|
||||
{
|
||||
if (pars.Length == 0)
|
||||
{
|
||||
publicNoArgsCtor = item;
|
||||
}
|
||||
else if (publicArgsCtor == null || pars.Length < publicArgsCtor.GetParameters().Length)
|
||||
{
|
||||
publicArgsCtor = item;
|
||||
publicArgsCtorParas = pars;
|
||||
}
|
||||
}
|
||||
else if (item.IsPrivate)
|
||||
{
|
||||
if (pars.Length == 0)
|
||||
{
|
||||
privateNoArgsCtor = item;
|
||||
}
|
||||
else if (privateArgsCtor == null || pars.Length < privateArgsCtor.GetParameters().Length)
|
||||
{
|
||||
privateArgsCtor = item;
|
||||
privateArgsCtorParas = pars;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (attrCtor != null)
|
||||
{
|
||||
args = attrCtorArgs;
|
||||
return attrCtor;
|
||||
}
|
||||
if (publicNoArgsCtor != null)
|
||||
{
|
||||
args = null;
|
||||
return publicNoArgsCtor;
|
||||
}
|
||||
if (privateNoArgsCtor != null)
|
||||
{
|
||||
args = null;
|
||||
return privateNoArgsCtor;
|
||||
}
|
||||
if (publicArgsCtor != null)
|
||||
{
|
||||
args = new List<Expression>();
|
||||
for (int i = 0; i < publicArgsCtorParas.Length; i++)
|
||||
{
|
||||
object value = null;
|
||||
var paraType = publicArgsCtorParas[i].ParameterType;
|
||||
if (paraType.IsValueType)
|
||||
value = Activator.CreateInstance(paraType);
|
||||
args.Add(Expression.Constant(value, paraType));
|
||||
}
|
||||
return publicArgsCtor;
|
||||
}
|
||||
else //(privateArgsCtor != null)
|
||||
{
|
||||
args = new List<Expression>();
|
||||
for (int i = 0; i < publicArgsCtorParas.Length; i++)
|
||||
{
|
||||
object value = null;
|
||||
var paraType = publicArgsCtorParas[i].ParameterType;
|
||||
if (paraType.IsValueType)
|
||||
value = Activator.CreateInstance(paraType);
|
||||
args.Add(Expression.Constant(value, paraType));
|
||||
}
|
||||
return privateArgsCtor;
|
||||
}
|
||||
}
|
||||
|
||||
internal static ConstructorInfo GetCtorByParameterInterfaceType(this Type type, params Type[] ctorParaTypes)
|
||||
{
|
||||
foreach (var ctor in type.GetConstructors())
|
||||
{
|
||||
var ctorParas = ctor.GetParameters();
|
||||
if (ctorParas.Length == ctorParaTypes.Length)
|
||||
{
|
||||
bool isTrue = true;
|
||||
for (int i = 0; i < ctorParaTypes.Length; i++)
|
||||
{
|
||||
if (ctorParas[i].ParameterType != ctorParaTypes[i])
|
||||
{
|
||||
isTrue = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (isTrue)
|
||||
return ctor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static ConstructorInfo GetDefaultNoArgCtorOrAppointTypeCtor(this Type type, Type ctorParaTypes = null)
|
||||
{
|
||||
foreach (var ctor in type.GetConstructors())
|
||||
{
|
||||
var ctorParas = ctor.GetParameters();
|
||||
if (ctorParas.Length == 0)
|
||||
return ctor;//no args
|
||||
if (ctorParaTypes != null && ctorParas.Length == 1)
|
||||
{
|
||||
if (ctorParas[0].ParameterType == ctorParaTypes)
|
||||
return ctor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static ConstructorInfo GetAppointTypeCtor(this Type type, Type ctorParaTypes)
|
||||
{
|
||||
foreach (var ctor in type.GetConstructors())
|
||||
{
|
||||
var ctorParas = ctor.GetParameters();
|
||||
if (ctorParas.Length == 1 && ctorParas[0].ParameterType == ctorParaTypes)
|
||||
{
|
||||
return ctor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static bool HasEmptyCtor(this Type type)
|
||||
{
|
||||
if (type.IsInterface)
|
||||
return false;
|
||||
foreach (var ctor in type.GetConstructors())
|
||||
{
|
||||
var ctorParas = ctor.GetParameters();
|
||||
if (ctorParas.Length == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool IsWrongKey(this Type keyType)
|
||||
{
|
||||
if (!keyType.IsPrimitive && !keyType.IsEnum && keyType != typeof(string) && keyType != typeof(Guid) && keyType != typeof(DateTime))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
internal static object GetDefaultValue(this Type type)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
return Activator.CreateInstance(type);
|
||||
return null;
|
||||
}
|
||||
|
||||
#if Net4
|
||||
public static Attribute GetCustomAttribute(this Assembly element, Type attributeType)
|
||||
{
|
||||
return Attribute.GetCustomAttribute(element, attributeType);
|
||||
}
|
||||
public static Attribute GetCustomAttribute(this Module element, Type attributeType)
|
||||
{
|
||||
return Attribute.GetCustomAttribute(element, attributeType);
|
||||
}
|
||||
public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType)
|
||||
{
|
||||
return Attribute.GetCustomAttribute(element, attributeType);
|
||||
}
|
||||
public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType)
|
||||
{
|
||||
return Attribute.GetCustomAttribute(element, attributeType);
|
||||
}
|
||||
|
||||
public static T GetCustomAttribute<T>(this Assembly element) where T : Attribute
|
||||
{
|
||||
return (T)GetCustomAttribute(element, typeof(T));
|
||||
}
|
||||
public static T GetCustomAttribute<T>(this Module element) where T : Attribute
|
||||
{
|
||||
return (T)GetCustomAttribute(element, typeof(T));
|
||||
}
|
||||
public static T GetCustomAttribute<T>(this MemberInfo element) where T : Attribute
|
||||
{
|
||||
return (T)GetCustomAttribute(element, typeof(T));
|
||||
}
|
||||
public static T GetCustomAttribute<T>(this ParameterInfo element) where T : Attribute
|
||||
{
|
||||
return (T)GetCustomAttribute(element, typeof(T));
|
||||
}
|
||||
|
||||
public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType, bool inherit)
|
||||
{
|
||||
return Attribute.GetCustomAttribute(element, attributeType, inherit);
|
||||
}
|
||||
public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType, bool inherit)
|
||||
{
|
||||
return Attribute.GetCustomAttribute(element, attributeType, inherit);
|
||||
}
|
||||
|
||||
public static T GetCustomAttribute<T>(this MemberInfo element, bool inherit) where T : Attribute
|
||||
{
|
||||
return (T)GetCustomAttribute(element, typeof(T), inherit);
|
||||
}
|
||||
public static T GetCustomAttribute<T>(this ParameterInfo element, bool inherit) where T : Attribute
|
||||
{
|
||||
return (T)GetCustomAttribute(element, typeof(T), inherit);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class BaseTypeNormal: DefaultJsonFormatter
|
||||
{
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.BaseType)]
|
||||
internal static void WriteValue(Exception value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == null)
|
||||
handler.WriteString("null");
|
||||
else
|
||||
{
|
||||
handler.WriteString("{\"Message\":");
|
||||
PrimitiveNormal.WriteValue(value.Message, handler);
|
||||
handler.WriteString(",\"Source\":");
|
||||
PrimitiveNormal.WriteValue(value.Source, handler);
|
||||
handler.WriteString(",\"StackTrace\":");
|
||||
PrimitiveNormal.WriteValue(value.StackTrace, handler);
|
||||
handler.WriteString(",\"HelpLink\":");
|
||||
PrimitiveNormal.WriteValue(value.HelpLink, handler);
|
||||
handler.WriteString("}");
|
||||
}
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.BaseType)]
|
||||
internal static void WriteValue(Type value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == null)
|
||||
handler.WriteString("null");
|
||||
else
|
||||
PrimitiveNormal.WriteValue(value.AssemblyQualifiedName, handler);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,400 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class PrimitiveNormal : DefaultJsonFormatter
|
||||
{
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(int value, JsonSerializerHandler handler)
|
||||
{
|
||||
// Gotta special case this, we can't negate it
|
||||
if (value == int.MinValue)
|
||||
{
|
||||
handler.WriteString("-2147483648");
|
||||
return;
|
||||
}
|
||||
if (value == int.MaxValue)
|
||||
{
|
||||
handler.WriteString("2147483647");
|
||||
return;
|
||||
}
|
||||
var ptr = 35;
|
||||
char[] buffer = new char[36];
|
||||
uint copy;
|
||||
if (value < 0)
|
||||
{
|
||||
handler.WriteChar('-');
|
||||
copy = (uint)(-value);
|
||||
}
|
||||
else
|
||||
copy = (uint)value;
|
||||
|
||||
do
|
||||
{
|
||||
byte ix = (byte)(copy % 100);
|
||||
copy /= 100;
|
||||
|
||||
var chars = SpecialTypeNormal. DigitPairs[ix];
|
||||
buffer[ptr--] = chars.Second;
|
||||
buffer[ptr--] = chars.First;
|
||||
} while (copy != 0);
|
||||
|
||||
if (buffer[ptr + 1] == '0')
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(uint value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == uint.MaxValue)
|
||||
{
|
||||
handler.WriteString("4294967295");
|
||||
return;
|
||||
}
|
||||
var ptr = 35;
|
||||
char[] buffer = new char[36];
|
||||
var copy = value;
|
||||
|
||||
do
|
||||
{
|
||||
byte ix = (byte)(copy % 100);
|
||||
copy /= 100;
|
||||
|
||||
var chars = SpecialTypeNormal.DigitPairs[ix];
|
||||
buffer[ptr--] = chars.Second;
|
||||
buffer[ptr--] = chars.First;
|
||||
} while (copy != 0);
|
||||
|
||||
if (buffer[ptr + 1] == '0')
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(long value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == long.MinValue)
|
||||
{
|
||||
handler.WriteString("-9223372036854775808");
|
||||
return;
|
||||
}
|
||||
char[] buffer = new char[36];
|
||||
var ptr = 35;
|
||||
|
||||
ulong copy;
|
||||
if (value < 0)
|
||||
{
|
||||
handler.WriteChar('-');
|
||||
copy = (ulong)(-value);
|
||||
}
|
||||
else
|
||||
{
|
||||
copy = (ulong)value;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
byte ix = (byte)(copy % 100);
|
||||
copy /= 100;
|
||||
|
||||
var chars = SpecialTypeNormal.DigitPairs[ix];
|
||||
buffer[ptr--] = chars.Second;
|
||||
buffer[ptr--] = chars.First;
|
||||
} while (copy != 0);
|
||||
|
||||
if (buffer[ptr + 1] == '0')
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(ulong value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == ulong.MaxValue)
|
||||
{
|
||||
handler.WriteString("18446744073709551615");
|
||||
return;
|
||||
}
|
||||
|
||||
var ptr = 35;
|
||||
char[] buffer = new char[36];
|
||||
var copy = value;
|
||||
|
||||
do
|
||||
{
|
||||
byte ix = (byte)(copy % 100);
|
||||
copy /= 100;
|
||||
|
||||
var chars = SpecialTypeNormal.DigitPairs[ix];
|
||||
buffer[ptr--] = chars.Second;
|
||||
buffer[ptr--] = chars.First;
|
||||
} while (copy != 0);
|
||||
|
||||
if (buffer[ptr + 1] == '0')
|
||||
{
|
||||
ptr++;
|
||||
}
|
||||
|
||||
handler.WriteChars(buffer, ptr + 1, 35 - ptr);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(float value, JsonSerializerHandler handler)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case float.NaN:
|
||||
handler.WriteString("\"NaN\"");
|
||||
return;
|
||||
case float.NegativeInfinity:
|
||||
handler.WriteString("\"-Infinity\"");
|
||||
return;
|
||||
case float.PositiveInfinity:
|
||||
handler.WriteString("\"Infinity\"");
|
||||
return;
|
||||
}
|
||||
handler.WriteString(value.ToString("R",CultureInfo.InvariantCulture));
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(decimal value, JsonSerializerHandler handler)
|
||||
{
|
||||
handler.WriteString(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(double value, JsonSerializerHandler handler)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case double.NaN:
|
||||
handler.WriteString("\"NaN\"");
|
||||
return;
|
||||
case double.NegativeInfinity:
|
||||
handler.WriteString("\"-Infinity\"");
|
||||
return;
|
||||
case double.PositiveInfinity:
|
||||
handler.WriteString("\"Infinity\"");
|
||||
return;
|
||||
}
|
||||
handler.WriteString(value.ToString("R", CultureInfo.InvariantCulture));
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(byte value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue((int)value, handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(sbyte value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue((int)value, handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(short value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue((int)value, handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(ushort value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue((int)value, handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(bool value, JsonSerializerHandler handler)
|
||||
{
|
||||
handler.WriteString(value ? "true" : "false");
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(char value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue(char.ToString(value), handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static unsafe void WriteValue(string value, JsonSerializerHandler handler)
|
||||
{
|
||||
/*
|
||||
string = quotation-mark *char quotation-mark
|
||||
|
||||
char = unescaped /
|
||||
escape (
|
||||
%x22 / ; " quotation mark U+0022
|
||||
%x5C / ; \ reverse solidus U+005C
|
||||
%x2F / ; / solidus U+002F
|
||||
%x62 / ; b backspace U+0008
|
||||
%x66 / ; f form feed U+000C
|
||||
%x6E / ; n line feed U+000A
|
||||
%x72 / ; r carriage return U+000D
|
||||
%x74 / ; t tab U+0009
|
||||
%x75 4HEXDIG ) ; uXXXX U+XXXX
|
||||
|
||||
escape = %x5C ; \
|
||||
|
||||
quotation-mark = %x22 ; "
|
||||
|
||||
unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
|
||||
*/
|
||||
if (value == null)
|
||||
{
|
||||
handler.WriteString("null");
|
||||
return;
|
||||
}
|
||||
//handler.Writer.EnsureCapacity(handler.Writer.Capacity + value.Length);
|
||||
handler.WriteString("\"");
|
||||
fixed (char* strFixed = value)
|
||||
{
|
||||
char* str = strFixed;
|
||||
char c;
|
||||
var len = value.Length;
|
||||
while (len > 0)
|
||||
{
|
||||
c = *str;
|
||||
str++;
|
||||
len--;
|
||||
|
||||
if (c == '\\')//\u005c //%x5c a\\b => a\u005cb
|
||||
{
|
||||
handler.WriteString(@"\\");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '"')//\u0022 //%x22
|
||||
{
|
||||
handler.WriteString("\\\"");
|
||||
continue;
|
||||
}
|
||||
switch (c)
|
||||
{
|
||||
//%x00-x19
|
||||
case '\u0000': handler.WriteString(@"\u0000"); continue;
|
||||
case '\u0001': handler.WriteString(@"\u0001"); continue;
|
||||
case '\u0002': handler.WriteString(@"\u0002"); continue;
|
||||
case '\u0003': handler.WriteString(@"\u0003"); continue;
|
||||
case '\u0004': handler.WriteString(@"\u0004"); continue;
|
||||
case '\u0005': handler.WriteString(@"\u0005"); continue;
|
||||
case '\u0006': handler.WriteString(@"\u0006"); continue;
|
||||
case '\u0007': handler.WriteString(@"\u0007"); continue;
|
||||
case '\u0008': handler.WriteString(@"\b"); continue;
|
||||
case '\u0009': handler.WriteString(@"\t"); continue;
|
||||
case '\u000A': handler.WriteString(@"\n"); continue;
|
||||
case '\u000B': handler.WriteString(@"\u000b"); continue;
|
||||
case '\u000C': handler.WriteString(@"\f"); continue;
|
||||
case '\u000D': handler.WriteString(@"\r"); continue;
|
||||
case '\u000E': handler.WriteString(@"\u000e"); continue;
|
||||
case '\u000F': handler.WriteString(@"\u000f"); continue;
|
||||
case '\u0010': handler.WriteString(@"\u0010"); continue;
|
||||
case '\u0011': handler.WriteString(@"\u0011"); continue;
|
||||
case '\u0012': handler.WriteString(@"\u0012"); continue;
|
||||
case '\u0013': handler.WriteString(@"\u0013"); continue;
|
||||
case '\u0014': handler.WriteString(@"\u0014"); continue;
|
||||
case '\u0015': handler.WriteString(@"\u0015"); continue;
|
||||
case '\u0016': handler.WriteString(@"\u0016"); continue;
|
||||
case '\u0017': handler.WriteString(@"\u0017"); continue;
|
||||
case '\u0018': handler.WriteString(@"\u0018"); continue;
|
||||
case '\u0019': handler.WriteString(@"\u0019"); continue;
|
||||
case '\u001A': handler.WriteString(@"\u001a"); continue;
|
||||
case '\u001B': handler.WriteString(@"\u001b"); continue;
|
||||
case '\u001C': handler.WriteString(@"\u001c"); continue;
|
||||
case '\u001D': handler.WriteString(@"\u001d"); continue;
|
||||
case '\u001E': handler.WriteString(@"\u001e"); continue;
|
||||
case '\u001F': handler.WriteString(@"\u001f"); continue;
|
||||
/*JavaScript */
|
||||
case '\u0085': // Next Line
|
||||
handler.WriteString(@"\u0085"); continue;
|
||||
case '\u2028': // Line Separator
|
||||
handler.WriteString(@"\u2028"); continue;
|
||||
case '\u2029': // Paragraph Separator
|
||||
handler.WriteString(@"\u2029"); continue;
|
||||
default: handler.WriteChar(c); continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
handler.WriteString("\"");
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(IntPtr value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue((long)value, handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(UIntPtr value, JsonSerializerHandler handler)
|
||||
{
|
||||
WriteValue((ulong)value, handler);
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
[FuncLable(FuncType.SameType)]
|
||||
internal static void WriteValue(object obj, JsonSerializerHandler handler)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
handler.WriteString("null");
|
||||
return;
|
||||
}
|
||||
var type = obj.GetType();
|
||||
if (type.IsAnonymousType() || type == typeof(object))
|
||||
SpecialConditions.WriteDynamic(obj, handler);
|
||||
else
|
||||
{
|
||||
var jumpAction = SerializerObjectJump.GetThreadSafetyJumpAction(type);
|
||||
jumpAction(obj, handler);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,283 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class SpecialConditions : DefaultJsonFormatter
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static MethodInfo _WriteEnum = typeof(SpecialConditions).GetMethod(nameof(WriteEnum), BindingFlags.NonPublic | BindingFlags.Static);
|
||||
#endregion
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteDynamic(object value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
handler.WriteString("null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
{
|
||||
if (handler.SerializeStacks.Contains(value))
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Null)
|
||||
handler.WriteString("null");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Empty)
|
||||
handler.WriteString("{}");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Remove)
|
||||
RemoveWriterHelper.RemoveDictionaryKey(handler);
|
||||
return;
|
||||
}
|
||||
handler.SerializeStacks.Push(value);
|
||||
}
|
||||
|
||||
var t = value.GetType();
|
||||
handler.WriteString("{");
|
||||
bool isFirst = true;
|
||||
foreach (var item in t.GetProperties())
|
||||
{
|
||||
if (isFirst)
|
||||
isFirst = false;
|
||||
else
|
||||
handler.WriteString(",");
|
||||
handler.WriteString("\"");
|
||||
handler.WriteString(item.Name);
|
||||
handler.WriteString("\"");
|
||||
handler.WriteString(":");
|
||||
#if Net4
|
||||
SerializerObjectJump.GetThreadSafetyJumpAction(item.PropertyType)(item.GetValue(value, null), handler);
|
||||
#else
|
||||
SerializerObjectJump.GetThreadSafetyJumpAction(item.PropertyType)(item.GetValue(value), handler);
|
||||
#endif
|
||||
}
|
||||
handler.WriteString("}");
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void AvoidTypes(object typeVar, JsonSerializerHandler handler)
|
||||
{
|
||||
handler.WriteString(typeVar == null ? "null" : "{}");
|
||||
}
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteEnum(Enum value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.Option.IsEnumNum)
|
||||
PrimitiveNormal.WriteValue(value.GetHashCode(), handler);
|
||||
else
|
||||
{
|
||||
handler.WriteString("\"");
|
||||
handler.WriteString(value.ToString());
|
||||
handler.WriteString("\"");
|
||||
}
|
||||
}
|
||||
|
||||
#region Array
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteCollection(IEnumerable value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
handler.WriteString("null");
|
||||
return;
|
||||
}
|
||||
|
||||
var t = value.GetType();
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
var serializerAction = SerializerObjectJump.GetThreadSafetyJumpAction(t);
|
||||
serializerAction(value, handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isMultidimensionalArray = false;
|
||||
Array ary = null;
|
||||
if (t.IsArray)
|
||||
{
|
||||
ary = (Array)value;
|
||||
if (ary.Rank > 1)
|
||||
isMultidimensionalArray = true;
|
||||
}
|
||||
if (isMultidimensionalArray)
|
||||
WriteMultidimensionalArray(ary, handler);
|
||||
else
|
||||
WriteIEnumerable(value, handler);
|
||||
}
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteIEnumerable(IEnumerable value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
{
|
||||
if (handler.SerializeStacks.Contains(value))
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Null)
|
||||
handler.WriteString("null");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Empty)
|
||||
handler.WriteString("[]");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Remove)
|
||||
RemoveWriterHelper.RemoveArrayItem(handler);
|
||||
return;
|
||||
}
|
||||
handler.SerializeStacks.Push(value);
|
||||
}
|
||||
|
||||
handler.WriteString("[");
|
||||
bool isFirst = true;
|
||||
foreach (var obj in value)
|
||||
{
|
||||
if (isFirst)
|
||||
isFirst = false;
|
||||
else
|
||||
handler.WriteString(",");
|
||||
PrimitiveNormal.WriteValue(obj, handler);
|
||||
}
|
||||
handler.WriteString("]");
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
handler.SerializeStacks.Pop();
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteMultidimensionalArray(Array value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
{
|
||||
if (handler.SerializeStacks.Contains(value))
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Null)
|
||||
handler.WriteString("null");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Empty)
|
||||
handler.WriteString("[]");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Remove)
|
||||
RemoveWriterHelper.RemoveArrayItem(handler);
|
||||
return;
|
||||
}
|
||||
handler.SerializeStacks.Push(value);
|
||||
}
|
||||
var action = SerializerObjectJump.GetThreadSafetyJumpAction(value.GetType().GetElementType());
|
||||
handler.WriteString("[");
|
||||
var enumerator = value.GetEnumerator();
|
||||
MultidimensionalWrite(enumerator, handler, value, action, value.GetLength(0), 0);
|
||||
handler.WriteString("]");
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
handler.SerializeStacks.Pop();
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
private static void MultidimensionalWrite(IEnumerator enumerator, JsonSerializerHandler handler, Array value, Action<object, JsonSerializerHandler> action, int leng, int level)
|
||||
{
|
||||
for (int i = 0; i < leng; i++)
|
||||
{
|
||||
if (level != value.Rank - 1)
|
||||
handler.WriteString("[");
|
||||
|
||||
if (level == value.Rank - 1)
|
||||
{
|
||||
enumerator.MoveNext();
|
||||
action(enumerator.Current, handler);
|
||||
if (i != leng - 1)
|
||||
handler.WriteString(",");
|
||||
continue;
|
||||
}
|
||||
|
||||
int localLevel = level;
|
||||
++localLevel;
|
||||
MultidimensionalWrite(enumerator, handler, value, action, value.GetLength(localLevel), localLevel);
|
||||
|
||||
handler.WriteString("]");
|
||||
|
||||
if (i != leng - 1)
|
||||
handler.WriteString(",");
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Dictionary
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteDictionary(IDictionary value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
handler.WriteString("null");
|
||||
return;
|
||||
}
|
||||
var t = value.GetType();
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
var serializerAction = SerializerObjectJump.GetThreadSafetyJumpAction(t);
|
||||
serializerAction(value, handler);
|
||||
}
|
||||
else
|
||||
WriteIDictionary(value, handler);
|
||||
}
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void WriteIDictionary(IDictionary value, JsonSerializerHandler handler)
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
{
|
||||
if (handler.SerializeStacks.Contains(value))
|
||||
{
|
||||
if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Null)
|
||||
handler.WriteString("null");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Empty)
|
||||
handler.WriteString("{}");
|
||||
else if (handler.Option.ReferenceLoopHandling == JsonReferenceHandlingEnum.Remove)
|
||||
RemoveWriterHelper.RemoveDictionaryKey(handler);
|
||||
return;
|
||||
}
|
||||
handler.SerializeStacks.Push(value);
|
||||
}
|
||||
|
||||
bool isFirst = true;
|
||||
handler.WriteString("{");
|
||||
foreach (DictionaryEntry item in value)
|
||||
{
|
||||
var keyType = item.Key.GetType();
|
||||
if (keyType.IsWrongKey())
|
||||
continue;
|
||||
|
||||
if (isFirst)
|
||||
isFirst = false;
|
||||
else
|
||||
handler.WriteString(",");
|
||||
|
||||
if (keyType.IsPrimitive || (keyType.IsEnum && handler.Option.IsEnumNum))//string,primitive,enum,guid,datetime
|
||||
handler.WriteString("\"");
|
||||
|
||||
PrimitiveNormal.WriteValue(item.Key, handler);
|
||||
|
||||
if (keyType.IsPrimitive || (keyType.IsEnum && handler.Option.IsEnumNum))
|
||||
handler.WriteString("\"");
|
||||
|
||||
handler.WriteString(":");
|
||||
PrimitiveNormal.WriteValue(item.Value, handler);
|
||||
}
|
||||
handler.WriteString("}");
|
||||
if (handler.Option.ReferenceLoopHandling != JsonReferenceHandlingEnum.None)
|
||||
handler.SerializeStacks.Pop();
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class DefaultJsonFormatter : JsonFormatterBase
|
||||
{
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class BuildFactory
|
||||
{
|
||||
static BuildFactory()
|
||||
{
|
||||
var types = SerializerBootTable.Table.ExpressionBuildTypes;
|
||||
foreach (var item in types)
|
||||
{
|
||||
ExpressionBuildTypeAttribute expressionBuildTypeAttribute = (ExpressionBuildTypeAttribute)item.GetCustomAttributes(false).First(e => e.GetType() == typeof(ExpressionBuildTypeAttribute));
|
||||
BuildMethodDics.Add(expressionBuildTypeAttribute._serializerBuildTypeEnum, item.GetMethod("Build", BindingFlags.Static | BindingFlags.NonPublic));
|
||||
}
|
||||
SerializerBootTable.Table.ExpressionBuildTypes = null;
|
||||
}
|
||||
|
||||
internal static Dictionary<Type, Expression> DEBUGSURVEY = new Dictionary<Type, Expression>();
|
||||
|
||||
static Dictionary<SerializerBuildTypeEnum, MethodInfo> BuildMethodDics = new Dictionary<SerializerBuildTypeEnum, MethodInfo>();
|
||||
internal static Action<T, JsonSerializerHandler> Create<T>(SerializerBuildTypeEnum buildTypeEnum)
|
||||
{
|
||||
Type t = typeof(T);
|
||||
ParameterExpression instanceArg = Expression.Variable(t, "instance");
|
||||
Expression mainBody = (Expression)BuildMethodDics[buildTypeEnum].Invoke(null, new object[] { t, instanceArg });
|
||||
|
||||
#if DEBUG
|
||||
DEBUGSURVEY.Add(t, mainBody);
|
||||
#endif
|
||||
|
||||
|
||||
#if VIEW && NET45
|
||||
var methodBuilder = typeBuilder.DefineMethod($"Serializer_{typeof(T).Name}", System.Reflection.MethodAttributes.Static | System.Reflection.MethodAttributes.Public, typeof(void), new Type[] { typeof(T), typeof(JsonSerializerHandler) });
|
||||
|
||||
Expression.Lambda<Action<T, JsonSerializerHandler>>(
|
||||
mainBody, instanceArg, ExpressionMembers.HandlerArg).CompileToMethod(methodBuilder);
|
||||
#endif
|
||||
|
||||
return Expression.Lambda<Action<T, JsonSerializerHandler>>(
|
||||
mainBody, instanceArg, ExpressionMembers.HandlerArg).Compile();
|
||||
}
|
||||
#if VIEW && NET45
|
||||
#if DEBUG
|
||||
static string suffix = "_Debug";
|
||||
#else
|
||||
static string suffix = "_Release";
|
||||
#endif
|
||||
static string name = $"Serializer_CodeView{suffix}";
|
||||
static System.Reflection.Emit.AssemblyBuilder assemblyBuilder = System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly(new System.Reflection.AssemblyName(name), System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave);
|
||||
static System.Reflection.Emit.ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name, name + ".dll");
|
||||
static System.Reflection.Emit.TypeBuilder typeBuilder = moduleBuilder.DefineType("Program");
|
||||
#endif
|
||||
internal static void Save()
|
||||
{
|
||||
#if VIEW && NET45
|
||||
typeBuilder.CreateType();
|
||||
assemblyBuilder.Save(name + ".dll");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal enum SerializerBuildTypeEnum
|
||||
{
|
||||
Nullable,
|
||||
IDictionaryGeneric,
|
||||
IEnumerableGeneric,
|
||||
IListGeneric,
|
||||
WrongGenericKey,
|
||||
KeyValueObject,
|
||||
KeyValuePair,
|
||||
Lazy
|
||||
}
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class ExpressionMembers
|
||||
{
|
||||
//- handler;
|
||||
internal static ParameterExpression HandlerArg = Expression.Parameter(typeof(JsonSerializerHandler), "handler");
|
||||
//- return(label);
|
||||
internal static readonly LabelTarget ReturnLable = Expression.Label(typeof(void));
|
||||
|
||||
//- handler.WriteString
|
||||
internal static readonly MemberExpression WriteString = Expression.MakeMemberAccess(HandlerArg, JsonSerializerHandler._WriteString);
|
||||
|
||||
//- handler.option;
|
||||
internal static readonly MemberExpression JOptionArg = Expression.MakeMemberAccess(HandlerArg, JsonSerializerHandler._Option);
|
||||
//- handler.serializeStacks
|
||||
internal static readonly MemberExpression SerializeStacksArg = Expression.MakeMemberAccess(HandlerArg, JsonSerializerHandler._SerializeStacks);
|
||||
|
||||
//- handler.option.GlobalKeyFormat(delegate)
|
||||
internal static readonly MemberExpression GlobalKeyFormat = Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._GlobalKeyFormat);
|
||||
//- handler.option.GlobalValueFormat(delegate)
|
||||
internal static readonly MemberExpression GlobalValueFormat = Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._GlobalValueFormat);
|
||||
|
||||
//- afterValueFormat(string)
|
||||
internal static readonly ParameterExpression AfterValueFormat = Expression.Variable(typeof(string), "afterValueFormat");
|
||||
//- isValueFormat(bool)
|
||||
internal static readonly ParameterExpression IsValueFormat = Expression.Variable(typeof(bool), "isValueFormat");
|
||||
|
||||
//- handler.option.ignoreKeys(List<string>)
|
||||
internal static readonly MemberExpression IgnoreKeys = Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._IgnoreKeys);
|
||||
//- handler.option.ignoreKeys == null
|
||||
internal static readonly BinaryExpression IgnoreKeysIsNull = Expression.Equal(IgnoreKeys, Expression.Constant(null));
|
||||
//- handler.option.ignoreKeys != null
|
||||
internal static readonly BinaryExpression IgnoreKeysIsNotNull = Expression.NotEqual(IgnoreKeys, Expression.Constant(null));
|
||||
//- handler.option.ignoreKeys.count() == 0
|
||||
internal static readonly BinaryExpression IgnoreKeysCountIsZero = Expression.Equal(Expression.MakeMemberAccess(IgnoreKeys, typeof(List<string>).GetProperty("Count")), Expression.Constant(0));
|
||||
|
||||
//- handler.option.jsonCharacterRead(Enum)
|
||||
internal static readonly MemberExpression JsonCharacterRead = Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._JsonCharacterRead);
|
||||
|
||||
//- handler.option.isEnumNum(bool)
|
||||
internal static readonly MemberExpression IsEnumNum = Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._IsEnumNum);
|
||||
|
||||
//- handler.option.isIgnoreValueNull(bool)
|
||||
internal static readonly UnaryExpression IgnoreValueNullIsTrue = Expression.IsTrue(Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._IsIgnoreValueNull));
|
||||
|
||||
//- handler.option.referenceLoopHandling(Enum)
|
||||
internal static readonly MemberExpression ReferenceLoopHandling = Expression.MakeMemberAccess(JOptionArg, JsonSerializerOption._ReferenceLoopHandling);
|
||||
//- handler.option.referenceLoopHandling != Enum.None
|
||||
internal static readonly BinaryExpression IsReferenceLoopHandlingNotEqualsNone = Expression.NotEqual(ReferenceLoopHandling, Expression.Constant(JsonReferenceHandlingEnum.None));
|
||||
//- handler.option.referenceLoopHandling == Enum.Remove
|
||||
internal static readonly BinaryExpression IsReferenceLoopHandlingEqualsRemove = Expression.Equal(ReferenceLoopHandling, Expression.Constant(JsonReferenceHandlingEnum.Remove));
|
||||
//- handler.option.referenceLoopHandling == Enum.Empty
|
||||
internal static readonly BinaryExpression IsReferenceLoopHandlingEqualsEmpty = Expression.Equal(ReferenceLoopHandling, Expression.Constant(JsonReferenceHandlingEnum.Empty));
|
||||
//- handler.option.referenceLoopHandling == Enum.Null
|
||||
internal static readonly BinaryExpression IsReferenceLoopHandlingEqualsNull = Expression.Equal(ReferenceLoopHandling, Expression.Constant(JsonReferenceHandlingEnum.Null));
|
||||
|
||||
//- handler.commaIndexLists
|
||||
internal static readonly MemberExpression ListCommaIndexs = Expression.MakeMemberAccess(HandlerArg, JsonSerializerHandler._CommaIndexLists);
|
||||
|
||||
|
||||
|
||||
|
||||
//if ( referenceLoopHandling == Enum.Remove ) ==> DeleteComma()
|
||||
internal static readonly ConditionalExpression IsReferenceLoopHandlingIsRemoveDeleteComma = Expression.IfThen(
|
||||
IsReferenceLoopHandlingEqualsRemove,
|
||||
DeleteComma()
|
||||
);
|
||||
|
||||
//if ( referenceLoopHandling == Enum.None ) ==> serializeStacks.Pop()
|
||||
internal static readonly ConditionalExpression IsReferenceLoopHandlingIsNoneSerializeStacksArgPop = Expression.IfThen(
|
||||
IsReferenceLoopHandlingNotEqualsNone,
|
||||
Expression.Call(SerializeStacksArg, typeof(Stack<object>).GetMethod("Pop"))
|
||||
);
|
||||
|
||||
//call
|
||||
internal static readonly MethodCallExpression WriteLeft = Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Constant("{"));
|
||||
internal static readonly MethodCallExpression WriteRight = Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Constant("}"));
|
||||
internal static readonly MethodCallExpression WriteComma = Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Constant(","));
|
||||
|
||||
internal enum RefernceByEmptyType
|
||||
{
|
||||
Array,
|
||||
Dictionary,
|
||||
CustomType
|
||||
}
|
||||
internal static Expression WriteKeyValuePairKey(Type keyType, Expression key)
|
||||
{
|
||||
List<Expression> calls = new List<Expression>();
|
||||
if (keyType == typeof(string) || keyType == typeof(Guid) || keyType == typeof(DateTime))
|
||||
{
|
||||
calls.Add(GetMethodCall(keyType, key));
|
||||
calls.Add(Append(":"));
|
||||
}
|
||||
else if (keyType.IsPrimitive)
|
||||
{
|
||||
calls.Add(Append("\""));
|
||||
calls.Add(Expression.Call(SerializerBootTable.Table.DefaultSameTypes[keyType], key, HandlerArg));
|
||||
calls.Add(Append("\":"));
|
||||
}
|
||||
else if (keyType.IsEnum)//The default is tostring
|
||||
{
|
||||
calls.Add(Append("\""));
|
||||
calls.Add(Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Call(key, typeof(Enum).GetMethod("ToString", new Type[0]))));
|
||||
calls.Add(Append("\":"));
|
||||
}
|
||||
|
||||
return Expression.Block(calls);
|
||||
}
|
||||
internal static Expression IsIgnoreSelfRefernce(ParameterExpression instanceArg, RefernceByEmptyType emptyType)
|
||||
{
|
||||
MethodCallExpression contains = Expression.Call(SerializeStacksArg, typeof(Stack<object>).GetMethod("Contains", new[] { typeof(object) }), Expression.Convert(instanceArg, typeof(object)));
|
||||
|
||||
MethodCallExpression call;
|
||||
if (emptyType == RefernceByEmptyType.Array)
|
||||
call = RemoveArrayItem();
|
||||
else if (emptyType == RefernceByEmptyType.Dictionary)
|
||||
call = RemoveDictionaryKey();
|
||||
else
|
||||
call = RemoveKeyAndAddIndex();
|
||||
|
||||
BlockExpression containsBody = Expression.Block(
|
||||
Expression.IfThenElse(
|
||||
IsReferenceLoopHandlingEqualsNull, Append("null"),
|
||||
Expression.IfThenElse(
|
||||
IsReferenceLoopHandlingEqualsEmpty, Append(emptyType == RefernceByEmptyType.Array ? "[]" : "{}"),
|
||||
call)
|
||||
),
|
||||
Expression.Return(ReturnLable)
|
||||
);
|
||||
|
||||
ConditionalExpression ifContainsBlock = Expression.IfThen(contains, containsBody);
|
||||
|
||||
// handler.serializeStacks.Push(value);
|
||||
MethodCallExpression push = Expression.Call(SerializeStacksArg, typeof(Stack<object>).GetMethod("Push", new[] { typeof(object) }), Expression.Convert(instanceArg, typeof(object)));
|
||||
|
||||
ConditionalExpression isIgnoreSelfRefernce = Expression.IfThen(IsReferenceLoopHandlingNotEqualsNone,
|
||||
Expression.Block(
|
||||
ifContainsBlock, push
|
||||
));
|
||||
|
||||
return isIgnoreSelfRefernce;
|
||||
}
|
||||
internal static MethodCallExpression GetMethodCall(Type type, Expression member)
|
||||
{
|
||||
return Expression.Call(typeof(FormattingProvider<>).MakeGenericType(type).GetMethod("Convert", BindingFlags.NonPublic | BindingFlags.Static), member, HandlerArg);
|
||||
}
|
||||
|
||||
internal static MethodCallExpression AppendKey(string str)
|
||||
{
|
||||
return Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Constant("\"" + str + "\":"));
|
||||
}
|
||||
internal static MethodCallExpression Append(string str)
|
||||
{
|
||||
return Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Constant(str));
|
||||
}
|
||||
internal static MethodCallExpression Append(Expression strExpression)
|
||||
{
|
||||
return Expression.Call(WriteString, JsonSerializerHandler._WriteStringInvoke, strExpression);
|
||||
}
|
||||
internal static MethodCallExpression RemoveDictionaryKey()
|
||||
{
|
||||
return Expression.Call(RemoveWriterHelper._RemoveDictionaryKey, HandlerArg);
|
||||
}
|
||||
internal static MethodCallExpression RemoveArrayItem()
|
||||
{
|
||||
return Expression.Call(RemoveWriterHelper._RemoveArrayItem, HandlerArg);
|
||||
}
|
||||
internal static MethodCallExpression RemoveKeyAndAddIndex()
|
||||
{
|
||||
return Expression.Call(RemoveWriterHelper._RemoveKeyAndAddIndex, HandlerArg, ListCommaIndexs);
|
||||
}
|
||||
internal static MethodCallExpression RemoveLastComma()
|
||||
{
|
||||
return Expression.Call(RemoveWriterHelper._RemoveLastComma, HandlerArg);
|
||||
}
|
||||
internal static MethodCallExpression DeleteComma()
|
||||
{
|
||||
return Expression.Call(RemoveWriterHelper._DeleteComma, HandlerArg, ListCommaIndexs);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.IDictionaryGeneric)]
|
||||
internal class IDictionaryGenericBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
Type[] genericArguments = type.GetGenericArguments();
|
||||
if (genericArguments.Length == 0)
|
||||
{
|
||||
Type idic = type.GetInterface("IDictionary`2");
|
||||
genericArguments = idic.GetGenericArguments();
|
||||
}
|
||||
|
||||
Type keyType = genericArguments[0];
|
||||
Type valueType = genericArguments[1];
|
||||
|
||||
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
if (!type.IsValueType)
|
||||
{
|
||||
ConditionalExpression ifNullAppendNull = Expression.IfThen(
|
||||
Expression.Equal(instanceArg, Expression.Constant(null, type)),
|
||||
Expression.Block(ExpressionMembers.Append("null"),
|
||||
Expression.Return(ExpressionMembers.ReturnLable)
|
||||
));
|
||||
|
||||
methodCall.Add(ifNullAppendNull);
|
||||
}
|
||||
methodCall.Add(ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.Dictionary));
|
||||
|
||||
methodCall.Add(ExpressionMembers.Append("{"));
|
||||
|
||||
ParameterExpression isFirst = Expression.Variable(typeof(bool), "isFirst");
|
||||
|
||||
Expression foreachs = ExpressionHelper.ForEach(instanceArg, Expression.Parameter(typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType), "loopVar"),
|
||||
item =>
|
||||
{
|
||||
List<Expression> calls = new List<Expression>
|
||||
{
|
||||
Expression.IfThenElse(
|
||||
Expression.IsFalse(isFirst),
|
||||
Expression.Assign(isFirst, Expression.Constant(true)),
|
||||
ExpressionMembers.Append(",")
|
||||
)
|
||||
};
|
||||
|
||||
MemberExpression key = Expression.MakeMemberAccess(item, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType).GetProperty("Key"));
|
||||
MemberExpression value = Expression.MakeMemberAccess(item, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType).GetProperty("Value"));
|
||||
|
||||
calls.Add(ExpressionMembers.WriteKeyValuePairKey(keyType, key));
|
||||
calls.Add(ExpressionMembers.GetMethodCall(valueType, value));
|
||||
|
||||
return Expression.Block(new[] { isFirst }, calls);
|
||||
}
|
||||
);
|
||||
|
||||
methodCall.Add(foreachs);
|
||||
|
||||
|
||||
methodCall.Add(ExpressionMembers.Append("}"));
|
||||
methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop);
|
||||
methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable));
|
||||
return Expression.Block(methodCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.IEnumerableGeneric)]
|
||||
internal class IEnumerableGenericBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
Type arrayItemType = type.GetElementType();
|
||||
if (arrayItemType == null)
|
||||
{
|
||||
Type[] genericArguments = type.GetGenericArguments();
|
||||
if (genericArguments.Length == 0)
|
||||
arrayItemType = type.GetInterface("IEnumerable`1").GetGenericArguments()[0];
|
||||
else
|
||||
arrayItemType = genericArguments[0];
|
||||
}
|
||||
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
|
||||
if (!type.IsValueType)
|
||||
{
|
||||
ConditionalExpression ifNullAppendNull = Expression.IfThen(
|
||||
Expression.Equal(instanceArg, Expression.Constant(null,type)),
|
||||
Expression.Block(ExpressionMembers.Append("null"),
|
||||
Expression.Return(ExpressionMembers.ReturnLable)
|
||||
));
|
||||
|
||||
methodCall.Add(ifNullAppendNull);
|
||||
}
|
||||
methodCall.Add(ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.Array));
|
||||
|
||||
methodCall.Add(ExpressionMembers.Append("["));
|
||||
|
||||
ParameterExpression isFirst = Expression.Variable(typeof(bool), "isFirst");
|
||||
|
||||
Expression foreachs = ExpressionHelper.ForEach(instanceArg, Expression.Parameter(arrayItemType, "loopVar"),
|
||||
item => Expression.Block(new[] { isFirst },
|
||||
Expression.IfThenElse(
|
||||
Expression.IsFalse(isFirst),
|
||||
Expression.Assign(isFirst, Expression.Constant(true)),
|
||||
ExpressionMembers.Append(",")
|
||||
),
|
||||
ExpressionMembers.GetMethodCall(arrayItemType, item)
|
||||
));
|
||||
|
||||
methodCall.Add(foreachs);
|
||||
methodCall.Add(ExpressionMembers.Append("]"));
|
||||
methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop);
|
||||
methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable));
|
||||
return Expression.Block(methodCall);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.IListGeneric)]
|
||||
internal class IListGenericBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
Type arrayItemType = type.GetElementType();
|
||||
if (arrayItemType == null)
|
||||
{
|
||||
Type[] genericArguments = type.GetGenericArguments();
|
||||
if (genericArguments.Length == 0)
|
||||
arrayItemType = type.GetInterface("IList`1").GetGenericArguments()[0];
|
||||
else
|
||||
arrayItemType = genericArguments[0];
|
||||
}
|
||||
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
|
||||
if (!type.IsValueType)
|
||||
{
|
||||
ConditionalExpression ifNullAppendNull = Expression.IfThen(
|
||||
Expression.Equal(instanceArg, Expression.Constant(null, type)),
|
||||
Expression.Block(ExpressionMembers.Append("null"),
|
||||
Expression.Return(ExpressionMembers.ReturnLable)
|
||||
));
|
||||
|
||||
methodCall.Add(ifNullAppendNull);
|
||||
}
|
||||
methodCall.Add(ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.Array));
|
||||
|
||||
methodCall.Add(ExpressionMembers.Append("["));
|
||||
|
||||
ParameterExpression isFirst = Expression.Variable(typeof(bool), "isFirst");
|
||||
|
||||
Type iListType = typeof(IList<>).MakeGenericType(arrayItemType);
|
||||
ParameterExpression iList = Expression.Variable(iListType);
|
||||
|
||||
methodCall.Add(Expression.Assign(iList, Expression.Convert(instanceArg, iListType)));
|
||||
|
||||
ParameterExpression forVariable = Expression.Variable(typeof(int));
|
||||
//Expression forExpression = ExpressionHelper.For(forVariable, Expression.LessThan(forVariable, Expression.MakeMemberAccess(instanceArg, type.IsArray ? type.GetProperty("Length") : type.GetProperty("Count"))), Expression.PostIncrementAssign(forVariable), Expression.Block(new[] { isFirst },
|
||||
// Expression.IfThenElse(
|
||||
// Expression.IsFalse(isFirst),
|
||||
// Expression.Assign(isFirst, Expression.Constant(true)),
|
||||
// ExpressionMembers.Append(",")
|
||||
// ),
|
||||
// ExpressionMembers.GetMethodCall(arrayItemType, type.IsArray ? Expression.ArrayAccess(instanceArg, forVariable) : Expression.MakeIndex(instanceArg, type.GetProperty("Item"), new[] { forVariable }))
|
||||
// ));
|
||||
|
||||
Expression forExpression = ExpressionHelper.For(forVariable, Expression.LessThan(forVariable, Expression.MakeMemberAccess(instanceArg, type.IsArray ? type.GetProperty("Length") : type.GetProperty("Count"))), Expression.PostIncrementAssign(forVariable), Expression.Block(new[] { isFirst },
|
||||
Expression.IfThenElse(
|
||||
Expression.IsFalse(isFirst),
|
||||
Expression.Assign(isFirst, Expression.Constant(true)),
|
||||
ExpressionMembers.Append(",")
|
||||
),
|
||||
ExpressionMembers.GetMethodCall(arrayItemType, Expression.MakeIndex(iList, iListType.GetProperty("Item"), new[] { forVariable }))
|
||||
));
|
||||
|
||||
|
||||
methodCall.Add(forExpression);
|
||||
methodCall.Add(ExpressionMembers.Append("]"));
|
||||
methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop);
|
||||
methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable));
|
||||
return Expression.Block(new[] { iList }, methodCall);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.KeyValueObject)]
|
||||
internal class KeyValueObjectBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
List<Expression> methodCall = new List<Expression>();
|
||||
|
||||
if (!type.IsValueType)
|
||||
{
|
||||
ConditionalExpression ifParaIsNullAppendNull = Expression.IfThen(Expression.Equal(instanceArg, Expression.Constant(null, type)),
|
||||
Expression.Block(
|
||||
ExpressionMembers.Append("null"),
|
||||
Expression.Return(ExpressionMembers.ReturnLable)
|
||||
));
|
||||
methodCall.Add(ifParaIsNullAppendNull);//add
|
||||
|
||||
Expression isIgnoreSelfRefernceModule = ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.CustomType);
|
||||
|
||||
methodCall.Add(isIgnoreSelfRefernceModule);//add
|
||||
}
|
||||
|
||||
methodCall.Add(ExpressionMembers.WriteLeft);
|
||||
|
||||
var elements = type.GetModelMembers(ReadMemberStateEnum.CanRead);
|
||||
bool hasIgnoreDefaultValueAttribute = false;
|
||||
for (int i = 0; i < elements.Count; i++)
|
||||
{
|
||||
var item = elements[i];
|
||||
|
||||
//valueformat
|
||||
ValueFormatAttribute valueformat = item.Value.MemberInfo.GetCustomAttribute<ValueFormatAttribute>() ??
|
||||
item.Value.MemberInfo.DeclaringType.GetCustomAttribute<ValueFormatAttribute>();
|
||||
|
||||
//IgnoreDefaultValue
|
||||
IgnoreDefaultValueAttribute ignoreDefaultValue = item.Value.MemberInfo.GetCustomAttribute<IgnoreDefaultValueAttribute>() ??
|
||||
item.Value.MemberInfo.DeclaringType.GetCustomAttribute<IgnoreDefaultValueAttribute>();
|
||||
|
||||
if (ignoreDefaultValue != null)
|
||||
hasIgnoreDefaultValueAttribute = true;
|
||||
|
||||
//if (!(m.Name == null && handler.option.IsIgnoreNull))//0
|
||||
MemberExpression mName = Expression.MakeMemberAccess(instanceArg, item.Value.MemberInfo);
|
||||
|
||||
// if (option1.IsFirstLower)
|
||||
string lowerName = item.Key.Substring(0, 1).ToLower() + item.Key.Substring(1);
|
||||
string upperName = item.Key.Substring(0, 1).ToUpper() + item.Key.Substring(1);
|
||||
|
||||
/*
|
||||
ignoreKeys == null || ignoreKeys.count() == 0 || ignoreKeys.Contains(name)==false
|
||||
*/
|
||||
BinaryExpression ignoreKeysJudge = Expression.OrElse(
|
||||
ExpressionMembers.IgnoreKeysIsNull,
|
||||
Expression.OrElse(
|
||||
ExpressionMembers.IgnoreKeysCountIsZero,
|
||||
Expression.Equal(
|
||||
Expression.Call(ExpressionMembers.IgnoreKeys, typeof(List<string>).GetMethod("Contains"), Expression.Constant(item.Key))
|
||||
, Expression.Constant(false))
|
||||
));
|
||||
|
||||
/*
|
||||
(ignoreKeys == null || ignoreKeys.count() == 0 || ignoreKeys.Contains(name)==false) && ( m!=default(m) )
|
||||
*/
|
||||
if (ignoreDefaultValue != null)
|
||||
ignoreKeysJudge = Expression.AndAlso(ignoreKeysJudge, Expression.NotEqual(mName, Expression.Constant(item.Value.Type.GetDefaultValue(), item.Value.Type)));
|
||||
|
||||
/*
|
||||
if(option.keyformat!=null)
|
||||
$handler.WriteString("\"");
|
||||
$handler.WriteString(option.keyformat.invoke(string));
|
||||
append("\":")
|
||||
else
|
||||
{
|
||||
switch(JsonCharacterRead)
|
||||
{
|
||||
case None:
|
||||
AppendKey()
|
||||
case InitialUpper:
|
||||
..
|
||||
case InitialLower:
|
||||
..
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
*/
|
||||
Expression writeKey = Expression.IfThenElse(Expression.NotEqual(ExpressionMembers.GlobalKeyFormat, Expression.Constant(null, JsonSerializerOption._GlobalKeyFormat.FieldType)),
|
||||
Expression.Block(
|
||||
ExpressionMembers.Append("\""),
|
||||
Expression.Call(ExpressionMembers.WriteString, JsonSerializerHandler._WriteStringInvoke, Expression.Call(ExpressionMembers.GlobalKeyFormat, JsonSerializerOption._GlobalKeyFormatInvoke, Expression.Constant(item.Key), Expression.Constant(type, typeof(Type)), ExpressionMembers.HandlerArg)
|
||||
),
|
||||
ExpressionMembers.Append("\":")
|
||||
),
|
||||
Expression.Switch(typeof(void), ExpressionMembers.JsonCharacterRead, null, null,
|
||||
Expression.SwitchCase(ExpressionMembers.AppendKey(item.Key), Expression.Constant(JsonCharacterReadStateEnum.None, typeof(JsonCharacterReadStateEnum))),
|
||||
Expression.SwitchCase(ExpressionMembers.AppendKey(upperName), Expression.Constant(JsonCharacterReadStateEnum.InitialUpper, typeof(JsonCharacterReadStateEnum))),
|
||||
Expression.SwitchCase(ExpressionMembers.AppendKey(lowerName), Expression.Constant(JsonCharacterReadStateEnum.InitialLower, typeof(JsonCharacterReadStateEnum)))
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
string afterValueFormat= valueformat.WriteValueFormat( model.Name,hander out isValueFormat)
|
||||
if(isValueFormat)
|
||||
sb.append(afterValueFormat)
|
||||
else
|
||||
WriteValue(model.Name,handler)
|
||||
*/
|
||||
Expression writeValue;
|
||||
if (valueformat != null)
|
||||
{
|
||||
writeValue = Expression.Block(
|
||||
Expression.NotEqual(ExpressionMembers.GlobalValueFormat, Expression.Constant(null, JsonSerializerOption._GlobalValueFormat.FieldType)),
|
||||
Expression.Assign(ExpressionMembers.AfterValueFormat, Expression.Call(Expression.Constant(valueformat, typeof(ValueFormatAttribute)), ValueFormatAttribute._WriteValueFormat, Expression.Convert(mName, typeof(object)), Expression.Constant(item.Value.Type, typeof(Type)), ExpressionMembers.HandlerArg, ExpressionMembers.IsValueFormat)),
|
||||
Expression.IfThenElse(Expression.IsTrue(ExpressionMembers.IsValueFormat), ExpressionMembers.Append(ExpressionMembers.AfterValueFormat), ExpressionMembers.GetMethodCall(item.Value.Type, mName))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
if( option.GlobalValueFormat!=null){
|
||||
string afterValueFormat= option.GlobalValueFormat.Invoke( model.Name,hander out isValueFormat)
|
||||
if(isValueFormat)
|
||||
sb.append(afterValueFormat)
|
||||
else
|
||||
WriteValue(model.Name,handler)
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteValue(model.Name,handler)
|
||||
}
|
||||
*/
|
||||
writeValue = Expression.IfThenElse(
|
||||
Expression.NotEqual(ExpressionMembers.GlobalValueFormat, Expression.Constant(null, JsonSerializerOption._GlobalValueFormat.FieldType)),
|
||||
Expression.Block(
|
||||
Expression.Assign(ExpressionMembers.AfterValueFormat, Expression.Call(ExpressionMembers.GlobalValueFormat, JsonSerializerOption._GlobalValueFormatInvoke, Expression.Convert(mName, typeof(object)), Expression.Constant(item.Value.Type, typeof(Type)), ExpressionMembers.HandlerArg, ExpressionMembers.IsValueFormat)),
|
||||
Expression.IfThenElse(Expression.IsTrue(ExpressionMembers.IsValueFormat), ExpressionMembers.Append(ExpressionMembers.AfterValueFormat), ExpressionMembers.GetMethodCall(item.Value.Type, mName))
|
||||
),
|
||||
ExpressionMembers.GetMethodCall(item.Value.Type, mName)
|
||||
);
|
||||
}
|
||||
|
||||
Expression trunk = Expression.Block(writeKey, writeValue);
|
||||
|
||||
// json.Append(",");
|
||||
if (i != elements.Count - 1)
|
||||
trunk = Expression.Block(trunk, ExpressionMembers.WriteComma);
|
||||
|
||||
if (!item.Value.Type.IsValueType || (item.Value.Type.IsGenericType && item.Value.Type.GetGenericTypeDefinition() == typeof(Nullable<>)))
|
||||
{
|
||||
BinaryExpression mNameIsNull = Expression.Equal(mName, Expression.Constant(null));
|
||||
//if(!null&&isgorenull)
|
||||
trunk = Expression.IfThen(Expression.IsFalse(Expression.And(mNameIsNull, ExpressionMembers.IgnoreValueNullIsTrue)), trunk);
|
||||
}
|
||||
//
|
||||
trunk = Expression.IfThen(ignoreKeysJudge, trunk);//忽略key
|
||||
|
||||
methodCall.Add(trunk);
|
||||
|
||||
}
|
||||
|
||||
// //if ( ignoreValueNull == true || ignoreKeys!=null ) ==> RemoveLastComma()
|
||||
var IgnoreValueNullIsTrueOrIgnoreKeysNotEqureNullRemoveLastComma = Expression.IfThen(
|
||||
Expression.OrElse(ExpressionMembers.IgnoreValueNullIsTrue, ExpressionMembers.IgnoreKeysIsNotNull),
|
||||
ExpressionMembers.RemoveLastComma()
|
||||
);
|
||||
methodCall.Add(hasIgnoreDefaultValueAttribute? (Expression)ExpressionMembers.RemoveLastComma():IgnoreValueNullIsTrueOrIgnoreKeysNotEqureNullRemoveLastComma);
|
||||
methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsRemoveDeleteComma);
|
||||
methodCall.Add(ExpressionMembers.WriteRight);
|
||||
methodCall.Add(ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop);
|
||||
methodCall.Add(Expression.Label(ExpressionMembers.ReturnLable));
|
||||
|
||||
return Expression.Block(new[] { ExpressionMembers.AfterValueFormat, ExpressionMembers.IsValueFormat }, methodCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.KeyValuePair)]
|
||||
internal class KeyValuePairBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
Type keyType = type.GetGenericArguments()[0];
|
||||
Type valueType = type.GetGenericArguments()[1];
|
||||
|
||||
Expression[] methodCall = new Expression[7];
|
||||
methodCall[0] = ExpressionMembers.IsIgnoreSelfRefernce(instanceArg, ExpressionMembers.RefernceByEmptyType.Dictionary);
|
||||
methodCall[1] = ExpressionMembers.Append("{");
|
||||
|
||||
MemberExpression key = Expression.MakeMemberAccess(instanceArg, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType).GetProperty("Key"));
|
||||
MemberExpression value = Expression.MakeMemberAccess(instanceArg, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType).GetProperty("Value"));
|
||||
|
||||
methodCall[2] = ExpressionMembers.WriteKeyValuePairKey(keyType, key);
|
||||
methodCall[3] = ExpressionMembers.GetMethodCall(valueType, value);
|
||||
methodCall[4] = ExpressionMembers.Append("}");
|
||||
methodCall[5] = ExpressionMembers.IsReferenceLoopHandlingIsNoneSerializeStacksArgPop;
|
||||
methodCall[6] = Expression.Label(ExpressionMembers.ReturnLable);
|
||||
|
||||
return Expression.Block(methodCall);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.Lazy)]
|
||||
internal class LazyBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
Expression orginal = ExpressionMembers.GetMethodCall(type.GetGenericArguments()[0], Expression.MakeMemberAccess(instanceArg, type.GetProperty("Value")));
|
||||
|
||||
return Expression.IfThenElse(
|
||||
Expression.Equal(instanceArg, Expression.Constant(null,type)),
|
||||
ExpressionMembers.Append("null")
|
||||
,
|
||||
//para.value
|
||||
orginal
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.Nullable)]
|
||||
internal class NullableBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
Expression orginal = ExpressionMembers.GetMethodCall(type.GetGenericArguments()[0], Expression.MakeMemberAccess(instanceArg, type.GetProperty("Value")));
|
||||
|
||||
return Expression.IfThenElse(
|
||||
Expression.Equal(instanceArg, Expression.Constant(null,type)),
|
||||
ExpressionMembers.Append("null")
|
||||
,
|
||||
//para.value
|
||||
orginal
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
[ExpressionBuildType(SerializerBuildTypeEnum.WrongGenericKey)]
|
||||
internal class WrongGenericKeyBuild : ExpressionJsonFormatter
|
||||
{
|
||||
internal static Expression Build(Type type, ParameterExpression instanceArg)
|
||||
{
|
||||
List<Expression> expressions = new List<Expression>();
|
||||
if (!type.IsValueType)
|
||||
expressions.Add(Expression.IfThen(
|
||||
Expression.Equal(instanceArg, Expression.Constant(null,type)),
|
||||
Expression.Block(ExpressionMembers.Append("null"),
|
||||
Expression.Return(ExpressionMembers.ReturnLable)
|
||||
)));
|
||||
expressions.Add(ExpressionMembers.Append("{}"));
|
||||
expressions.Add(Expression.Label(ExpressionMembers.ReturnLable));
|
||||
return Expression.Block(expressions);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class ExpressionJsonFormatter :JsonFormatterBase
|
||||
{
|
||||
}
|
||||
}
|
@ -1,462 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class FormatterFind<T>
|
||||
{
|
||||
internal static Action<T, JsonSerializerHandler> Find()
|
||||
{
|
||||
Type t = typeof(T);
|
||||
return FindTypeIsDefaultImplemented(t) ?? FindTypeIsMeetDefaultCondition(t) ?? FindTypeIsDefaultImplementedBaseType(t) ?? FindTypeIsDefaultImplementedInterface(t) ?? DefaultResolve(t);
|
||||
}
|
||||
|
||||
private static Action<T, JsonSerializerHandler> FindTypeIsDefaultImplemented(Type t)
|
||||
{
|
||||
if (SerializerBootTable.Table.DefaultSameTypes.TryGetValue(t, out MethodInfo value))
|
||||
return GenerateLambdaCall(value);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Action<T, JsonSerializerHandler> FindTypeIsMeetDefaultCondition(Type t)
|
||||
{
|
||||
return IsLoadDynamic(t) ?? IsArray(t) ?? IsEnum(t);
|
||||
}
|
||||
|
||||
private static Action<T, JsonSerializerHandler> FindTypeIsDefaultImplementedBaseType(Type t)
|
||||
{
|
||||
var baseTypes = t.GetTypeAndBaseTypes();
|
||||
|
||||
//Avoid
|
||||
if (SerializerBootTable.Table.DefaultAvoidTypes.Intersect(baseTypes).Any())
|
||||
return (a, b) => SpecialConditions.AvoidTypes(a, b);
|
||||
|
||||
//Default
|
||||
foreach (var implementedType in SerializerBootTable.Table.DefaultImplementedBaseType)
|
||||
{
|
||||
foreach (var baseType in baseTypes)
|
||||
{
|
||||
if (baseType == implementedType.Key)
|
||||
{
|
||||
return GenerateLambdaCall(implementedType.Value.MethodInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Action<T, JsonSerializerHandler> FindTypeIsDefaultImplementedInterface(Type t)
|
||||
{
|
||||
var intserfaces = t.GetInterfaces().ToList();
|
||||
if (t.IsInterface)
|
||||
intserfaces.Add(t);
|
||||
|
||||
foreach (var item in SerializerBootTable.Table.DefaultImplementedInterfaces)
|
||||
{
|
||||
foreach (var objInterface in intserfaces)
|
||||
{
|
||||
if (objInterface == item.Key)
|
||||
{
|
||||
return GenerateLambdaCall(item.Value.MethodInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Action<T, JsonSerializerHandler> DefaultResolve(Type t)
|
||||
{
|
||||
Func<Action<T, JsonSerializerHandler>> func = TypeIsDictionary(t) ?? TypeIsCollection(t) ?? TypeIsSpecial(t);
|
||||
if (func != null)
|
||||
return func();
|
||||
|
||||
return BuildFactory.Create<T>(SerializerBuildTypeEnum.KeyValueObject);
|
||||
}
|
||||
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsDictionary(Type t)
|
||||
{
|
||||
return TypeIsDictionaryInterface(t) ?? TypeIsDictionaryType(t);
|
||||
}
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsDictionaryInterface(Type t)
|
||||
{
|
||||
if (t == typeof(IDictionary))
|
||||
return () => (obj, handler) => SpecialConditions.WriteDictionary((IDictionary)obj, handler);
|
||||
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
Type[] args = t.GetGenericArguments();
|
||||
if (args.Length != 2)
|
||||
return null;
|
||||
var genericTypeDefinition = t.GetGenericTypeDefinition();
|
||||
var keyType = args[0];
|
||||
var valueType = args[1];
|
||||
|
||||
if (genericTypeDefinition == typeof(IDictionary<,>)
|
||||
#if !Net4
|
||||
|| genericTypeDefinition == typeof(IReadOnlyDictionary<,>)
|
||||
#endif
|
||||
)
|
||||
return () => IsWrongKeyType(keyType) ?? BuildFactory.Create<T>(SerializerBuildTypeEnum.IDictionaryGeneric);
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsDictionaryType(Type t)
|
||||
{
|
||||
if (t.IsInterface)
|
||||
return null;
|
||||
|
||||
var intserfaces = t.GetInterfaces();
|
||||
|
||||
bool hasIDictionaryGeneric = false;
|
||||
bool hasIDictionary = false;
|
||||
Type iDictionaryGenericType = null;
|
||||
|
||||
Type keyType = null;
|
||||
Type valueType = null;
|
||||
foreach (var item in intserfaces)
|
||||
{
|
||||
if (item.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = item.GetGenericTypeDefinition();
|
||||
if (genericTypeDefinition == typeof(IDictionary<,>))
|
||||
{
|
||||
iDictionaryGenericType = item;
|
||||
hasIDictionaryGeneric = true;
|
||||
keyType = item.GetGenericArguments()[0];
|
||||
valueType = item.GetGenericArguments()[1];
|
||||
}
|
||||
}
|
||||
if (item == typeof(IDictionary))
|
||||
hasIDictionary = true;
|
||||
}
|
||||
|
||||
if (hasIDictionaryGeneric)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(iDictionaryGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (TypeIsDictionary(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => IsWrongKeyType(keyType) ?? BuildFactory.Create<T>(SerializerBuildTypeEnum.IDictionaryGeneric);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => IsWrongKeyType(keyType) ?? BuildFactory.Create<T>(SerializerBuildTypeEnum.IDictionaryGeneric);
|
||||
}
|
||||
else
|
||||
return () => IsWrongKeyType(keyType) ?? BuildFactory.Create<T>(SerializerBuildTypeEnum.IDictionaryGeneric);
|
||||
}
|
||||
if (hasIDictionary)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(typeof(IDictionary));
|
||||
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (TypeIsDictionary(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => (obj, handler) => SpecialConditions.WriteDictionary((IDictionary)obj, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => (obj, handler) => SpecialConditions.WriteDictionary((IDictionary)obj, handler);
|
||||
}
|
||||
else
|
||||
return () => (obj, handler) => SpecialConditions.WriteDictionary((IDictionary)obj, handler);
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsCollection(Type t)
|
||||
{
|
||||
return TypeIsCollectionInterface(t) ?? TypeIsCollectionType(t);
|
||||
}
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsCollectionInterface(Type t)
|
||||
{
|
||||
if (t == typeof(IEnumerable) || t == typeof(ICollection) || t == typeof(IList))
|
||||
return () => (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = t.GetGenericTypeDefinition();
|
||||
var arrayItemType = t.GetGenericArguments()[0];
|
||||
|
||||
if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(ISet<>)
|
||||
#if !Net4
|
||||
|| genericTypeDefinition == typeof(IReadOnlyList<>) || genericTypeDefinition == typeof(IReadOnlyCollection<>)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IEnumerableGeneric);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsCollectionType(Type t)
|
||||
{
|
||||
if (t.IsInterface)
|
||||
return null;
|
||||
|
||||
var intserfaces = t.GetInterfaces();
|
||||
|
||||
bool hasIEnumerableGeneric = false;
|
||||
bool hasICollectionGeneric = false;
|
||||
bool hasIListGeneric = false;
|
||||
bool hasICollection = false;
|
||||
bool hasIList = false;
|
||||
|
||||
Type arrayItemType = null;
|
||||
Type iCollectionGenericType = null;
|
||||
Type iEnumerableGenericType = null;
|
||||
Type iListGenericType = null;
|
||||
foreach (var item in intserfaces)
|
||||
{
|
||||
if (item.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = item.GetGenericTypeDefinition();
|
||||
|
||||
if (genericTypeDefinition == typeof(IEnumerable<>))
|
||||
{
|
||||
hasIEnumerableGeneric = true;
|
||||
arrayItemType = item.GetGenericArguments()[0];
|
||||
iEnumerableGenericType = item;
|
||||
}
|
||||
else if (genericTypeDefinition == typeof(ICollection<>))
|
||||
{
|
||||
hasICollectionGeneric = true;
|
||||
arrayItemType = item.GetGenericArguments()[0];
|
||||
iCollectionGenericType = item;
|
||||
}
|
||||
else if (genericTypeDefinition == typeof(IList<>))
|
||||
{
|
||||
hasIListGeneric = true;
|
||||
arrayItemType = item.GetGenericArguments()[0];
|
||||
iListGenericType = item;
|
||||
}
|
||||
}
|
||||
else if (item == typeof(ICollection))
|
||||
hasICollection = true;
|
||||
else if (item == typeof(IList))
|
||||
hasIList = true;
|
||||
}
|
||||
|
||||
if (hasIListGeneric)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(iListGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IListGeneric);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IListGeneric);
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IListGeneric);
|
||||
}
|
||||
|
||||
|
||||
if (hasICollectionGeneric)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(iCollectionGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IEnumerableGeneric);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IEnumerableGeneric);
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IEnumerableGeneric);
|
||||
}
|
||||
|
||||
if (hasIEnumerableGeneric && hasICollection)
|
||||
{
|
||||
var ctor = t.GetAppointTypeCtor(iEnumerableGenericType);
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IEnumerableGeneric);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.IEnumerableGeneric);
|
||||
}
|
||||
|
||||
if (hasIList)
|
||||
{
|
||||
var ctor = t.GetDefaultNoArgCtorOrAppointTypeCtor(typeof(IList));
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ctor.GetParameters().Length == 0)
|
||||
{
|
||||
return () => (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
}
|
||||
else
|
||||
return () => (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
}
|
||||
|
||||
if (hasICollection)
|
||||
{
|
||||
var ctor = t.GetAppointTypeCtor(typeof(ICollection));
|
||||
if (ctor == null)
|
||||
{
|
||||
foreach (var item in t.GetConstructors())
|
||||
{
|
||||
if (item.GetParameters().Length == 1)
|
||||
{
|
||||
var firstCtor = item.GetParameters()[0];
|
||||
if (firstCtor.ParameterType.IsArray || TypeIsCollection(firstCtor.ParameterType) != null)
|
||||
{
|
||||
return () => (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return () => (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Func<Action<T, JsonSerializerHandler>> TypeIsSpecial(Type t)
|
||||
{
|
||||
if (t.IsGenericType)
|
||||
{
|
||||
var genericTypeDefinition = t.GetGenericTypeDefinition();
|
||||
if (genericTypeDefinition == typeof(KeyValuePair<,>))
|
||||
{
|
||||
var keyType = t.GetGenericArguments()[0];
|
||||
return () => IsWrongKeyType(keyType) ?? BuildFactory.Create<T>(SerializerBuildTypeEnum.KeyValuePair);
|
||||
}
|
||||
if (genericTypeDefinition == typeof(Nullable<>))
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.Nullable);
|
||||
if (genericTypeDefinition == typeof(Lazy<>))
|
||||
return () => BuildFactory.Create<T>(SerializerBuildTypeEnum.Lazy);
|
||||
if (genericTypeDefinition == typeof(Lookup<,>))
|
||||
{
|
||||
|
||||
}
|
||||
if (genericTypeDefinition == typeof(ILookup<,>))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Action<T, JsonSerializerHandler> IsArray(Type t)
|
||||
{
|
||||
if (t.IsArray)
|
||||
{
|
||||
if (t.GetArrayRank() == 1)
|
||||
return BuildFactory.Create<T>(SerializerBuildTypeEnum.IListGeneric);
|
||||
else
|
||||
return (obj, handler) => SpecialConditions.WriteCollection((IEnumerable)obj, handler);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static Action<T, JsonSerializerHandler> IsLoadDynamic(Type t)
|
||||
{
|
||||
if (t.IsAnonymousType())
|
||||
return (a, b) => SpecialConditions.WriteDynamic(a, b);
|
||||
return null;
|
||||
}
|
||||
private static Action<T, JsonSerializerHandler> IsEnum(Type t)
|
||||
{
|
||||
if (t.IsEnum)
|
||||
return GenerateLambdaCallWithTypeConvert(SpecialConditions._WriteEnum, typeof(Enum));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static Action<T, JsonSerializerHandler> IsWrongKeyType(Type keyType)
|
||||
{
|
||||
if (keyType.IsWrongKey())
|
||||
return BuildFactory.Create<T>(SerializerBuildTypeEnum.WrongGenericKey);
|
||||
return null;
|
||||
}
|
||||
private static Action<T, JsonSerializerHandler> GenerateLambdaCall(MethodInfo method)
|
||||
{
|
||||
ParameterExpression objArg = Expression.Parameter(typeof(T), "instance");
|
||||
ParameterExpression handlerArg = Expression.Parameter(typeof(JsonSerializerHandler), "handler");
|
||||
var body = Expression.Call(method, objArg, handlerArg);
|
||||
return Expression.Lambda<Action<T, JsonSerializerHandler>>(body, objArg, handlerArg).Compile();
|
||||
}
|
||||
private static Action<T, JsonSerializerHandler> GenerateLambdaCallWithTypeConvert(MethodInfo method, Type t)
|
||||
{
|
||||
ParameterExpression objArg = Expression.Parameter(typeof(T), "instance");
|
||||
ParameterExpression handlerArg = Expression.Parameter(typeof(JsonSerializerHandler), "handler");
|
||||
var body = Expression.Call(method, Expression.Convert(objArg, t), handlerArg);
|
||||
return Expression.Lambda<Action<T, JsonSerializerHandler>>(body, objArg, handlerArg).Compile();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class FormattingProvider<T>
|
||||
{
|
||||
internal static Action<T, JsonSerializerHandler> Get = FormatterFind<T>.Find();
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static void Convert(T type, JsonSerializerHandler handler) => Get(type, handler);
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal class JsonFormatterBase
|
||||
{
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Datetime格式化枚举
|
||||
/// Datetime Format Enumeration
|
||||
/// </summary>
|
||||
public enum DatetimeFormatEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// DateTimes will be formatted as "yyyy-MM-ddThh:mm:ssZ" where
|
||||
/// yyyy is the year, MM is the month (starting at 01), dd is the day (starting at 01),
|
||||
/// hh is the hour (starting at 00, continuing to 24), mm is the minute (start at 00),
|
||||
/// and ss is the second (starting at 00).
|
||||
///
|
||||
/// Examples:
|
||||
/// 2011-07-14T19:43:37Z
|
||||
/// 2012-01-02T03:04:05Z
|
||||
/// </summary>
|
||||
ISO8601,
|
||||
/// <summary>
|
||||
/// DateTimes will be formatted as "ddd, dd MMM yyyy HH:mm:ss GMT" where
|
||||
/// ddd is the abbreviation of a day, dd is the day (starting at 01), MMM is the abbreviation of a month,
|
||||
/// yyyy is the year, HH is the hour (starting at 00, continuing to 24), mm is the minute (start at 00),
|
||||
/// and ss is the second (starting at 00), and GMT is a literal indicating the timezone (always GMT).
|
||||
///
|
||||
/// Examples:
|
||||
/// Thu, 10 Apr 2008 13:30:00 GMT
|
||||
/// Tue, 10 Mar 2015 00:14:34 GMT
|
||||
/// </summary>
|
||||
RFC1123,
|
||||
/// <summary>
|
||||
/// DateTimes will be formatted as "\/Date(##...##)\/" where ##...## is the
|
||||
/// number of milliseconds since the unix epoch (January 1st, 1970 UTC).
|
||||
/// See: https://msdn.microsoft.com/en-us/library/bb299886.aspx
|
||||
///
|
||||
/// Example:
|
||||
/// "\/Date(628318530718)\/"
|
||||
///
|
||||
/// TimeSpans will be formatted as "days.hours:minutes:seconds.fractionalSeconds"
|
||||
/// </summary>
|
||||
Microsoft
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 对Model进行Json序列化时全局值格式化器
|
||||
/// The global value formatter when the Model is Json serialized
|
||||
/// </summary>
|
||||
/// <param name="value">传进来的值,The value passed in</param>
|
||||
/// <param name="type">值的类型,The type of the value</param>
|
||||
/// <param name="handler">提供一些选项进行访问,Provides options for access</param>
|
||||
/// <param name="isValueFormat">决定最终是否进行值格式化,Determines whether the value is ultimately formatted</param>
|
||||
/// <returns></returns>
|
||||
public delegate string JsonSerializerGlobalValueFormatDelegate(object value,Type type, JsonSerializerHandler handler, out bool isValueFormat);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 发生循环引用时的处理方式枚举
|
||||
/// Enumeration of processing methods when circular references occur
|
||||
/// </summary>
|
||||
public enum JsonReferenceHandlingEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认,不处理
|
||||
/// Default
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// 将值处理为null
|
||||
/// Processing the value to null
|
||||
/// </summary>
|
||||
Null,
|
||||
/// <summary>
|
||||
/// 删除该值
|
||||
/// Delete this value
|
||||
/// </summary>
|
||||
Remove,
|
||||
/// <summary>
|
||||
/// 返回空(Keyvalue =>{},Array=>[])
|
||||
/// Return empty
|
||||
/// </summary>
|
||||
Empty
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供了用于在序列化中的一些配置
|
||||
/// Provides some configuration for serialization
|
||||
/// </summary>
|
||||
public class JsonSerializerHandler
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static readonly FieldInfo _Option = typeof(JsonSerializerHandler).GetField(nameof(Option));
|
||||
internal static readonly FieldInfo _SerializeStacks = typeof(JsonSerializerHandler).GetField(nameof(SerializeStacks), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
internal static readonly FieldInfo _CommaIndexLists = typeof(JsonSerializerHandler).GetField(nameof(CommaIndexLists), BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
internal static readonly MethodInfo _WriteStringInvoke = typeof(Action<string>).GetMethod("Invoke");
|
||||
internal static readonly FieldInfo _WriteString = typeof(JsonSerializerHandler).GetField(nameof(WriteString));
|
||||
#endregion
|
||||
|
||||
internal JsonSerializerHandler(StringBuilder stringBuilder) {
|
||||
this.stringBuilder = stringBuilder;
|
||||
WriteString = str => this.stringBuilder.Append(str);
|
||||
WriteChars = (chars, start, length) => this.stringBuilder.Append(chars, start, length);
|
||||
WriteChar = @char => this.stringBuilder.Append(@char);
|
||||
WriteLong = @long => this.stringBuilder.Append(@long);
|
||||
}
|
||||
|
||||
internal JsonSerializerHandler(StreamWriter streamWriter)
|
||||
{
|
||||
this.streamWriter = streamWriter;
|
||||
WriteString = str => this.streamWriter.Write(str);
|
||||
WriteChars = (chars, start, length) => this.streamWriter.Write(chars, start, length);
|
||||
WriteChar = @char => this.streamWriter.Write(@char);
|
||||
WriteLong = @long => this.streamWriter.Write(@long);
|
||||
}
|
||||
|
||||
internal StringBuilder stringBuilder;
|
||||
|
||||
internal StreamWriter streamWriter;
|
||||
|
||||
/// <summary>
|
||||
/// Write Long
|
||||
/// </summary>
|
||||
public Action<long> WriteLong;
|
||||
|
||||
/// <summary>
|
||||
/// Write Char
|
||||
/// </summary>
|
||||
public Action<char> WriteChar;
|
||||
|
||||
/// <summary>
|
||||
/// Write String
|
||||
/// </summary>
|
||||
public Action<string> WriteString;
|
||||
|
||||
/// <summary>
|
||||
/// Write Chars
|
||||
/// </summary>
|
||||
public Action<char[], int, int> WriteChars;
|
||||
|
||||
/// <summary>
|
||||
/// Json Serializer Option
|
||||
/// </summary>
|
||||
public JsonSerializerOption Option = null;
|
||||
|
||||
/// <summary>
|
||||
/// Used for infinite loop interreferences
|
||||
/// </summary>
|
||||
internal Stack<object> SerializeStacks = new Stack<object>();
|
||||
|
||||
/// <summary>
|
||||
/// Used for JsonRefernceHandlingEnum. Remove case, customtype comma to delete
|
||||
/// </summary>
|
||||
internal Stack<int> CommaIndexLists = new Stack<int>();
|
||||
|
||||
internal new string ToString()
|
||||
{
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// 序列化全局配置器
|
||||
/// Serializer global configuration's options
|
||||
/// </summary>
|
||||
public class JsonSerializerOption
|
||||
{
|
||||
#region pregenerated metas
|
||||
internal static readonly FieldInfo _JsonCharacterRead = typeof(JsonSerializerOption).GetField(nameof(JsonCharacterRead));
|
||||
internal static readonly FieldInfo _ReferenceLoopHandling = typeof(JsonSerializerOption).GetField(nameof(ReferenceLoopHandling));
|
||||
internal static readonly FieldInfo _IsIgnoreValueNull = typeof(JsonSerializerOption).GetField(nameof(IsIgnoreValueNull));
|
||||
internal static readonly FieldInfo _IgnoreKeys = typeof(JsonSerializerOption).GetField(nameof(IgnoreKeys));
|
||||
internal static readonly FieldInfo _IsEnumNum = typeof(JsonSerializerOption).GetField(nameof(IsEnumNum));
|
||||
|
||||
internal static readonly MethodInfo _GlobalKeyFormatInvoke = typeof(Func<string,Type, JsonSerializerHandler, string>).GetMethod("Invoke");
|
||||
internal static readonly FieldInfo _GlobalKeyFormat = typeof(JsonSerializerOption).GetField(nameof(GlobalKeyFormat));
|
||||
internal static readonly MethodInfo _GlobalValueFormatInvoke = typeof(JsonSerializerGlobalValueFormatDelegate).GetMethod("Invoke");
|
||||
internal static readonly FieldInfo _GlobalValueFormat = typeof(JsonSerializerOption).GetField(nameof(GlobalValueFormat));
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Datetime格式化枚举,默认ISO8601
|
||||
/// Datetime formatted enumeration, default ISO8601
|
||||
/// </summary>
|
||||
public DatetimeFormatEnum DatetimeFormat = DatetimeFormatEnum.ISO8601;
|
||||
|
||||
/// <summary>
|
||||
/// Timespan格式化枚举,默认ISO8601
|
||||
/// Timespan formatted enumeration, default ISO8601
|
||||
/// </summary>
|
||||
public TimespanFormatEnum TimespanFormat = TimespanFormatEnum.ISO8601;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举是否被序列化为数字,true -> 数字, false -> 字符
|
||||
/// Enumeration is serialized into numbers, true - > numbers, false - > characters
|
||||
/// </summary>
|
||||
public bool IsEnumNum = false;
|
||||
|
||||
/// <summary>
|
||||
/// byte[]数组是否按照base64格式来序列化, true -> base64 , false -> array
|
||||
/// Is the byte [] array serialized in Base64 format
|
||||
/// </summary>
|
||||
public bool IsByteArrayFormatBase64 = false;
|
||||
|
||||
/// <summary>
|
||||
/// 对Model中的Key的首字母写入状态:默认,大写,小写
|
||||
/// Write the first letter of Key in Model: default, capitalization, lowercase
|
||||
/// </summary>
|
||||
public JsonCharacterReadStateEnum JsonCharacterRead = JsonCharacterReadStateEnum.None;
|
||||
|
||||
/// <summary>
|
||||
/// 对实例因互相引用而导致的无限循环的情况的处理
|
||||
/// Handling of infinite loops caused by cross-references of instances
|
||||
/// </summary>
|
||||
public JsonReferenceHandlingEnum ReferenceLoopHandling = JsonReferenceHandlingEnum.None;
|
||||
|
||||
/// <summary>
|
||||
/// 是否忽略Model中原本值为null的对象(不包括由忽略互引用导致的null)
|
||||
/// Whether to ignore null objects in Model (excluding null caused by ignoring mutual references)
|
||||
/// </summary>
|
||||
public bool IsIgnoreValueNull = false;
|
||||
|
||||
/// <summary>
|
||||
/// 对Model中要忽略写入的Key
|
||||
/// Key to ignore writing in Model
|
||||
/// </summary>
|
||||
public List<string> IgnoreKeys;
|
||||
|
||||
/// <summary>
|
||||
/// 对Model的全局Key格式化器
|
||||
/// Global Key formatter for Model
|
||||
/// </summary>
|
||||
public Func<string,Type, JsonSerializerHandler, string> GlobalKeyFormat;
|
||||
|
||||
/// <summary>
|
||||
/// 对Model的全局Value格式化器
|
||||
/// Global Value Formatter for Model
|
||||
/// </summary>
|
||||
public JsonSerializerGlobalValueFormatDelegate GlobalValueFormat;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
namespace CPF.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Timespan格式化枚举
|
||||
/// Timespan Format Enumeration
|
||||
/// </summary>
|
||||
public enum TimespanFormatEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// TimeSpans will be formatted as ISO8601 durations.
|
||||
/// Examples: P123DT11H30M2.3S
|
||||
/// </summary>
|
||||
ISO8601,
|
||||
/// <summary>
|
||||
/// TimeSpans will be formatted as "days.hours:minutes:seconds.fractionalSeconds"
|
||||
/// </summary>
|
||||
Microsoft
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace CPF.Json.Serializer
|
||||
{
|
||||
internal static class SerializerObjectJump
|
||||
{
|
||||
private static SpinLock _spinLock = new SpinLock();
|
||||
|
||||
private static readonly Dictionary<Type, Action<object, JsonSerializerHandler>> JumpActions = new Dictionary<Type, Action<object, JsonSerializerHandler>>();
|
||||
|
||||
|
||||
#if !Net4
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
internal static Action<object, JsonSerializerHandler> GetThreadSafetyJumpAction(Type t)
|
||||
{
|
||||
if (JumpActions.TryGetValue(t, out var ac))
|
||||
return ac;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
bool i = false;
|
||||
_spinLock.Enter(ref i);
|
||||
if (!JumpActions.TryGetValue(t,out ac))
|
||||
{
|
||||
ac = GenerateAction(t);
|
||||
JumpActions.Add(t, ac);
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_spinLock.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static Action<object, JsonSerializerHandler> GenerateAction( Type t)
|
||||
{
|
||||
ParameterExpression objArg = Expression.Parameter(typeof(object), "instance");
|
||||
Expression originalArg = Expression.Convert(objArg, t);
|
||||
ParameterExpression handlerArg = Expression.Parameter(typeof(JsonSerializerHandler), "handler");
|
||||
var body = Expression.Call(typeof(FormattingProvider<>).MakeGenericType(t).GetMethod("Convert",BindingFlags.NonPublic|BindingFlags.Static), originalArg, handlerArg);
|
||||
return Expression.Lambda<Action<object, JsonSerializerHandler>>(body, objArg, handlerArg).Compile();
|
||||
}
|
||||
}
|
||||
}
|
10
CPF/Json/Getters.cs
Normal file
10
CPF/Json/Getters.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
public sealed class DatasetSchema
|
||||
{
|
||||
public List<string> Info ;//{ get; set; }
|
||||
public string Name ;//{ get; set; }
|
||||
}
|
||||
}
|
663
CPF/Json/JSerializer.cs
Normal file
663
CPF/Json/JSerializer.cs
Normal file
@ -0,0 +1,663 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
#if !SILVERLIGHT
|
||||
using System.Data;
|
||||
#endif
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
internal sealed class JSerializer
|
||||
{
|
||||
private StringBuilder _output = new StringBuilder();
|
||||
//private StringBuilder _before = new StringBuilder();
|
||||
private int _before;
|
||||
private int _MAX_DEPTH = 200;
|
||||
int _current_depth = 0;
|
||||
private Dictionary<string, int> _globalTypes = new Dictionary<string, int>();
|
||||
private Dictionary<object, int> _cirobj = new Dictionary<object, int>();
|
||||
private JSONParameters _params;
|
||||
private bool _useEscapedUnicode = false;
|
||||
|
||||
internal JSerializer(JSONParameters param)
|
||||
{
|
||||
_params = param;
|
||||
_useEscapedUnicode = _params.UseEscapedUnicode;
|
||||
_MAX_DEPTH = _params.SerializerMaxDepth;
|
||||
}
|
||||
|
||||
internal string ConvertToJSON(object obj)
|
||||
{
|
||||
WriteValue(obj);
|
||||
|
||||
if (_params.UsingGlobalTypes && _globalTypes != null && _globalTypes.Count > 0)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("\"$types\":{");
|
||||
var pendingSeparator = false;
|
||||
foreach (var kv in _globalTypes)
|
||||
{
|
||||
if (pendingSeparator) sb.Append(',');
|
||||
pendingSeparator = true;
|
||||
sb.Append('\"');
|
||||
sb.Append(kv.Key);
|
||||
sb.Append("\":\"");
|
||||
sb.Append(kv.Value);
|
||||
sb.Append('\"');
|
||||
}
|
||||
sb.Append("},");
|
||||
_output.Insert(_before, sb.ToString());
|
||||
}
|
||||
return _output.ToString();
|
||||
}
|
||||
|
||||
private void WriteValue(object obj)
|
||||
{
|
||||
if (obj == null || obj is DBNull)
|
||||
_output.Append("null");
|
||||
|
||||
else if (obj is string || obj is char)
|
||||
WriteString(obj.ToString());
|
||||
|
||||
else if (obj is Guid)
|
||||
WriteGuid((Guid)obj);
|
||||
|
||||
else if (obj is bool)
|
||||
_output.Append(((bool)obj) ? "true" : "false"); // conform to standard
|
||||
|
||||
else if (
|
||||
obj is int || obj is long ||
|
||||
obj is decimal ||
|
||||
obj is byte || obj is short ||
|
||||
obj is sbyte || obj is ushort ||
|
||||
obj is uint || obj is ulong
|
||||
)
|
||||
_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
|
||||
|
||||
else if (obj is double || obj is Double)
|
||||
{
|
||||
double d = (double)obj;
|
||||
if (double.IsNaN(d))
|
||||
_output.Append("\"NaN\"");
|
||||
else
|
||||
_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
|
||||
}
|
||||
else if (obj is float || obj is Single)
|
||||
{
|
||||
float d = (float)obj;
|
||||
if (float.IsNaN(d))
|
||||
_output.Append("\"NaN\"");
|
||||
else
|
||||
_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
|
||||
}
|
||||
|
||||
else if (obj is DateTime)
|
||||
WriteDateTime((DateTime)obj);
|
||||
|
||||
else if (obj is DateTimeOffset)
|
||||
WriteDateTimeOffset((DateTimeOffset)obj);
|
||||
|
||||
else if (obj is TimeSpan)
|
||||
_output.Append(((TimeSpan)obj).Ticks);
|
||||
|
||||
#if net4
|
||||
else if (_params.KVStyleStringDictionary == false &&
|
||||
obj is IEnumerable<KeyValuePair<string, object>>)
|
||||
|
||||
WriteStringDictionary((IEnumerable<KeyValuePair<string, object>>)obj);
|
||||
#endif
|
||||
|
||||
else if (_params.KVStyleStringDictionary == false && obj is IDictionary &&
|
||||
obj.GetType().IsGenericType && obj.GetType().GetGenericArguments()[0] == typeof(string))
|
||||
|
||||
WriteStringDictionary((IDictionary)obj);
|
||||
else if (obj is IDictionary)
|
||||
WriteDictionary((IDictionary)obj);
|
||||
#if !SILVERLIGHT
|
||||
else if (obj is DataSet)
|
||||
WriteDataset((DataSet)obj);
|
||||
|
||||
else if (obj is DataTable)
|
||||
this.WriteDataTable((DataTable)obj);
|
||||
#endif
|
||||
else if (obj is byte[])
|
||||
WriteBytes((byte[])obj);
|
||||
|
||||
else if (obj is StringDictionary)
|
||||
WriteSD((StringDictionary)obj);
|
||||
|
||||
else if (obj is NameValueCollection)
|
||||
WriteNV((NameValueCollection)obj);
|
||||
|
||||
else if (obj is IEnumerable)
|
||||
WriteArray((IEnumerable)obj);
|
||||
|
||||
else if (obj is Enum)
|
||||
WriteEnum((Enum)obj);
|
||||
|
||||
else if (Reflection.Instance.IsTypeRegistered(obj.GetType()))
|
||||
WriteCustom(obj);
|
||||
|
||||
else
|
||||
WriteObject(obj);
|
||||
}
|
||||
|
||||
private void WriteDateTimeOffset(DateTimeOffset d)
|
||||
{
|
||||
write_date_value(d.DateTime);
|
||||
_output.Append(" ");
|
||||
if (d.Offset.Hours > 0)
|
||||
_output.Append("+");
|
||||
else
|
||||
_output.Append("-");
|
||||
_output.Append(d.Offset.Hours.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||
_output.Append(":");
|
||||
_output.Append(d.Offset.Minutes);
|
||||
|
||||
_output.Append('\"');
|
||||
}
|
||||
|
||||
private void WriteNV(NameValueCollection nameValueCollection)
|
||||
{
|
||||
_output.Append('{');
|
||||
|
||||
bool pendingSeparator = false;
|
||||
|
||||
foreach (string key in nameValueCollection)
|
||||
{
|
||||
if (_params.SerializeNullValues == false && (nameValueCollection[key] == null))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pendingSeparator) _output.Append(',');
|
||||
if (_params.SerializeToLowerCaseNames)
|
||||
WritePair(key.ToLower(), nameValueCollection[key]);
|
||||
else
|
||||
WritePair(key, nameValueCollection[key]);
|
||||
pendingSeparator = true;
|
||||
}
|
||||
}
|
||||
_output.Append('}');
|
||||
}
|
||||
|
||||
private void WriteSD(StringDictionary stringDictionary)
|
||||
{
|
||||
_output.Append('{');
|
||||
|
||||
bool pendingSeparator = false;
|
||||
|
||||
foreach (DictionaryEntry entry in stringDictionary)
|
||||
{
|
||||
if (_params.SerializeNullValues == false && (entry.Value == null))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pendingSeparator) _output.Append(',');
|
||||
|
||||
string k = (string)entry.Key;
|
||||
if (_params.SerializeToLowerCaseNames)
|
||||
WritePair(k.ToLower(), entry.Value);
|
||||
else
|
||||
WritePair(k, entry.Value);
|
||||
pendingSeparator = true;
|
||||
}
|
||||
}
|
||||
_output.Append('}');
|
||||
}
|
||||
|
||||
private void WriteCustom(object obj)
|
||||
{
|
||||
Serialize s;
|
||||
Reflection.Instance._customSerializer.TryGetValue(obj.GetType(), out s);
|
||||
WriteStringFast(s(obj));
|
||||
}
|
||||
|
||||
private void WriteEnum(Enum e)
|
||||
{
|
||||
// FEATURE : optimize enum write
|
||||
if (_params.UseValuesOfEnums)
|
||||
WriteValue(Convert.ToInt32(e));
|
||||
else
|
||||
WriteStringFast(e.ToString());
|
||||
}
|
||||
|
||||
private void WriteGuid(Guid g)
|
||||
{
|
||||
if (_params.UseFastGuid == false)
|
||||
WriteStringFast(g.ToString());
|
||||
else
|
||||
WriteBytes(g.ToByteArray());
|
||||
}
|
||||
|
||||
private void WriteBytes(byte[] bytes)
|
||||
{
|
||||
#if !SILVERLIGHT
|
||||
WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None));
|
||||
#else
|
||||
WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length));
|
||||
#endif
|
||||
}
|
||||
|
||||
private void WriteDateTime(DateTime dateTime)
|
||||
{
|
||||
// datetime format standard : yyyy-MM-dd HH:mm:ss
|
||||
DateTime dt = dateTime;
|
||||
if (_params.UseUTCDateTime)
|
||||
dt = dateTime.ToUniversalTime();
|
||||
|
||||
write_date_value(dt);
|
||||
|
||||
if (_params.UseUTCDateTime)
|
||||
_output.Append('Z');
|
||||
|
||||
_output.Append('\"');
|
||||
}
|
||||
|
||||
private void write_date_value(DateTime dt)
|
||||
{
|
||||
_output.Append('\"');
|
||||
_output.Append(dt.Year.ToString("0000", NumberFormatInfo.InvariantInfo));
|
||||
_output.Append('-');
|
||||
_output.Append(dt.Month.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||
_output.Append('-');
|
||||
_output.Append(dt.Day.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||
_output.Append('T'); // strict ISO date compliance
|
||||
_output.Append(dt.Hour.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||
_output.Append(':');
|
||||
_output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||
_output.Append(':');
|
||||
_output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo));
|
||||
if (_params.DateTimeMilliseconds)
|
||||
{
|
||||
_output.Append('.');
|
||||
_output.Append(dt.Millisecond.ToString("000", NumberFormatInfo.InvariantInfo));
|
||||
}
|
||||
}
|
||||
|
||||
#if !SILVERLIGHT
|
||||
private DatasetSchema GetSchema(DataTable ds)
|
||||
{
|
||||
if (ds == null) return null;
|
||||
|
||||
DatasetSchema m = new DatasetSchema();
|
||||
m.Info = new List<string>();
|
||||
m.Name = ds.TableName;
|
||||
|
||||
foreach (DataColumn c in ds.Columns)
|
||||
{
|
||||
m.Info.Add(ds.TableName);
|
||||
m.Info.Add(c.ColumnName);
|
||||
m.Info.Add(c.DataType.ToString());
|
||||
}
|
||||
// FEATURE : serialize relations and constraints here
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
private DatasetSchema GetSchema(DataSet ds)
|
||||
{
|
||||
if (ds == null) return null;
|
||||
|
||||
DatasetSchema m = new DatasetSchema();
|
||||
m.Info = new List<string>();
|
||||
m.Name = ds.DataSetName;
|
||||
|
||||
foreach (DataTable t in ds.Tables)
|
||||
{
|
||||
foreach (DataColumn c in t.Columns)
|
||||
{
|
||||
m.Info.Add(t.TableName);
|
||||
m.Info.Add(c.ColumnName);
|
||||
m.Info.Add(c.DataType.ToString());
|
||||
}
|
||||
}
|
||||
// FEATURE : serialize relations and constraints here
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
private string GetXmlSchema(DataTable dt)
|
||||
{
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
dt.WriteXmlSchema(writer);
|
||||
return dt.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteDataset(DataSet ds)
|
||||
{
|
||||
_output.Append('{');
|
||||
if (_params.UseExtensions)
|
||||
{
|
||||
WritePair("$schema", _params.UseOptimizedDatasetSchema ? (object)GetSchema(ds) : ds.GetXmlSchema());
|
||||
_output.Append(',');
|
||||
}
|
||||
bool tablesep = false;
|
||||
foreach (DataTable table in ds.Tables)
|
||||
{
|
||||
if (tablesep) _output.Append(',');
|
||||
tablesep = true;
|
||||
WriteDataTableData(table);
|
||||
}
|
||||
// end dataset
|
||||
_output.Append('}');
|
||||
}
|
||||
|
||||
private void WriteDataTableData(DataTable table)
|
||||
{
|
||||
_output.Append('\"');
|
||||
_output.Append(table.TableName);
|
||||
_output.Append("\":[");
|
||||
DataColumnCollection cols = table.Columns;
|
||||
bool rowseparator = false;
|
||||
foreach (DataRow row in table.Rows)
|
||||
{
|
||||
if (rowseparator) _output.Append(',');
|
||||
rowseparator = true;
|
||||
_output.Append('[');
|
||||
|
||||
bool pendingSeperator = false;
|
||||
foreach (DataColumn column in cols)
|
||||
{
|
||||
if (pendingSeperator) _output.Append(',');
|
||||
WriteValue(row[column]);
|
||||
pendingSeperator = true;
|
||||
}
|
||||
_output.Append(']');
|
||||
}
|
||||
|
||||
_output.Append(']');
|
||||
}
|
||||
|
||||
void WriteDataTable(DataTable dt)
|
||||
{
|
||||
this._output.Append('{');
|
||||
if (_params.UseExtensions)
|
||||
{
|
||||
this.WritePair("$schema", _params.UseOptimizedDatasetSchema ? (object)this.GetSchema(dt) : this.GetXmlSchema(dt));
|
||||
this._output.Append(',');
|
||||
}
|
||||
|
||||
WriteDataTableData(dt);
|
||||
|
||||
// end datatable
|
||||
this._output.Append('}');
|
||||
}
|
||||
#endif
|
||||
|
||||
bool _TypesWritten = false;
|
||||
private void WriteObject(object obj)
|
||||
{
|
||||
int i = 0;
|
||||
if (_cirobj.TryGetValue(obj, out i) == false)
|
||||
_cirobj.Add(obj, _cirobj.Count + 1);
|
||||
else
|
||||
{
|
||||
if (_current_depth > 0 && _params.InlineCircularReferences == false)
|
||||
{
|
||||
//_circular = true;
|
||||
_output.Append("{\"$i\":");
|
||||
_output.Append(i.ToString());
|
||||
_output.Append("}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_params.UsingGlobalTypes == false)
|
||||
_output.Append('{');
|
||||
else
|
||||
{
|
||||
if (_TypesWritten == false)
|
||||
{
|
||||
_output.Append('{');
|
||||
_before = _output.Length;
|
||||
//_output = new StringBuilder();
|
||||
}
|
||||
else
|
||||
_output.Append('{');
|
||||
}
|
||||
_TypesWritten = true;
|
||||
_current_depth++;
|
||||
if (_current_depth > _MAX_DEPTH)
|
||||
throw new Exception("Serializer encountered maximum depth of " + _MAX_DEPTH);
|
||||
|
||||
|
||||
Dictionary<string, string> map = new Dictionary<string, string>();
|
||||
Type t = obj.GetType();
|
||||
bool append = false;
|
||||
if (_params.UseExtensions)
|
||||
{
|
||||
if (_params.UsingGlobalTypes == false)
|
||||
WritePairFast("$type", Reflection.Instance.GetTypeAssemblyName(t));
|
||||
else
|
||||
{
|
||||
int dt = 0;
|
||||
string ct = Reflection.Instance.GetTypeAssemblyName(t);
|
||||
if (_globalTypes.TryGetValue(ct, out dt) == false)
|
||||
{
|
||||
dt = _globalTypes.Count + 1;
|
||||
_globalTypes.Add(ct, dt);
|
||||
}
|
||||
WritePairFast("$type", dt.ToString());
|
||||
}
|
||||
append = true;
|
||||
}
|
||||
|
||||
Getters[] g = Reflection.Instance.GetGetters(t, _params.ShowReadOnlyProperties, _params.IgnoreAttributes);
|
||||
int c = g.Length;
|
||||
for (int ii = 0; ii < c; ii++)
|
||||
{
|
||||
var p = g[ii];
|
||||
object o = p.Getter(obj);
|
||||
if (_params.SerializeNullValues == false && (o == null || o is DBNull))
|
||||
{
|
||||
//append = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (append)
|
||||
_output.Append(',');
|
||||
if (_params.SerializeToLowerCaseNames)
|
||||
WritePair(p.lcName, o);
|
||||
else
|
||||
WritePair(p.Name, o);
|
||||
if (o != null && _params.UseExtensions)
|
||||
{
|
||||
Type tt = o.GetType();
|
||||
if (tt == typeof(System.Object))
|
||||
map.Add(p.Name, tt.ToString());
|
||||
}
|
||||
append = true;
|
||||
}
|
||||
}
|
||||
if (map.Count > 0 && _params.UseExtensions)
|
||||
{
|
||||
_output.Append(",\"$map\":");
|
||||
WriteStringDictionary(map);
|
||||
}
|
||||
_output.Append('}');
|
||||
_current_depth--;
|
||||
}
|
||||
|
||||
private void WritePairFast(string name, string value)
|
||||
{
|
||||
WriteStringFast(name);
|
||||
|
||||
_output.Append(':');
|
||||
|
||||
WriteStringFast(value);
|
||||
}
|
||||
|
||||
private void WritePair(string name, object value)
|
||||
{
|
||||
WriteString(name);
|
||||
|
||||
_output.Append(':');
|
||||
|
||||
WriteValue(value);
|
||||
}
|
||||
|
||||
private void WriteArray(IEnumerable array)
|
||||
{
|
||||
_output.Append('[');
|
||||
|
||||
bool pendingSeperator = false;
|
||||
|
||||
foreach (object obj in array)
|
||||
{
|
||||
if (pendingSeperator) _output.Append(',');
|
||||
|
||||
WriteValue(obj);
|
||||
|
||||
pendingSeperator = true;
|
||||
}
|
||||
_output.Append(']');
|
||||
}
|
||||
|
||||
private void WriteStringDictionary(IDictionary dic)
|
||||
{
|
||||
_output.Append('{');
|
||||
|
||||
bool pendingSeparator = false;
|
||||
|
||||
foreach (DictionaryEntry entry in dic)
|
||||
{
|
||||
if (_params.SerializeNullValues == false && (entry.Value == null))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pendingSeparator) _output.Append(',');
|
||||
|
||||
string k = (string)entry.Key;
|
||||
if (_params.SerializeToLowerCaseNames)
|
||||
WritePair(k.ToLower(), entry.Value);
|
||||
else
|
||||
WritePair(k, entry.Value);
|
||||
pendingSeparator = true;
|
||||
}
|
||||
}
|
||||
_output.Append('}');
|
||||
}
|
||||
|
||||
private void WriteStringDictionary(IEnumerable<KeyValuePair<string, object>> dic)
|
||||
{
|
||||
_output.Append('{');
|
||||
bool pendingSeparator = false;
|
||||
foreach (KeyValuePair<string, object> entry in dic)
|
||||
{
|
||||
if (_params.SerializeNullValues == false && (entry.Value == null))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pendingSeparator) _output.Append(',');
|
||||
string k = entry.Key;
|
||||
|
||||
if (_params.SerializeToLowerCaseNames)
|
||||
WritePair(k.ToLower(), entry.Value);
|
||||
else
|
||||
WritePair(k, entry.Value);
|
||||
pendingSeparator = true;
|
||||
}
|
||||
}
|
||||
_output.Append('}');
|
||||
}
|
||||
|
||||
private void WriteDictionary(IDictionary dic)
|
||||
{
|
||||
_output.Append('[');
|
||||
|
||||
bool pendingSeparator = false;
|
||||
|
||||
foreach (DictionaryEntry entry in dic)
|
||||
{
|
||||
if (pendingSeparator) _output.Append(',');
|
||||
_output.Append('{');
|
||||
WritePair("k", entry.Key);
|
||||
_output.Append(",");
|
||||
WritePair("v", entry.Value);
|
||||
_output.Append('}');
|
||||
|
||||
pendingSeparator = true;
|
||||
}
|
||||
_output.Append(']');
|
||||
}
|
||||
|
||||
private void WriteStringFast(string s)
|
||||
{
|
||||
_output.Append('\"');
|
||||
_output.Append(s);
|
||||
_output.Append('\"');
|
||||
}
|
||||
|
||||
private void WriteString(string s)
|
||||
{
|
||||
_output.Append('\"');
|
||||
|
||||
int runIndex = -1;
|
||||
int l = s.Length;
|
||||
for (var index = 0; index < l; ++index)
|
||||
{
|
||||
var c = s[index];
|
||||
|
||||
if (_useEscapedUnicode)
|
||||
{
|
||||
if (c >= ' ' && c < 128 && c != '\"' && c != '\\')
|
||||
{
|
||||
if (runIndex == -1)
|
||||
runIndex = index;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c != '\t' && c != '\n' && c != '\r' && c != '\"' && c != '\\')// && c != ':' && c!=',')
|
||||
{
|
||||
if (runIndex == -1)
|
||||
runIndex = index;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (runIndex != -1)
|
||||
{
|
||||
_output.Append(s, runIndex, index - runIndex);
|
||||
runIndex = -1;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\t': _output.Append("\\t"); break;
|
||||
case '\r': _output.Append("\\r"); break;
|
||||
case '\n': _output.Append("\\n"); break;
|
||||
case '"':
|
||||
case '\\': _output.Append('\\'); _output.Append(c); break;
|
||||
default:
|
||||
if (_useEscapedUnicode)
|
||||
{
|
||||
_output.Append("\\u");
|
||||
_output.Append(((int)c).ToString("X4", NumberFormatInfo.InvariantInfo));
|
||||
}
|
||||
else
|
||||
_output.Append(c);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (runIndex != -1)
|
||||
_output.Append(s, runIndex, s.Length - runIndex);
|
||||
|
||||
_output.Append('\"');
|
||||
}
|
||||
}
|
||||
}
|
443
CPF/Json/JsonParser.cs
Normal file
443
CPF/Json/JsonParser.cs
Normal file
@ -0,0 +1,443 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class encodes and decodes JSON strings.
|
||||
/// Spec. details, see http://www.json.org/
|
||||
/// </summary>
|
||||
internal sealed class JsonParser
|
||||
{
|
||||
enum Token
|
||||
{
|
||||
None = -1, // Used to denote no Lookahead available
|
||||
Curly_Open,
|
||||
Curly_Close,
|
||||
Squared_Open,
|
||||
Squared_Close,
|
||||
Colon,
|
||||
Comma,
|
||||
String,
|
||||
Number,
|
||||
True,
|
||||
False,
|
||||
Null
|
||||
}
|
||||
|
||||
readonly string json;
|
||||
readonly StringBuilder s = new StringBuilder(); // used for inner string parsing " \"\r\n\u1234\'\t "
|
||||
Token lookAheadToken = Token.None;
|
||||
int index;
|
||||
|
||||
internal JsonParser(string json)
|
||||
{
|
||||
this.json = json;
|
||||
}
|
||||
|
||||
public object Decode()
|
||||
{
|
||||
return ParseValue();
|
||||
}
|
||||
|
||||
private Dictionary<string, object> ParseObject()
|
||||
{
|
||||
Dictionary<string, object> table = new Dictionary<string, object>();
|
||||
|
||||
ConsumeToken(); // {
|
||||
|
||||
while (true)
|
||||
{
|
||||
switch (LookAhead())
|
||||
{
|
||||
|
||||
case Token.Comma:
|
||||
ConsumeToken();
|
||||
break;
|
||||
|
||||
case Token.Curly_Close:
|
||||
ConsumeToken();
|
||||
return table;
|
||||
|
||||
default:
|
||||
{
|
||||
// name
|
||||
string name = ParseString();
|
||||
|
||||
// :
|
||||
if (NextToken() != Token.Colon)
|
||||
{
|
||||
throw new Exception("Expected colon at index " + index);
|
||||
}
|
||||
|
||||
// value
|
||||
object value = ParseValue();
|
||||
|
||||
table[name] = value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<object> ParseArray()
|
||||
{
|
||||
List<object> array = new List<object>();
|
||||
ConsumeToken(); // [
|
||||
|
||||
while (true)
|
||||
{
|
||||
switch (LookAhead())
|
||||
{
|
||||
case Token.Comma:
|
||||
ConsumeToken();
|
||||
break;
|
||||
|
||||
case Token.Squared_Close:
|
||||
ConsumeToken();
|
||||
return array;
|
||||
|
||||
default:
|
||||
array.Add(ParseValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object ParseValue()
|
||||
{
|
||||
switch (LookAhead())
|
||||
{
|
||||
case Token.Number:
|
||||
return ParseNumber();
|
||||
|
||||
case Token.String:
|
||||
return ParseString();
|
||||
|
||||
case Token.Curly_Open:
|
||||
return ParseObject();
|
||||
|
||||
case Token.Squared_Open:
|
||||
return ParseArray();
|
||||
|
||||
case Token.True:
|
||||
ConsumeToken();
|
||||
return true;
|
||||
|
||||
case Token.False:
|
||||
ConsumeToken();
|
||||
return false;
|
||||
|
||||
case Token.Null:
|
||||
ConsumeToken();
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new Exception("Unrecognized token at index" + index);
|
||||
}
|
||||
|
||||
private string ParseString()
|
||||
{
|
||||
ConsumeToken(); // "
|
||||
|
||||
s.Length = 0;
|
||||
|
||||
int runIndex = -1;
|
||||
int l = json.Length;
|
||||
//fixed (char* p = json)
|
||||
string p = json;
|
||||
{
|
||||
while (index < l)
|
||||
{
|
||||
var c = p[index++];
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
if (runIndex != -1)
|
||||
{
|
||||
if (s.Length == 0)
|
||||
return json.Substring(runIndex, index - runIndex - 1);
|
||||
|
||||
s.Append(json, runIndex, index - runIndex - 1);
|
||||
}
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
if (c != '\\')
|
||||
{
|
||||
if (runIndex == -1)
|
||||
runIndex = index - 1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index == l) break;
|
||||
|
||||
if (runIndex != -1)
|
||||
{
|
||||
s.Append(json, runIndex, index - runIndex - 1);
|
||||
runIndex = -1;
|
||||
}
|
||||
|
||||
switch (p[index++])
|
||||
{
|
||||
case '"':
|
||||
s.Append('"');
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
s.Append('\\');
|
||||
break;
|
||||
|
||||
case '/':
|
||||
s.Append('/');
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
s.Append('\b');
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
s.Append('\f');
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
s.Append('\n');
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
s.Append('\r');
|
||||
break;
|
||||
|
||||
case 't':
|
||||
s.Append('\t');
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
{
|
||||
int remainingLength = l - index;
|
||||
if (remainingLength < 4) break;
|
||||
|
||||
// parse the 32 bit hex into an integer codepoint
|
||||
uint codePoint = ParseUnicode(p[index], p[index + 1], p[index + 2], p[index + 3]);
|
||||
s.Append((char)codePoint);
|
||||
|
||||
// skip 4 chars
|
||||
index += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Unexpectedly reached end of string");
|
||||
}
|
||||
|
||||
private uint ParseSingleChar(char c1, uint multipliyer)
|
||||
{
|
||||
uint p1 = 0;
|
||||
if (c1 >= '0' && c1 <= '9')
|
||||
p1 = (uint)(c1 - '0') * multipliyer;
|
||||
else if (c1 >= 'A' && c1 <= 'F')
|
||||
p1 = (uint)((c1 - 'A') + 10) * multipliyer;
|
||||
else if (c1 >= 'a' && c1 <= 'f')
|
||||
p1 = (uint)((c1 - 'a') + 10) * multipliyer;
|
||||
return p1;
|
||||
}
|
||||
|
||||
private uint ParseUnicode(char c1, char c2, char c3, char c4)
|
||||
{
|
||||
uint p1 = ParseSingleChar(c1, 0x1000);
|
||||
uint p2 = ParseSingleChar(c2, 0x100);
|
||||
uint p3 = ParseSingleChar(c3, 0x10);
|
||||
uint p4 = ParseSingleChar(c4, 1);
|
||||
|
||||
return p1 + p2 + p3 + p4;
|
||||
}
|
||||
|
||||
private long CreateLong(string s)
|
||||
{
|
||||
long num = 0;
|
||||
bool neg = false;
|
||||
foreach (char cc in s)
|
||||
{
|
||||
if (cc == '-')
|
||||
neg = true;
|
||||
else if (cc == '+')
|
||||
neg = false;
|
||||
else
|
||||
{
|
||||
num *= 10;
|
||||
num += (int)(cc - '0');
|
||||
}
|
||||
}
|
||||
|
||||
return neg ? -num : num;
|
||||
}
|
||||
|
||||
private object ParseNumber()
|
||||
{
|
||||
ConsumeToken();
|
||||
|
||||
// Need to start back one place because the first digit is also a token and would have been consumed
|
||||
var startIndex = index - 1;
|
||||
bool dec = false;
|
||||
do
|
||||
{
|
||||
if (index == json.Length)
|
||||
break;
|
||||
var c = json[index];
|
||||
|
||||
if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E')
|
||||
{
|
||||
if (c == '.' || c == 'e' || c == 'E')
|
||||
dec = true;
|
||||
if (++index == json.Length)
|
||||
break;//throw new Exception("Unexpected end of string whilst parsing number");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} while (true);
|
||||
|
||||
if (dec)
|
||||
{
|
||||
string s = json.Substring(startIndex, index - startIndex);
|
||||
return double.Parse(s, NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
return JsonSerializer.CreateLong(json, startIndex, index - startIndex);
|
||||
}
|
||||
|
||||
private Token LookAhead()
|
||||
{
|
||||
if (lookAheadToken != Token.None) return lookAheadToken;
|
||||
|
||||
return lookAheadToken = NextTokenCore();
|
||||
}
|
||||
|
||||
private void ConsumeToken()
|
||||
{
|
||||
lookAheadToken = Token.None;
|
||||
}
|
||||
|
||||
private Token NextToken()
|
||||
{
|
||||
var result = lookAheadToken != Token.None ? lookAheadToken : NextTokenCore();
|
||||
|
||||
lookAheadToken = Token.None;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Token NextTokenCore()
|
||||
{
|
||||
char c;
|
||||
|
||||
// Skip past whitespace
|
||||
do
|
||||
{
|
||||
c = json[index];
|
||||
|
||||
if (c == '/' && json[index + 1] == '/') // c++ style single line comments
|
||||
{
|
||||
index++;
|
||||
index++;
|
||||
do
|
||||
{
|
||||
c = json[index];
|
||||
if (c == '\r' || c == '\n') break; // read till end of line
|
||||
}
|
||||
while (++index < json.Length);
|
||||
}
|
||||
if (c > ' ') break;
|
||||
if (c != ' ' && c != '\t' && c != '\n' && c != '\r') break;
|
||||
|
||||
} while (++index < json.Length);
|
||||
|
||||
if (index == json.Length)
|
||||
{
|
||||
throw new Exception("Reached end of string unexpectedly");
|
||||
}
|
||||
|
||||
c = json[index];
|
||||
|
||||
index++;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '{':
|
||||
return Token.Curly_Open;
|
||||
|
||||
case '}':
|
||||
return Token.Curly_Close;
|
||||
|
||||
case '[':
|
||||
return Token.Squared_Open;
|
||||
|
||||
case ']':
|
||||
return Token.Squared_Close;
|
||||
|
||||
case ',':
|
||||
return Token.Comma;
|
||||
|
||||
case '"':
|
||||
return Token.String;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
case '+':
|
||||
case '.':
|
||||
return Token.Number;
|
||||
|
||||
case ':':
|
||||
return Token.Colon;
|
||||
|
||||
case 'f':
|
||||
if (json.Length - index >= 4 &&
|
||||
json[index + 0] == 'a' &&
|
||||
json[index + 1] == 'l' &&
|
||||
json[index + 2] == 's' &&
|
||||
json[index + 3] == 'e')
|
||||
{
|
||||
index += 4;
|
||||
return Token.False;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (json.Length - index >= 3 &&
|
||||
json[index + 0] == 'r' &&
|
||||
json[index + 1] == 'u' &&
|
||||
json[index + 2] == 'e')
|
||||
{
|
||||
index += 3;
|
||||
return Token.True;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (json.Length - index >= 3 &&
|
||||
json[index + 0] == 'u' &&
|
||||
json[index + 1] == 'l' &&
|
||||
json[index + 2] == 'l')
|
||||
{
|
||||
index += 3;
|
||||
return Token.Null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new Exception("Could not find token at index " + --index);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
51
CPF/Json/SafeDictionary.cs
Normal file
51
CPF/Json/SafeDictionary.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CPF.Json
|
||||
{
|
||||
public sealed class SafeDictionary<TKey, TValue>
|
||||
{
|
||||
private readonly object _Padlock = new object();
|
||||
private readonly Dictionary<TKey, TValue> _Dictionary;
|
||||
|
||||
public SafeDictionary(int capacity)
|
||||
{
|
||||
_Dictionary = new Dictionary<TKey, TValue>(capacity);
|
||||
}
|
||||
|
||||
public SafeDictionary()
|
||||
{
|
||||
_Dictionary = new Dictionary<TKey, TValue>();
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
lock (_Padlock)
|
||||
return _Dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public int Count { get { lock (_Padlock) return _Dictionary.Count; } }
|
||||
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_Padlock)
|
||||
return _Dictionary[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (_Padlock)
|
||||
_Dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
lock (_Padlock)
|
||||
{
|
||||
if (_Dictionary.ContainsKey(key) == false)
|
||||
_Dictionary.Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
175
ConsoleApp1.sln
175
ConsoleApp1.sln
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29324.140
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34309.116
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{ABE4ED47-CB9F-4183-9CE3-65E3E521BE2A}"
|
||||
EndProject
|
||||
@ -11,64 +11,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Windows", "CPF.Windows\
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Skia", "CPF.Skia\CPF.Skia.csproj", "{E6495F31-7937-4A69-A915-834BFA1A031F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApp1", "WindowsFormsApp1\WindowsFormsApp1.csproj", "{2C544909-EAB9-43F8-85B0-C04E2453289E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Mac", "CPF.Mac\CPF.Mac.csproj", "{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPFProjectTemplate", "CPFProjectTemplate\CPFProjectTemplate.csproj", "{BBAFD33E-1CF8-4AC4-9928-337E746947A6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPFItemTemplate", "CPFItemTemplate\CPFItemTemplate.csproj", "{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPFWindowTemplate", "CPFWindowTemplate\CPFWindowTemplate.csproj", "{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Linux", "CPF.Linux\CPF.Linux.csproj", "{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Template", "Template", "{1D98D556-38A7-4ED6-ACAD-697B5E0625DE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPFProjectNetCore3AndNet4", "CPFProjectNetCore3AndNet4\CPFProjectNetCore3AndNet4.csproj", "{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Cef", "CPF.Cef\CPF.Cef.csproj", "{A0703482-DAAD-43F6-A39F-4326157C1ADC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Vlc", "CPF.Vlc\CPF.Vlc.csproj", "{B2A6696C-288D-44C2-A393-9DC3C7773C8F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPF.Android", "CPF.Android\CPF.Android.csproj", "{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NESPlayer", "NESPlayer\NESPlayer.csproj", "{CC00B3A6-7F84-4BDA-B8C9-915723F51207}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidTest", "AndroidTest\AndroidTest.csproj", "{C7338F66-2EAF-4F0A-9306-53232DD20501}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPFDesigner", "Private\CPFDesigner\CPFDesigner.csproj", "{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Private", "Private", "{2B729C46-7592-425A-87E9-D769A94881F7}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesignerShared", "Private\DesignerShared\DesignerShared.csproj", "{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesignerSurface", "Private\DesignerSurface\DesignerSurface.csproj", "{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeveloperTools", "Private\DeveloperTools\DeveloperTools.csproj", "{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DeveloperUpdate", "Private\DeveloperUpdate\DeveloperUpdate.csproj", "{1278A1BC-327D-4D13-AD04-C6FF2B680530}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedVSIX", "Private\SharedVSIX\SharedVSIX.shproj", "{F34CFFEE-546F-490E-A76A-2792840B284D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CPFDesigner2022", "Private\CPFDesigner2022\CPFDesigner2022.csproj", "{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Demo", "CPF_Demo\CPF.Demo.csproj", "{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "蓝图重制版", "蓝图重制版\蓝图重制版.csproj", "{003E155A-8C40-41AF-A796-ED17E729E013}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CPF.Razor", "CPF.Razor\CPF.Razor.csproj", "{87E1ED0A-BFBF-4F5E-9FDF-5EAFE48DD719}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CpfRazorSample", "CpfRazorSample\CpfRazorSample.csproj", "{25A4EE47-F5BD-4F1E-B143-3E3B50C5AC2A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
Private\SharedVSIX\SharedVSIX.projitems*{db53e8d7-dfb6-48eb-a7b6-d1cf762acb9b}*SharedItemsImports = 4
|
||||
Private\SharedVSIX\SharedVSIX.projitems*{df526631-d060-47f2-afd4-62c6cea2fe9a}*SharedItemsImports = 4
|
||||
Private\SharedVSIX\SharedVSIX.projitems*{f34cffee-546f-490e-a76a-2792840b284d}*SharedItemsImports = 13
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
@ -99,135 +52,24 @@ Global
|
||||
{E6495F31-7937-4A69-A915-834BFA1A031F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E6495F31-7937-4A69-A915-834BFA1A031F}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E6495F31-7937-4A69-A915-834BFA1A031F}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C544909-EAB9-43F8-85B0-C04E2453289E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C544909-EAB9-43F8-85B0-C04E2453289E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C544909-EAB9-43F8-85B0-C04E2453289E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C544909-EAB9-43F8-85B0-C04E2453289E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C544909-EAB9-43F8-85B0-C04E2453289E}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C544909-EAB9-43F8-85B0-C04E2453289E}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C63692AB-1CA6-4416-AB5C-9D71D1E3FC66}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A91093C9-BFE6-4536-ADA1-E35F91C8AB37}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{A0703482-DAAD-43F6-A39F-4326157C1ADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A0703482-DAAD-43F6-A39F-4326157C1ADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A0703482-DAAD-43F6-A39F-4326157C1ADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A0703482-DAAD-43F6-A39F-4326157C1ADC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A0703482-DAAD-43F6-A39F-4326157C1ADC}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A0703482-DAAD-43F6-A39F-4326157C1ADC}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{B2A6696C-288D-44C2-A393-9DC3C7773C8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B2A6696C-288D-44C2-A393-9DC3C7773C8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B2A6696C-288D-44C2-A393-9DC3C7773C8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B2A6696C-288D-44C2-A393-9DC3C7773C8F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B2A6696C-288D-44C2-A393-9DC3C7773C8F}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B2A6696C-288D-44C2-A393-9DC3C7773C8F}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6255E6D7-7EE3-4CB9-AF6C-F75B52341294}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1DF2CDD-E6B1-4844-B3DE-0F414091E972}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{CC00B3A6-7F84-4BDA-B8C9-915723F51207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CC00B3A6-7F84-4BDA-B8C9-915723F51207}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CC00B3A6-7F84-4BDA-B8C9-915723F51207}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CC00B3A6-7F84-4BDA-B8C9-915723F51207}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CC00B3A6-7F84-4BDA-B8C9-915723F51207}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CC00B3A6-7F84-4BDA-B8C9-915723F51207}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{C7338F66-2EAF-4F0A-9306-53232DD20501}.类库d|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}.类库d|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BBF891E9-1939-4EE9-A1C7-7654ED8601E1}.类库d|Any CPU.Build.0 = Release|Any CPU
|
||||
{003E155A-8C40-41AF-A796-ED17E729E013}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{003E155A-8C40-41AF-A796-ED17E729E013}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{003E155A-8C40-41AF-A796-ED17E729E013}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{003E155A-8C40-41AF-A796-ED17E729E013}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{003E155A-8C40-41AF-A796-ED17E729E013}.类库d|Any CPU.ActiveCfg = 类库d|Any CPU
|
||||
{003E155A-8C40-41AF-A796-ED17E729E013}.类库d|Any CPU.Build.0 = 类库d|Any CPU
|
||||
{87E1ED0A-BFBF-4F5E-9FDF-5EAFE48DD719}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{87E1ED0A-BFBF-4F5E-9FDF-5EAFE48DD719}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{87E1ED0A-BFBF-4F5E-9FDF-5EAFE48DD719}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -244,19 +86,6 @@ Global
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{BBAFD33E-1CF8-4AC4-9928-337E746947A6} = {1D98D556-38A7-4ED6-ACAD-697B5E0625DE}
|
||||
{E0235FD9-93F9-44CC-A449-CB9E24E0D93B} = {1D98D556-38A7-4ED6-ACAD-697B5E0625DE}
|
||||
{79F0E685-FD16-4AE7-8DC8-3655FAA63ED2} = {1D98D556-38A7-4ED6-ACAD-697B5E0625DE}
|
||||
{F5E89FCC-BF21-4664-B7A8-0740C4D1191C} = {1D98D556-38A7-4ED6-ACAD-697B5E0625DE}
|
||||
{DB53E8D7-DFB6-48EB-A7B6-D1CF762ACB9B} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
{431F48E7-CB1B-4161-99A7-5DB4B0A975B5} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
{71FBFC1A-8EC8-4FD7-ADEB-07C56E1C9286} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
{ED65F5A2-0459-49C6-B895-A6ABFF32C8B9} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
{1278A1BC-327D-4D13-AD04-C6FF2B680530} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
{F34CFFEE-546F-490E-A76A-2792840B284D} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
{DF526631-D060-47F2-AFD4-62C6CEA2FE9A} = {2B729C46-7592-425A-87E9-D769A94881F7}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {16FB883C-167C-4E1A-B311-6D74452A3CD6}
|
||||
EndGlobalSection
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ApplicationIcon />
|
||||
<StartupObject />
|
||||
<LangVersion>9.0</LangVersion>
|
||||
|
Loading…
x
Reference in New Issue
Block a user