예제 #1
0
        private object DeserializeObject(Type targetType)
        {
            object result;

            if (targetType == typeof(string))
            {
                result = Activator.CreateInstance(targetType, '\0', 0);
            }
            else
            {
                result = Activator.CreateInstance(targetType);
            }

            if (targetType.IsGenericType &&
                SlimTypeInfo.DicTypes.Contains(targetType.Name))
            {
                //dic
                var tinfo = SlimTypeInfo.GetOrAddInstance(targetType);

                result = tinfo.Instance;
                foreach (var item in xml.Elements())
                {
                    if (item.Attribute("item") != null)
                    {
                        var keyStr = item.Attribute("item").Value;
                        var valStr = item.Value;

                        var key = Convert.ChangeType(keyStr, tinfo.ArgTypes[0]);
                        var val = DeserializeValue(item, tinfo.ArgTypes[1]);

                        tinfo.MethodInfo.Invoke(result, new object[] { key, val });
                    }
                    else
                    {
                        var key = Convert.ChangeType(item.Name.LocalName, tinfo.ArgTypes[0]);
                        var val = DeserializeValue(item, tinfo.ArgTypes[1]);

                        tinfo.MethodInfo.Invoke(result, new object[] { key, val });
                    }
                }
            }
            else
            {
                var dict = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                           .Where(p => p.CanWrite)
                           .ToDictionary(pi => pi.Name, pi => pi);
                foreach (var item in xml.Elements())
                {
                    PropertyInfo propertyInfo;
                    if (!dict.TryGetValue(item.Name.LocalName, out propertyInfo))
                    {
                        continue;
                    }
                    var value = DeserializeValue(item, propertyInfo.PropertyType);
                    propertyInfo.SetValue(result, value, null);
                }
            }

            return(result);
        }
예제 #2
0
        private object DeserializeArray(Type targetType)
        {
            if (targetType.IsArray) // Foo[]
            {
                var     elemType = targetType.GetElementType();
                dynamic array    = Array.CreateInstance(elemType, xml.Elements().Count());
                var     index    = 0;
                foreach (var item in xml.Elements())
                {
                    array[index++] = DeserializeValue(item, elemType);
                }
                return(array);
            }
            else if (targetType.IsGenericType &&
                     SlimTypeInfo.DicTypes.Contains(targetType.Name))
            {
                //dic
                var tinfo = SlimTypeInfo.GetOrAddInstance(targetType);

                var dic = tinfo.Instance;
                foreach (var item in xml.Elements())
                {
                    var kv  = item.Elements().ToArray();
                    var key = DeserializeValue(kv[0], tinfo.ArgTypes[0]);
                    var val = DeserializeValue(kv[1], tinfo.ArgTypes[1]);

                    tinfo.MethodInfo.Invoke(dic, new object[] { key, val });
                }

                return(dic);
            }
            else if (targetType.IsGenericType &&
                     SlimTypeInfo.ListTypes.Contains(targetType.Name))
            {
                //list
                var tinfo = SlimTypeInfo.GetOrAddInstance(targetType);

                var list = tinfo.Instance;
                foreach (var item in xml.Elements())
                {
                    var val = DeserializeValue(item, tinfo.ArgTypes[0]);

                    tinfo.MethodInfo.Invoke(list, new object[] { val });
                }

                return(list);
            }
            else // List<Foo>
            {
                var     elemType = targetType.GetGenericArguments()[0];
                dynamic list     = Activator.CreateInstance(targetType);
                foreach (var item in xml.Elements())
                {
                    list.Add(DeserializeValue(item, elemType));
                }
                return(list);
            }
        }
