123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Text.RegularExpressions;
- namespace CommonLang
- {
- public static class Parser
- {
- private static HashMap<Type, ParserAdapter> mParsers = new HashMap<Type, ParserAdapter>();
- private static string FloatFormat = "F";
- static Parser()
- {
- RegistParser(new ListParser<sbyte>());
- RegistParser(new ListParser<byte>());
- RegistParser(new ListParser<short>());
- RegistParser(new ListParser<ushort>());
- RegistParser(new ListParser<int>());
- RegistParser(new ListParser<uint>());
- RegistParser(new ListParser<long>());
- RegistParser(new ListParser<ulong>());
- RegistParser(new ListParser<float>());
- RegistParser(new ListParser<double>());
- RegistParser(new ListParser<decimal>());
- RegistParser(new ListParser<char>());
- RegistParser(new ListParser<bool>());
- RegistParser(new ListParser<string>());
- RegistParser(new ListParser<object>());
- }
- public static void RegistParser(ParserAdapter parser)
- {
- mParsers.Put(parser.ParserType, parser);
- }
- public static void SetFloatFormat(string format)
- {
- FloatFormat = format;
- }
- public static bool TryConvertTo(object src, Type targetType)
- {
- object target;
- return TryConvertTo(src, targetType, out target);
- }
- public static bool TryConvertTo(object src, Type targetType, out object target)
- {
- if (targetType.IsInstanceOfType(src))
- {
- target = src;
- return true;
- }
- if (targetType.IsPrimitive && src.GetType().IsPrimitive)
- {
- try
- {
- target = Convert.ChangeType(src, targetType);
- if (targetType.IsInstanceOfType(target))
- {
- return true;
- }
- }
- catch (Exception err)
- {
- Console.WriteLine("TryConvertTo : " + src + " -> " + targetType + ", catch: " + err);
- }
- }
- target = null;
- return false;
- }
- public static bool StringToObject<T>(string text, out T ret)
- {
- Type type = typeof(T);
- try
- {
- ret = (T)StringToObject(text, type);
- return true;
- }
- catch (Exception err)
- {
- Console.WriteLine("StringToObject 1: " + text + ", catch: " + err);
- ret = default(T);
- return false;
- }
- }
- public static object StringToObject(string text, Type type)
- {
- if (String.IsNullOrEmpty(text))
- {
- return null;
- }
- ParserAdapter parser = mParsers.Get(type);
- if (parser != null)
- {
- object ret = parser.StringToObject(text);
- if (ret != null)
- {
- return ret;
- }
- }
- if (type.IsArray)
- {
- int rank = type.GetArrayRank();
- if (rank == 1)
- {
- Type subtype = type.GetElementType();
- string[] kvs = text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- Array array = Array.CreateInstance(subtype, kvs.Length);
- for (int i = 0; i < kvs.Length; i++)
- {
- object obj = StringToObject(kvs[i], subtype);
- array.SetValue(obj, i);
- }
- return array;
- }
- else if (rank == 2)
- {
- int a0 = text.IndexOf('{');
- int a1 = text.LastIndexOf('}');
- if (a0 >= 0 && a1 > a0)
- {
- Type subtype = type.GetElementType();
- Array array = null;
- string stext = text.Substring(a0 + 1, a1 - a0 - 1);
- string[] range0 = Regex.Split(stext, @"\}\s*,\s*\{");
- for (int i = 0; i < range0.Length; i++)
- {
- string[] range1 = range0[i].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- if (array == null)
- {
- array = Array.CreateInstance(subtype, range0.Length, range1.Length);
- }
- for (int j = 0; j < range1.Length; j++)
- {
- object obj = StringToObject(range1[j], subtype);
- array.SetValue(obj, i, j);
- }
- }
- return array;
- }
- }
- }
- if (type.IsEnum)
- {
- try
- {
- return Enum.Parse(type, text, true);
- }
- catch (Exception err)
- {
- Console.WriteLine("StringToObject2 : " + text + ", catch: " + err);
- return null;
- }
- }
- if (type.IsAssignableFrom(typeof(string)))
- {
- return text;
- }
- if (type.IsAssignableFrom(typeof(int)))
- {
- return int.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(uint)))
- {
- return uint.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(short)))
- {
- return short.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(ushort)))
- {
- return ushort.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(byte)))
- {
- return byte.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(sbyte)))
- {
- return sbyte.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(bool)))
- {
- return bool.Parse(text);
- }
- if (type.IsAssignableFrom(typeof(float)))
- {
- if (text == float.NaN.ToString())
- {
- return float.NaN;
- }
- return float.Parse(text, System.Globalization.CultureInfo.InvariantCulture);
- }
- if (type.IsAssignableFrom(typeof(double)))
- {
- return float.Parse(text, System.Globalization.CultureInfo.InvariantCulture);
- }
- return null;
- }
- public static string ObjectToString(object obj)
- {
- if (obj == null)
- {
- return "";
- }
- Type type = obj.GetType();
- ParserAdapter parser = mParsers.Get(type);
- if (parser != null)
- {
- string ret = parser.ObjectToString(obj);
- if (ret != null)
- {
- return ret;
- }
- }
- if (type.IsArray)
- {
- int rank = type.GetArrayRank();
- if (rank == 1)
- {
- Array array = (Array)obj;
- StringBuilder sb = new StringBuilder();
- Type subtype = type.GetElementType();
- for (int i = 0; i < array.Length; i++)
- {
- sb.Append(ObjectToString(array.GetValue(i)));
- if (i < array.Length - 1)
- {
- sb.Append(",");
- }
- }
- return sb.ToString();
- }
- else if (rank == 2)
- {
- Array array = (Array)obj;
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < array.GetLength(0); i++)
- {
- sb.Append("{");
- for (int j = 0; j < array.GetLength(1); j++)
- {
- sb.Append(ObjectToString(array.GetValue(i, j)));
- if (j < array.GetLength(1) - 1)
- {
- sb.Append(",");
- }
- }
- sb.Append("}");
- if (i < array.GetLength(0) - 1)
- {
- sb.Append(",");
- }
- }
- return sb.ToString();
- }
- }
- if (type.IsEnum)
- {
- return Enum.GetName(type, obj);
- }
- if (obj is float)
- {
- return ((float)obj).ToString(FloatFormat);
- }
- if (obj is double)
- {
- return ((double)obj).ToString(FloatFormat);
- }
- return obj + "";
- }
- public abstract class ParserAdapter
- {
- readonly public Type ParserType;
- public ParserAdapter(Type type)
- {
- this.ParserType = type;
- }
- public abstract object StringToObject(string text);
- public abstract string ObjectToString(object obj);
- }
- public class ListParser<T> : ParserAdapter
- {
- public ListParser()
- : base(typeof(List<T>))
- {
- }
- public override object StringToObject(string text)
- {
- string[] ss = text.Split(',');
- List<T> ret = null;
- if (ss.Length > 0)
- {
- ret = new List<T>();
- foreach (string s in ss)
- {
- T d = (T)Parser.StringToObject(s, typeof(T));
- ret.Add(d);
- }
- }
- return ret;
- }
- public override string ObjectToString(object obj)
- {
- List<T> list = (List<T>)obj;
- StringBuilder sb = new StringBuilder();
- int i = 0;
- foreach (T d in list)
- {
- sb.Append(ObjectToString(d));
- if (i < list.Count - 1)
- {
- sb.Append(",");
- }
- i++;
- }
- return sb.ToString();
- }
- }
- }
- }
|