using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using CYQ.Data.Table;
using CYQ.Data.Tool;
namespace CYQ.Data.Json
{
///
/// 分隔Json字符串为字典集合。
///
internal partial class JsonSplit
{
internal static bool IsJson(string json)
{
return IsJson(json, false);
}
internal static bool IsJson(string json, bool isStrictMode)
{
int errIndex;
return IsJson(json, isStrictMode, out errIndex);
}
internal static bool IsJson(string json, bool isStrictMode, out int errIndex)
{
errIndex = 0;
if (string.IsNullOrEmpty(json) || json.Length < 2 ||
((json[0] != '{' && json[json.Length - 1] != '}') && (json[0] != '[' && json[json.Length - 1] != ']')))
{
return false;
}
CharState cs = new CharState(isStrictMode);
for (int i = 0; i < json.Length; i++)
{
//char c = ;
if (cs.IsKeyword(json[i]) && cs.childrenStart)//设置关键符号状态。
{
int err;
int length = GetValueLength(isStrictMode, json, i, true, out err);
cs.childrenStart = false;
if (err > 0)
{
errIndex = i + err;
return false;
}
i = i + length - 1;
}
if (cs.isError)
{
errIndex = i;
return false;
}
}
return !cs.arrayStart && !cs.jsonStart; //只要不是正常关闭,则失败
}
internal static List> Split(string json)
{
return Split(json, 0);
}
/////
///// 解析Json
/////
/////
//internal static List> Split(string json, int topN)
//{
// List> result = new List>();
// if (!string.IsNullOrEmpty(json))
// {
// Dictionary dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase);
// int keyIndex = -1, valueIndex = -1;
// int keyLength = 0, valueLength = 0;
// CharState cs = new CharState(false);
// try
// {
// #region 核心逻辑
// for (int i = 0; i < json.Length; i++)
// {
// char c = json[i];
// if (!cs.IsKeyword(c))//设置关键符号状态。
// {
// if (cs.jsonStart)//Json进行中。。。
// {
// if (cs.keyStart > 0)
// {
// if (keyIndex == -1)
// {
// keyIndex = i;
// }
// keyLength++;
// }
// else if (cs.valueStart > 0)
// {
// if (valueIndex == -1)
// {
// valueIndex = i;
// }
// valueLength++;
// }
// }
// else if (!cs.arrayStart)//json结束,又不是数组,则退出。
// {
// break;
// }
// }
// else if (cs.childrenStart)//正常字符,值状态下。
// {
// int temp;
// valueLength = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍
// valueIndex = i;
// cs.childrenStart = false;
// cs.valueStart = 0;
// cs.setDicValue = true;
// i = i + valueLength - 1;
// }
// if (cs.setDicValue)//设置键值对。
// {
// if (keyLength > 0)
// {
// string k = json.Substring(keyIndex, keyLength);// key.ToString();
// if (!dic.ContainsKey(k))
// {
// string val = valueLength > 0 ? json.Substring(valueIndex, valueLength) : ""; //value.ToString();
// bool isNull = json[i - 5] == ':' && json[i] != '"' && valueLength == 4 && val == "null";
// if (isNull)
// {
// val = "";
// }
// dic.Add(k, val);
// }
// }
// cs.setDicValue = false;
// keyIndex = valueIndex = -1;
// keyLength = valueLength = 0;
// }
// if (!cs.jsonStart && dic.Count > 0)
// {
// result.Add(dic);
// if (topN > 0 && result.Count >= topN)
// {
// return result;
// }
// if (cs.arrayStart)//处理数组。
// {
// dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase);
// }
// }
// }
// #endregion
// }
// catch (Exception err)
// {
// Log.Write(err, LogType.Error);
// }
// }
// return result;
//}
///
/// 解析Json
///
///
internal static List> Split(string json, int topN)
{
List> result = new List>();
if (!string.IsNullOrEmpty(json))
{
Dictionary dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase);
//string key = string.Empty;
StringBuilder key = new StringBuilder(32);
StringBuilder value = new StringBuilder();
CharState cs = new CharState(false);
try
{
#region 核心逻辑
for (int i = 0; i < json.Length; i++)
{
char c = json[i];
if (!cs.IsKeyword(c))//设置关键符号状态。
{
if (cs.jsonStart)//Json进行中。。。
{
if (cs.keyStart > 0)
{
key.Append(c);
}
else if (cs.valueStart > 0)
{
value.Append(c);
}
}
else if (!cs.arrayStart)//json结束,又不是数组,则退出。
{
break;
}
}
else if (cs.childrenStart)//正常字符,值状态下。
{
//string item = json.Substring(i);
int temp;
// int length = GetValueLength(false, json.Substring(i), false, out temp);//这里应该有优化的空间,传json和i,不重新生成string
int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍
value.Length = 0;
value.Append(json.Substring(i, length));
cs.childrenStart = false;
cs.valueStart = 0;
//cs.state = 0;
cs.setDicValue = true;
i = i + length - 1;
}
if (cs.setDicValue)//设置键值对。
{
if (key.Length > 0)
{
string k = key.ToString();
if (!dic.ContainsKey(k))
{
string val = value.ToString();
bool isNull = i > 4 && json[i - 5] == ':' && json[i] != '"' && value.Length == 4 && val == "null";
if (isNull)
{
val = "";
}
dic.Add(k, val);
}
}
cs.setDicValue = false;
key.Length = 0;
value.Length = 0;
}
if (!cs.jsonStart && dic.Count > 0)
{
result.Add(dic);
if (topN > 0 && result.Count >= topN)
{
return result;
}
if (cs.arrayStart)//处理数组。
{
dic = new Dictionary(16, StringComparer.OrdinalIgnoreCase);
}
}
}
#endregion
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
finally
{
key = null;
value = null;
}
}
return result;
}
/*
///
/// 获取值的长度(当Json值嵌套以"{"或"["开头时)
///
private static int GetValueLength(bool isStrictMode, string json, bool breakOnErr, out int errIndex)
{
errIndex = 0;
int len = json.Length - 1;
if (!string.IsNullOrEmpty(json))
{
CharState cs = new CharState(isStrictMode);
char c;
for (int i = 0; i < json.Length; i++)
{
c = json[i];
if (!cs.IsKeyword(c))//设置关键符号状态。
{
if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。
{
break;
}
}
else if (cs.childrenStart)//正常字符,值状态下。
{
int length = GetValueLength(isStrictMode, json.Substring(i), breakOnErr, out errIndex);//递归子值,返回一个长度。。。
cs.childrenStart = false;
cs.valueStart = 0;
//cs.state = 0;
i = i + length - 1;
}
if (breakOnErr && cs.isError)
{
errIndex = i;
return i;
}
if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。
{
len = i + 1;//长度比索引+1
break;
}
}
}
return len;
}
*/
///
/// 获取值的长度(当Json值嵌套以"{"或"["开头时),【优化后】
///
private static int GetValueLength(bool isStrictMode, string json, int startIndex, bool breakOnErr, out int errIndex)
{
errIndex = 0;
int len = json.Length - 1 - startIndex;
if (!string.IsNullOrEmpty(json))
{
CharState cs = new CharState(isStrictMode);
char c;
for (int i = startIndex; i < json.Length; i++)
{
c = json[i];
if (!cs.IsKeyword(c))//设置关键符号状态。
{
if (!cs.jsonStart && !cs.arrayStart)//json结束,又不是数组,则退出。
{
break;
}
}
else if (cs.childrenStart)//正常字符,值状态下。
{
int length = GetValueLength(isStrictMode, json, i, breakOnErr, out errIndex);//递归子值,返回一个长度。。。
cs.childrenStart = false;
cs.valueStart = 0;
i = i + length - 1;
}
if (breakOnErr && cs.isError)
{
errIndex = i;
return i - startIndex;
}
if (!cs.jsonStart && !cs.arrayStart)//记录当前结束位置。
{
len = i + 1;//长度比索引+1
len = len - startIndex;
break;
}
}
}
return len;
}
#region 扩展转实体T
internal static T ToEntity(string json, EscapeOp op)
{
List t = ToList(json, 0, op);
if (t.Count > 0)
{
return t[0];
}
return default(T);
}
internal static List ToList(string json, int topN, EscapeOp op)
{
Type t = typeof(T);
if (t.IsValueType || t.Name == "String")
{
return new MDataRow().GetObj(typeof(List), json) as List;
}
List result = new List();
if (!string.IsNullOrEmpty(json) && json.Length > 4)
{
// object entity = Activator.CreateInstance(t);
T entity = Activator.CreateInstance();
bool hasSetValue = false;
List pInfoList = ReflectTool.GetPropertyList(t);
List fInfoList = ReflectTool.GetFieldList(t);
//string key = string.Empty;
StringBuilder key = new StringBuilder(32);
StringBuilder value = new StringBuilder();
CharState cs = new CharState(false);
try
{
#region 核心逻辑
char c;
for (int i = 0; i < json.Length; i++)
{
c = json[i];
if (!cs.IsKeyword(c))//设置关键符号状态。
{
if (cs.jsonStart)//Json进行中。。。
{
if (cs.keyStart > 0)
{
key.Append(c);
}
else if (cs.valueStart > 0)
{
value.Append(c);
}
}
else if (!cs.arrayStart)//json结束,又不是数组,则退出。
{
break;
}
}
else if (cs.childrenStart)//正常字符,值状态下。
{
int temp;
int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍
value.Length = 0;
value.Append(json.Substring(i, length));
cs.childrenStart = false;
cs.valueStart = 0;
cs.setDicValue = true;
i = i + length - 1;
}
if (cs.setDicValue)//设置键值对。
{
if (key.Length > 0)
{
string k = key.ToString();
string val = value.ToString();//.TrimEnd('\r', '\n', '\t');
bool isNull = i > 4 && json[i - 5] == ':' && json[i] != '"' && val.Length == 4 && val == "null";
if (isNull)
{
val = "";
}
else
{
val = JsonHelper.UnEscape(val, op);
}
bool hasProperty = false;
object o = val;
foreach (PropertyInfo p in pInfoList)
{
if (String.Compare(p.Name, k, StringComparison.OrdinalIgnoreCase) == 0)
{
hasProperty = true;
if (p.CanWrite)
{
if (p.PropertyType.Name != "String")
{
o = ConvertTool.ChangeType(val, p.PropertyType);
}
p.SetValue(entity, o, null);
hasSetValue = true;
}
break;
}
}
if (!hasProperty && fInfoList.Count > 0)
{
foreach (FieldInfo f in fInfoList)
{
if (String.Compare(f.Name, k, StringComparison.OrdinalIgnoreCase) == 0)
{
if (f.FieldType.Name != "String")
{
o = ConvertTool.ChangeType(val, f.FieldType);
}
f.SetValue(entity, o);
hasSetValue = true;
break;
}
}
}
}
cs.setDicValue = false;
key.Length = 0;
value.Length = 0;
}
if (!cs.jsonStart && hasSetValue)
{
result.Add(entity);
if (topN > 0 && result.Count >= topN)
{
return result;
}
if (cs.arrayStart)//处理数组。
{
entity = Activator.CreateInstance();
hasSetValue = false;
}
}
}
#endregion
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
finally
{
key = null;
value = null;
}
}
return result;
}
///
/// 支持转换:实体或实体列表二合一
///
internal static object ToEntityOrList(Type t, string json, EscapeOp op)
{
Type toType = t;
object listObj = null;
MethodInfo method = null;
if (t.IsGenericType && (t.Name.StartsWith("List") || t.Name.StartsWith("IList") || t.Name.StartsWith("MList")))
{
Type[] paraTypeList = null;
ReflectTool.GetArgumentLength(ref t, out paraTypeList);
toType = paraTypeList[0];
if (toType.IsValueType || toType.Name == "String")
{
return new MDataRow().GetObj(t, json);
}
listObj = Activator.CreateInstance(t);//创建实例
method = t.GetMethod("Add");
}
if (!string.IsNullOrEmpty(json))
{
object entity = Activator.CreateInstance(toType);
bool hasSetValue = false;
List pInfoList = ReflectTool.GetPropertyList(toType);
List fInfoList = ReflectTool.GetFieldList(toType);
//string key = string.Empty;
StringBuilder key = new StringBuilder(32);
StringBuilder value = new StringBuilder();
CharState cs = new CharState(false);
try
{
#region 核心逻辑
char c;
for (int i = 0; i < json.Length; i++)
{
c = json[i];
if (!cs.IsKeyword(c))//设置关键符号状态。
{
if (cs.jsonStart)//Json进行中。。。
{
if (cs.keyStart > 0)
{
key.Append(c);
}
else if (cs.valueStart > 0)
{
value.Append(c);
}
}
else if (!cs.arrayStart)//json结束,又不是数组,则退出。
{
break;
}
}
else if (cs.childrenStart)//正常字符,值状态下。
{
int temp;
int length = GetValueLength(false, json, i, false, out temp);//优化后,速度快了10倍
value.Length = 0;
value.Append(json.Substring(i, length));
cs.childrenStart = false;
cs.valueStart = 0;
cs.setDicValue = true;
i = i + length - 1;
}
if (cs.setDicValue)//设置键值对。
{
if (key.Length > 0)
{
string k = key.ToString();
string val = value.ToString();//.TrimEnd('\r', '\n', '\t');
bool isNull = i > 4 && json[i - 5] == ':' && json[i] != '"' && val.Length == 4 && val == "null";
if (isNull)
{
val = "";
}
else
{
val = JsonHelper.UnEscape(val, op);
}
bool hasProperty = false;
object o = val;
foreach (PropertyInfo p in pInfoList)
{
if (String.Compare(p.Name, k, StringComparison.OrdinalIgnoreCase) == 0)
{
hasProperty = true;
if (p.CanWrite)
{
if (p.PropertyType.Name != "String")
{
o = ConvertTool.ChangeType(val, p.PropertyType);
}
p.SetValue(entity, o, null);
hasSetValue = true;
}
break;
}
}
if (!hasProperty && fInfoList.Count > 0)
{
foreach (FieldInfo f in fInfoList)
{
if (String.Compare(f.Name, k, StringComparison.OrdinalIgnoreCase) == 0)
{
if (f.FieldType.Name != "String")
{
o = ConvertTool.ChangeType(val, f.FieldType);
}
f.SetValue(entity, o);
hasSetValue = true;
break;
}
}
}
}
cs.setDicValue = false;
key.Length = 0;
value.Length = 0;
}
if (!cs.jsonStart && hasSetValue)
{
if (method != null)
{
method.Invoke(listObj, new object[] { entity });
}
else
{
return entity;
}
if (cs.arrayStart)//处理数组。
{
entity = Activator.CreateInstance(toType);
hasSetValue = false;
}
}
}
#endregion
}
catch (Exception err)
{
Log.Write(err, LogType.Error);
}
finally
{
key = null;
value = null;
}
}
return listObj;
}
#endregion
}
internal partial class JsonSplit
{
///
/// 将json数组分成字符串List
///
/// ["a,","bbb,,"]
///
internal static List SplitEscapeArray(string jsonArray)
{
if (!string.IsNullOrEmpty(jsonArray))
{
jsonArray = jsonArray.Trim(' ', '[', ']');//["a,","bbb,,"]
List list = new List();
if (jsonArray.Length > 0)
{
string[] items = jsonArray.Split(',');
string objStr = string.Empty;
foreach (string value in items)
{
string item = value.Trim('\r', '\n', '\t', ' ');
if (objStr == string.Empty)
{
objStr = item;
}
else
{
objStr += "," + item;
}
char firstChar = objStr[0];
if (firstChar == '"' || firstChar == '\'')
{
//检测双引号的数量
if (GetCharCount(objStr, firstChar) % 2 == 0)//引号成双
{
list.Add(objStr.Trim(firstChar).Replace("\\" + firstChar, firstChar.ToString()));
objStr = string.Empty;
}
}
else
{
list.Add(item);
objStr = string.Empty;
}
}
}
return list;
}
return null;
}
///
/// 获取字符在字符串出现的次数
///
///
///
private static int GetCharCount(string item, char c)
{
int num = 0;
for (int i = 0; i < item.Length; i++)
{
if (item[i] == '\\')
{
i++;
}
else if (item[i] == c)
{
num++;
}
}
return num;
}
}
}