예제 #3
0
        private static object DeserializeList(Type type, byte[] datas)
        {
            var info = SlimTypeInfo.GetOrAddInstance(type);

            var instance = info.Instance;

            if (info.ArgTypes[0].IsClass && info.ArgTypes[0] != typeof(string))
            {
                //子项内容
                var slen    = 0;
                var soffset = 0;
                while (soffset < datas.Length)
                {
                    slen = BitConverter.ToInt32(datas, soffset);
                    if (slen > 0)
                    {
                        var sobj = Deserialize(info.ArgTypes[0], datas, ref soffset);
                        if (sobj != null)
                        {
                            info.MethodInfo.Invoke(instance, new object[] { sobj });
                        }
                    }
                    else
                    {
                        info.MethodInfo.Invoke(instance, null);
                    }
                }
                return(instance);
            }
            else
            {
                //子项内容
                var slen    = 0;
                var soffset = 0;
                while (soffset < datas.Length)
                {
                    var len  = BitConverter.ToInt32(datas, soffset);
                    var data = new byte[len];
                    Buffer.BlockCopy(datas, soffset + 4, data, 0, len);
                    soffset += 4;
                    slen     = BitConverter.ToInt32(datas, soffset);
                    if (slen > 0)
                    {
                        var sobj = Deserialize(info.ArgTypes[0], datas, ref soffset);
                        if (sobj != null)
                        {
                            info.MethodInfo.Invoke(instance, new object[] { sobj });
                        }
                    }
                    else
                    {
                        info.MethodInfo.Invoke(instance, null);
                    }
                }
                return(instance);
            }
        }
예제 #4
0
        private static object DeserializeDic(Type type, byte[] datas)
        {
            var tinfo = SlimTypeInfo.GetOrAddInstance(type);

            var instance = tinfo.Instance;

            //子项内容
            var slen = 0;

            var soffset = 0;

            int m = 1;

            object key = null;
            object val = null;

            while (soffset < datas.Length)
            {
                slen = BitConverter.ToInt32(datas, soffset);
                var sdata = new byte[slen + 4];
                Buffer.BlockCopy(datas, soffset, sdata, 0, slen + 4);
                soffset += slen + 4;
                if (m % 2 == 1)
                {
                    object v = null;
                    if (slen > 0)
                    {
                        int lloffset = 0;
                        var sobj     = Deserialize(tinfo.ArgTypes[0], sdata, ref lloffset);
                        if (sobj != null)
                        {
                            v = sobj;
                        }
                    }
                    key = v;
                }
                else
                {
                    object v = null;
                    if (slen > 0)
                    {
                        int lloffset = 0;
                        var sobj     = Deserialize(tinfo.ArgTypes[1], sdata, ref lloffset);
                        if (sobj != null)
                        {
                            v = sobj;
                        }
                    }
                    val = v;
                    tinfo.MethodInfo.Invoke(instance, new object[] { key, val });
                }
                m++;
            }
            return(instance);
        }
