using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ShootCore.Core
{
/// <summary>
/// 表格工具
/// 1.将内存或本地文件中的数据导入实例对象
/// 2.将实例对象集合中的有效数据以字符串的形式导入内存或本地文件
/// 3.有效数据包括bool int long float double string,以及他们的数组形式
/// </summary>
public class TitanTabTools
{
/// <summary>
/// 比较信息,充当有效类型筛选器
/// 我们需要通过它,将排除目标对
/// 象身上一些无法操作的数据类型
/// </summary>
private static List<ComparerInfo> gComparerQueue = null;
#region Interface
/// <summary>
/// 从文件中创建一个新表
/// </summary>
/// <param name="tab_path">文件的路径</param>
/// <returns>是否创建成功</returns>
public static bool CreateTabFromPach(string tab_path)
{
FileStream fs = new FileStream(tab_path, FileMode.Open);
if (fs != null)
{
StreamReader sw = new StreamReader(fs);
fs.Seek(0,SeekOrigin.Begin);
bool result;
string tabtxt = sw.ReadToEnd();
string tables = Path.GetFileNameWithoutExtension(fs.Name);
Console.WriteLine("FileName:{0}\nFileContent:{1}", tables, tabtxt);
result = CreateTabFromString(tables, tabtxt);
sw.Close();
fs.Close();
return result;
}
else
{
Console.WriteLine("DontFindTheFile!");
}
return false;
}
/// <summary>
/// 从字符串创建表数据
/// </summary>
/// <param name="tab_name">表的名称</param>
/// <param name="tab_content">表的内容,内容包含表头</param>
/// <returns>是否创建成功</returns>
public static bool CreateTabFromString(string tab_name, string tab_content)
{
if (string.IsNullOrEmpty(tab_name) == false && tab_content != null && tab_content.Length > 0)
{
Type table_root = null;
if ((table_root = Assembly.GetExecutingAssembly().GetType(tab_name)) != null)
{
string[] LineString = tab_content.Split(new char[]{'\n'});
if (LineString.Length > 1)
{
// 初始化比较队列信息
if (gComparerQueue == null)
{
gComparerQueue = RWCallBack.MakeComparerInfo();
}
//检查目标对象是否有静态的存储结构,没有当作失败处理
Type rootsArr = table_root.MakeArrayType();
FieldInfo store_info = table_root.GetField("Array");
if ((store_info != null && store_info.FieldType.Equals(rootsArr)) == false)
{
return false;
}
//产生所有读写的数据成员信息,放入allRW列表内
List<RWBase> allRW = new List<RWBase>();
if (MakeAllRW(ref allRW, table_root))
{
//继续进行的开关,假如我们没有一个匹配成功的属性,那么就没有必要继续写入操作了
bool goon = false;
//取出表头数据,该数据应该和目标存储的变量名称一一对应
//为了考虑效率没有使用链表,我们使用数组将RWBase和property进行绑定
string[] propertys = LineString[0].Split(new char[] { '\t' });
RWBase[] bindProps = new RWBase[propertys.Length];
for(int i = 0, max = propertys.Length; i < max; ++i)
{
foreach (var val in allRW)
{
if (val.GetName() == propertys[i])
{
goon = true;
bindProps[i] = val;
break;
}
}
}
if (goon)
{
//初始数组的最大值
int CountMax = LineString.Length - 1;
//列分隔符
char[] splitArr = new char[] { '\t' };
//创建一个数组储存器,大小由CountMax指定
object[] dataArr = (object[])System.Activator.CreateInstance(rootsArr, CountMax);
//使用的数据实例个数
int numbInstance = 0;
//当前操作的实例对象
object curInstance = null;
//遍历写入剩余的内容
for (int i = 1, max = LineString.Length; i < max; ++i)
{
//分割并筛选有效数据,默认与表头单元不等的数据行为无效数据
string[] group = LineString[i].Split(splitArr);
if (group.Length != propertys.Length) continue;
//创建并向目标身上写入数据
curInstance = System.Activator.CreateInstance(table_root);
for (int n = 0, n_max = group.Length; n < n_max; ++n)
{
if (bindProps[n] != null)
{
bindProps[n].SetValue(curInstance, group[n]);
}
}
dataArr[numbInstance++] = curInstance;
}
//最后的矫正,没有任何数据成员将返回false
//若有数据成员,我们会取数量最小的数据集,然后填充给目标的Array变量
if (numbInstance > 0 && numbInstance != CountMax)
{
object[] final = (object[])System.Activator.CreateInstance(rootsArr, numbInstance);
Array.Copy(dataArr,final,final.Length);
store_info.SetValue(null,final);
return true;
}
}
}
}
}
}
return false;
}
/// <summary>
/// 保存表数据到指定路径文件下
/// </summary>
/// <param name="abs_url">文件路径</param>
/// <param name="table">数据集合</param>
/// <returns>是否成功</returns>
public static bool SaveTabToPath(string abs_url, List<Object> table)
{
string out_val = "";
string out_tab = "";
if (SaveTabToString(out out_val,out out_tab, table))
{
//> 创建保存文件
FileStream fs = new FileStream(string.Format("{0}/{1}.txt",abs_url,out_tab),FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
fs.Seek(0,SeekOrigin.Begin);
sw.Write(out_val);
sw.Close();
fs.Close();
return true;
}
return false;
}
/// <summary>
/// 保存表为字符串 :如果该数据集没有有效数据那么将会导出失败
/// </summary>
/// <param name="out_str">输出的字符串结果</param>
/// <param name="table">要导出的数据源</param>
/// <returns>是否导出成功</returns>
public static bool SaveTabToString(out string out_str,out string table_name,List<Object> table)
{
out_str = "";
table_name = "";
if (table.Count > 0)
{
//是否开始写表头
bool wfh = true;
if (gComparerQueue == null)
{
gComparerQueue = RWCallBack.MakeComparerInfo();
}
List<RWBase> allInfos = new List<RWBase>();
Object item = null;
//循环遍历数据集合,并将每个数据集合打包成一个由'\t'分割
//单元数据,结尾带有'\n'的字符串
for (int i = 0, max = table.Count; i < max; ++i)
{
item = table[i];
//只导出有对象
if (item != null)
{
//先写表头,并且表头只写一次
if (wfh)
{
wfh = false;
table_name = item.GetType().Name;
if ( MakeAllRW(ref allInfos,item.GetType() ) )
{
WriteFileFieldGetString(ref out_str, null, allInfos);
}
else
{
return false;
}
}
//将传入的item内部的数据打包成字符串
WriteFileFieldGetString(ref out_str, item, allInfos);
}
}
return true;
}
return false;
}
#endregion
#region Support
/// <summary>
/// 根据类型产生所有有效数据的读写信息
/// </summary>
/// <param name="allInfos">读写信息队列</param>
/// <param name="type">目标类型</param>
/// <returns>是否成功</returns>
private static bool MakeAllRW(ref List<RWBase> allInfos, Type type)
{
FieldInfo[] allField = type.GetFields();
PropertyInfo[] allProperty = type.GetProperties();
RWBase rwItem = null;
foreach (var val in allField)
{
if (false == val.IsStatic && (rwItem = MakeRWBase(val, null)) != null)
{
allInfos.Add(rwItem);
}
}
foreach (var val in allProperty)
{
if ((rwItem = MakeRWBase(null, val)) != null)
{
allInfos.Add(rwItem);
}
}
return allInfos.Count > 0;
}
/// <summary>
/// 根据变量或字段产生一个与之对应的读写信息对象
/// </summary>
/// <param name="field">变量信息</param>
/// <param name="property">字段信息</param>
/// <returns>是否成功</returns>
private static RWBase MakeRWBase(FieldInfo field,PropertyInfo property)
{
if (field != null)
{
ComparerInfo info = ComparerTypeWithQueue(field.FieldType);
if (info != null)
{
RWField rwf = new RWField();
rwf.SetFieldInfo(field);
rwf.SetReadCallBack(info.HowRead);
rwf.SetWriteCallBack(info.HowWrite);
return rwf;
}
}
else if (property != null)
{
ComparerInfo info = ComparerTypeWithQueue(property.PropertyType);
if (info != null)
{
RWProperty rwp = new RWProperty();
rwp.SetPropertyInfo(property);
rwp.SetReadCallBack(info.HowRead);
rwp.SetWriteCallBack(info.HowWrite);
return rwp;
}
}
return null;
}
/// <summary>
/// 将传入类型和可用数据类型队列做比较
/// 并返回比较结果,返回空表示此匹配失败
/// </summary>
/// <param name="type">需要比较的数据类型</param>
/// <returns>返回与之对应比较信息对象</returns>
private static ComparerInfo ComparerTypeWithQueue(Type type)
{
if (gComparerQueue != null)
{
foreach (var val in gComparerQueue)
{
if (val.BaseType.Equals(type))
{
return val;
}
}
}
return null;
}
/// <summary>
/// 将属性打包成字符串
/// </summary>
/// <param name="out_str">输出的字符串结果,形式为累加</param>
/// <param name="item">操作对象,如果为空默认写入表头</param>
/// <param name="allInfo">选定的数据类型读写对象</param>
private static void WriteFileFieldGetString(ref string out_str,Object item,List<RWBase> allInfo)
{
if (allInfo.Count > 0)
{
if (null == item)
{
out_str += allInfo[0].GetName();
for (int i = 1, max = allInfo.Count; i < max; ++i)
{
out_str += '\t' + allInfo[i].GetName();
}
out_str += '\n';
}
else
{
out_str += allInfo[0].GetValue(item);
for (int i = 1, max = allInfo.Count; i < max; ++i)
{
out_str += '\t' + allInfo[i].GetValue(item);
}
out_str += '\n';
}
}
}
#endregion
#region Can Extend
#endregion
}
}