예제 #5
0
        private static object DeserializeClass(Type type, byte[] datas)
        {
            var tinfo = SlimTypeInfo.GetOrAddInstance(type);

            var instance = tinfo.Instance;

            var ts = new List <Type>();

            //var ps = type.GetProperties();
            var fs = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            ApplyPropertySerializable(fs, type);
            foreach (var field in fs)
            {
                if (field != null)
                {
                    ts.Add(field.FieldType);
                }
            }

            var vas = Deserialize(ts.ToArray(), datas);

            var fsWithoutNull = fs.Where(f => f != null).ToArray();

            for (int j = 0; j < fsWithoutNull.Length; j++)
            {
                try
                {
                    if (!fsWithoutNull[j].FieldType.IsGenericType)
                    {
                        fsWithoutNull[j].SetValue(instance, vas[j]);
                    }
                    else
                    {
                        Type genericTypeDefinition = fsWithoutNull[j].FieldType.GetGenericTypeDefinition();
                        if (genericTypeDefinition == typeof(Nullable <>))
                        {
                            fsWithoutNull[j].SetValue(instance, Convert.ChangeType(vas[j], Nullable.GetUnderlyingType(fsWithoutNull[j].FieldType)));
                        }
                        else
                        {
                            fsWithoutNull[j].SetValue(instance, vas[j]);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new NotImplementedException("未定义的类型:" + type.ToString(), ex);
                }
            }

            return(instance);
        }
예제 #6
0
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="type"></param>
        /// <param name="datas"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        private static object Deserialize(Type type, byte[] datas, ref int offset)
        {
            dynamic obj = null;

            var len = 0;

            byte[] data = null;

            len     = BitConverter.ToInt32(datas, offset);
            offset += 4;
            if (len > 0)
            {
                data = new byte[len];
                Buffer.BlockCopy(datas, offset, data, 0, len);
                offset += len;

                if (type.IsObject())
                {
                    var    lenTypeName  = BitConverter.ToInt32(data, 0) + 4;
                    byte[] dataTypeName = new byte[lenTypeName];
                    Buffer.BlockCopy(data, 0, dataTypeName, 0, lenTypeName);
                    var realTypeName = (string)Deserialize(typeof(string).AssemblyQualifiedName, dataTypeName);

                    //将获得的类型赋值后处理真正的数据
                    type = Type.GetType(realTypeName);
                    var srcData = data;
                    len  = BitConverter.ToInt32(data, lenTypeName);
                    data = new byte[len];
                    Buffer.BlockCopy(srcData, lenTypeName + 4, data, 0, len);
                }

                if (type == typeof(string))
                {
                    obj = Encoding.UTF8.GetString(data);
                }
                else if (type == typeof(byte))
                {
                    obj = data[0];
                }
                else if (type == typeof(bool))
                {
                    obj = (BitConverter.ToBoolean(data, 0));
                }
                else if (type == typeof(short))
                {
                    obj = (BitConverter.ToInt16(data, 0));
                }
                else if (type == typeof(int))
                {
                    obj = (BitConverter.ToInt32(data, 0));
                }
                else if (type == typeof(long))
                {
                    obj = (BitConverter.ToInt64(data, 0));
                }
                else if (type == typeof(float))
                {
                    obj = (BitConverter.ToSingle(data, 0));
                }
                else if (type == typeof(double))
                {
                    obj = (BitConverter.ToDouble(data, 0));
                }
                else if (type == typeof(decimal))
                {
                    var dstr = Encoding.UTF8.GetString(data);

                    obj = decimal.Parse(dstr);;
                }
                else if (type == typeof(DateTime))
                {
                    var dstr  = Encoding.UTF8.GetString(data);
                    var ticks = long.Parse(dstr);
                    obj = (new DateTime(ticks));
                }
                else if (type == typeof(Guid))
                {
                    var dstr = Encoding.UTF8.GetString(data);
                    obj = Guid.Parse(dstr);
                }
                else if (type == typeof(Type))
                {
                    var dstr = Encoding.UTF8.GetString(data);
                    obj = Type.GetType(dstr);
                }
                else if (type.BaseType == typeof(Enum))
                {
                    var numType = Enum.GetUnderlyingType(type);

                    if (numType == typeof(byte))
                    {
                        obj = Enum.ToObject(type, data[0]);
                    }
                    else if (numType == typeof(short))
                    {
                        obj = Enum.ToObject(type, BitConverter.ToInt16(data, 0));
                    }
                    else if (numType == typeof(int))
                    {
                        obj = Enum.ToObject(type, BitConverter.ToInt32(data, 0));
                    }
                    else
                    {
                        obj = Enum.ToObject(type, BitConverter.ToInt64(data, 0));
                    }
                }
                else if (type == typeof(byte[]))
                {
                    obj = (byte[])data;
                }
                else if (type.IsGenericType)
                {
                    if (SlimTypeInfo.ListTypes.Contains(type.Name))
                    {
                        obj = DeserializeList(type, data);
                    }
                    else if (SlimTypeInfo.DicTypes.Contains(type.Name))
                    {
                        obj = DeserializeDic(type, data);
                    }
                    else
                    {
                        obj = DeserializeClass(type, data);
                    }
                }
                else if (type.IsArray)
                {
                    obj = DeserializeArray(type, data);
                }
                else if (type.IsClass)
                {
                    obj = DeserializeClass(type, data);
                }
                else
                {
                    throw new NotImplementedException("未定义的类型:" + type.ToString());
                }
            }
            else
            {
                var tinfo = SlimTypeInfo.GetOrAddInstance(type);
                obj = tinfo.Instance;
            }

            return(obj);
        }