Beispiel #1
0
        /// <summary>
        /// 尝试读取目标对象指定成员的值,处理基础类型、特殊类型、基础类型数组、特殊类型数组,通过委托方法处理成员
        /// </summary>
        /// <remarks>
        /// 简单类型在value中返回,复杂类型直接填充target;
        /// </remarks>
        /// <param name="reader">读取器</param>
        /// <param name="target">目标对象</param>
        /// <param name="member">成员</param>
        /// <param name="type">成员类型,以哪一种类型读取</param>
        /// <param name="encodeInt">是否编码整数</param>
        /// <param name="allowNull">是否允许空</param>
        /// <param name="isProperty">是否处理属性</param>
        /// <param name="value">成员值</param>
        /// <param name="callback">处理成员的方法</param>
        /// <returns>是否读取成功</returns>
        protected virtual Boolean ReadMember(BinaryReaderX reader, Object target, MemberInfoX member, Type type, Boolean encodeInt, Boolean allowNull, Boolean isProperty, out Object value, BinaryReaderX.ReadCallback callback)
        {
            if (type == null) type = member.Type;

            // 接口支持
            if (typeof(IBinaryAccessor).IsAssignableFrom(type))
            {
                // 读取对象
                value = member.GetValue(target);

                // 实例化对象
                if (value == null)
                {
                    //value = Activator.CreateInstance(member.Type);
                    value = CreateInstance(type);
                    //member.SetValue(target, value);
                }
                if (value == null) return false;

                // 调用接口
                IBinaryAccessor accessor = value as IBinaryAccessor;
                accessor.Read(reader);

                return true;
            }

            return reader.TryReadObject(target, member, type, encodeInt, true, isProperty, out value, callback);
        }
Beispiel #2
0
        /// <summary>
        /// 尝试读取枚举
        /// </summary>
        /// <remarks>重点和难点在于如果得知枚举元素类型,这里假设所有元素类型一致,否则实在无法处理</remarks>
        /// <param name="target">目标对象</param>
        /// <param name="member">成员</param>
        /// <param name="encodeInt">是否编码整数</param>
        /// <param name="allowNull">是否允许空</param>
        /// <param name="isProperty">是否处理属性</param>
        /// <param name="value">成员值</param>
        /// <param name="callback">处理成员的方法</param>
        /// <returns>是否读取成功</returns>
        public Boolean TryReadEnumerable(Object target, MemberInfoX member, Boolean encodeInt, Boolean allowNull, Boolean isProperty, out Object value, ReadCallback callback)
        {
            value = null;
            if (member == null || !typeof(IEnumerable).IsAssignableFrom(member.Type)) return false;

            //// 尝试计算元素类型,通过成员的第一个元素。这个办法实在丑陋,不仅要给成员赋值,还要加一个元素
            //Type elmType = null;
            //if (target != null && !member.IsType)
            //{
            //    IEnumerable en = member.GetValue(target) as IEnumerable;
            //    if (en != null)
            //    {
            //        foreach (Object item in en)
            //        {
            //            if (item != null)
            //            {
            //                elmType = item.GetType();
            //                break;
            //            }
            //        }
            //    }
            //}

            if (!TryReadEnumerable(member.Type, Type.EmptyTypes, encodeInt, allowNull, isProperty, out value, callback)) return false;

            if (!member.IsType) member.SetValue(target, value);

            return true;
        }
Beispiel #3
0
 /// <summary>
 /// 尝试读取枚举
 /// </summary>
 /// <param name="target">目标对象</param>
 /// <param name="member">成员</param>
 /// <param name="encodeInt">是否编码整数</param>
 /// <param name="allowNull">是否允许空</param>
 /// <param name="isProperty">是否处理属性</param>
 /// <param name="value">成员值</param>
 /// <returns>是否读取成功</returns>
 public Boolean TryReadEnumerable(Object target, MemberInfoX member, Boolean encodeInt, Boolean allowNull, Boolean isProperty, out Object value)
 {
     return TryReadEnumerable(target, member, encodeInt, allowNull, isProperty, out value, null);
 }
Beispiel #4
0
 private static Boolean ReadMember(BinaryReaderX reader, Object target, MemberInfoX member, Type type, Boolean encodeInt, Boolean allowNull, Boolean isProperty, out Object value, ReadCallback callback)
 {
     // 使用自己作为处理成员的方法
     return reader.TryReadObject(target, member, type, encodeInt, allowNull, isProperty, out value, callback);
 }
Beispiel #5
0
        /// <summary>
        /// 尝试读取目标对象指定成员的值,处理基础类型、特殊类型、基础类型数组、特殊类型数组,通过委托方法处理成员
        /// </summary>
        /// <remarks>
        /// 简单类型在value中返回,复杂类型直接填充target;
        /// </remarks>
        /// <param name="target">目标对象</param>
        /// <param name="member">成员</param>
        /// <param name="type">成员类型,以哪一种类型读取</param>
        /// <param name="encodeInt">是否编码整数</param>
        /// <param name="allowNull">是否允许空</param>
        /// <param name="isProperty">是否处理属性</param>
        /// <param name="value">成员值</param>
        /// <param name="callback">处理成员的方法</param>
        /// <returns>是否读取成功</returns>
        public Boolean TryReadObject(Object target, MemberInfoX member, Type type, Boolean encodeInt, Boolean allowNull, Boolean isProperty, out Object value, ReadCallback callback)
        {
            if (type == null)
            {
                type = member.Type;
                if (target != null && member.IsType) type = target.GetType();
            }
            if (callback == null) callback = ReadMember;

            // 基本类型
            if (TryReadValue(type, encodeInt, out value)) return true;

            // 特殊类型
            if (TryReadX(type, out value)) return true;

            #region 枚举
            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                return TryReadEnumerable(target, member, encodeInt, allowNull, isProperty, out value, callback);
            }
            #endregion

            #region 复杂对象
            // 引用类型允许空时,先读取一个字节判断对象是否为空
            if (!type.IsValueType && allowNull && !ReadBoolean()) return true;

            // 成员对象
            //if (member.Member.MemberType == MemberTypes.TypeInfo)
            //    value = target;
            //else
            //    value = member.GetValue(target);
            value = member.IsType ? target : member.GetValue(target);

            // 如果为空,实例化并赋值。只有引用类型才会进来
            if (value == null)
            {
                value = TypeX.CreateInstance(type);
                //// 如果是成员,还需要赋值
                //if (member.Member.MemberType != MemberTypes.TypeInfo && target != null) member.SetValue(target, value);
            }

            // 以下只负责填充value的各成员
            Object obj = null;
            if (isProperty)
            {
                PropertyInfo[] pis = BinaryWriterX.FindProperties(type);
                if (pis == null || pis.Length < 1) return true;

                foreach (PropertyInfo item in pis)
                {
                    //ReadMember(target, reader, item, encodeInt, allowNull);
                    MemberInfoX member2 = item;
                    if (!callback(this, value, member2, member2.Type, encodeInt, allowNull, isProperty, out obj, callback)) return false;
                    member2.SetValue(value, obj);
                }
            }
            else
            {
                FieldInfo[] fis = BinaryWriterX.FindFields(type);
                if (fis == null || fis.Length < 1) return true;

                foreach (FieldInfo item in fis)
                {
                    //#if DEBUG
                    //                    long p = 0;
                    //                    long p2 = 0;
                    //                    if (BaseStream.CanSeek && BaseStream.CanRead)
                    //                    {
                    //                        p = BaseStream.Position;
                    //                        Console.Write("{0,-16}:", item.Name);
                    //                    }
                    //#endif
                    //ReadMember(target, this, item, encodeInt, allowNull);
                    MemberInfoX member2 = item;
                    if (!callback(this, value, member2, member2.Type, encodeInt, allowNull, isProperty, out obj, callback)) return false;
                    // 尽管有可能会二次赋值(如果callback调用这里的话),但是没办法保证用户的callback一定会给成员赋值,所以这里多赋值一次
                    member2.SetValue(value, obj);
                    //#if DEBUG
                    //                    if (BaseStream.CanSeek && BaseStream.CanRead)
                    //                    {
                    //                        p2 = BaseStream.Position;
                    //                        if (p2 > p)
                    //                        {
                    //                            BaseStream.Seek(p, SeekOrigin.Begin);
                    //                            Byte[] data = new Byte[p2 - p];
                    //                            BaseStream.Read(data, 0, data.Length);
                    //                            Console.WriteLine("[{0}] {1}", data.Length, BitConverter.ToString(data));
                    //                        }
                    //                        else
                    //                            Console.WriteLine();
                    //                    }
                    //#endif
                }
            }
            #endregion

            return true;
        }
Beispiel #6
0
 /// <summary>
 /// 尝试读取目标对象指定成员的值,通过委托方法递归处理成员
 /// </summary>
 /// <param name="target">目标对象</param>
 /// <param name="member">成员</param>
 /// <param name="type">成员类型,以哪一种类型读取</param>
 /// <param name="encodeInt">是否编码整数</param>
 /// <param name="allowNull">是否允许空</param>
 /// <param name="isProperty">是否处理属性</param>
 /// <param name="value">成员值</param>
 /// <returns>是否读取成功</returns>
 public Boolean TryReadObject(Object target, MemberInfoX member, Type type, Boolean encodeInt, Boolean allowNull, Boolean isProperty, out Object value)
 {
     // 使用自己作为处理成员的方法
     return TryReadObject(target, member, type, encodeInt, allowNull, isProperty, out value, ReadMember);
 }
Beispiel #7
0
 private static Boolean WriteMember(BinaryWriterX writer, Object value, MemberInfoX member, Boolean encodeInt, Boolean allowNull, Boolean isProperty, WriteCallback callback)
 {
     // 使用自己作为处理成员的方法
     return writer.WriteObject(value, member, encodeInt, allowNull, isProperty, callback);
 }
Beispiel #8
0
        /// <summary>
        /// 把目标对象指定成员写入数据流,处理基础类型、特殊类型、基础类型数组、特殊类型数组,通过委托方法处理成员
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="member">成员</param>
        /// <param name="encodeInt">是否编码整数</param>
        /// <param name="allowNull">是否允许空</param>
        /// <param name="isProperty">是否处理属性</param>
        /// <param name="callback">处理成员的方法</param>
        /// <returns>是否写入成功</returns>
        public Boolean WriteObject(Object target, MemberInfoX member, Boolean encodeInt, Boolean allowNull, Boolean isProperty, WriteCallback callback)
        {
            Type type = member.Type;
            Object value = member.IsType ? target : member.GetValue(target);

            if (value != null) type = value.GetType();
            if (callback == null) callback = WriteMember;

            // 基本类型
            if (WriteValue(value, type, encodeInt)) return true;

            // 扩展类型
            if (WriteX(value, type)) return true;

            #region 枚举
            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                if (WriteEnumerable(value as IEnumerable, type, encodeInt, allowNull, isProperty, callback)) return true;
            }
            #endregion

            #region 复杂对象
            // 值类型不会为null,只有引用类型才需要写标识
            if (!type.IsValueType)
            {
                // 允许空时,增加一个字节表示对象是否为空
                if (value == null)
                {
                    if (allowNull) Write(false);
                    return true;
                }
                if (allowNull) Write(true);
            }

            // 复杂类型,处理对象成员
            if (isProperty)
            {
                PropertyInfo[] pis = FindProperties(type);
                if (pis == null || pis.Length < 1) return true;

                foreach (PropertyInfo item in pis)
                {
                    if (!callback(this, value, item, encodeInt, allowNull, isProperty, callback)) return false;
                }
            }
            else
            {
                FieldInfo[] fis = FindFields(type);
                if (fis == null || fis.Length < 1) return true;

                foreach (FieldInfo item in fis)
                {
                    //#if DEBUG
                    //                    long p = 0;
                    //                    long p2 = 0;
                    //                    if (BaseStream.CanSeek && BaseStream.CanRead)
                    //                    {
                    //                        p = BaseStream.Position;
                    //                        Console.Write("{0,-16}:", item.Name);
                    //                    }
                    //#endif
                    if (!callback(this, value, item, encodeInt, allowNull, isProperty, callback)) return false;
                    //#if DEBUG
                    //                    if (BaseStream.CanSeek && BaseStream.CanRead)
                    //                    {
                    //                        p2 = BaseStream.Position;
                    //                        if (p2 > p)
                    //                        {
                    //                            BaseStream.Seek(p, SeekOrigin.Begin);
                    //                            Byte[] data = new Byte[p2 - p];
                    //                            BaseStream.Read(data, 0, data.Length);
                    //                            Console.WriteLine("[{0}] {1}", data.Length, BitConverter.ToString(data));
                    //                        }
                    //                        else
                    //                            Console.WriteLine();
                    //                    }
                    //#endif
                }
            }
            #endregion

            return true;
        }
Beispiel #9
0
 /// <summary>
 /// 把目标对象指定成员写入数据流,通过委托方法递归处理成员
 /// </summary>
 /// <param name="target">对象</param>
 /// <param name="member">成员</param>
 /// <param name="encodeInt">是否编码整数</param>
 /// <param name="allowNull">是否允许空</param>
 /// <param name="isProperty">是否处理属性</param>
 /// <returns>是否写入成功</returns>
 public Boolean WriteObject(Object target, MemberInfoX member, Boolean encodeInt, Boolean allowNull, Boolean isProperty)
 {
     // 使用自己作为处理成员的方法
     return WriteObject(target, member, encodeInt, allowNull, isProperty, WriteMember);
 }
Beispiel #10
0
 /// <summary>
 /// 尝试读取目标对象指定成员的值,处理基础类型、特殊类型、基础类型数组、特殊类型数组,通过委托方法处理成员
 /// </summary>
 /// <remarks>
 /// 简单类型在value中返回,复杂类型直接填充target;
 /// </remarks>
 /// <param name="reader">读取器</param>
 /// <param name="target">目标对象</param>
 /// <param name="member">成员</param>
 /// <param name="type">成员类型,以哪一种类型读取</param>
 /// <param name="encodeInt">是否编码整数</param>
 /// <param name="allowNull">是否允许空</param>
 /// <param name="isProperty">是否处理属性</param>
 /// <param name="value">成员值</param>
 /// <param name="callback">处理成员的方法</param>
 /// <returns>是否读取成功</returns>
 protected override Boolean ReadMember(BinaryReaderX reader, object target, MemberInfoX member, Type type, bool encodeInt, bool allowNull, bool isProperty, out object value, BinaryReaderX.ReadCallback callback)
 {
     if (member.Member.Name != "_Entity")
         return base.ReadMember(reader, target, member, type, encodeInt, allowNull, isProperty, out value, callback);
     else
         return base.ReadMember(reader, target, member, EntityType, encodeInt, allowNull, isProperty, out value, callback);
 }
Beispiel #11
0
        /// <summary>
        /// 把对象写入数据流,处理基础类型、特殊类型、基础类型数组、特殊类型数组,通过委托方法处理成员
        /// </summary>
        /// <param name="writer">写入器</param>
        /// <param name="target">目标对象</param>
        /// <param name="member">成员</param>
        /// <param name="encodeInt">是否编码整数</param>
        /// <param name="allowNull">是否允许空</param>
        /// <param name="isProperty">是否处理属性</param>
        /// <param name="callback">处理成员的方法</param>
        /// <returns>是否写入成功</returns>
        protected virtual Boolean WriteMember(BinaryWriterX writer, Object target, MemberInfoX member, Boolean encodeInt, Boolean allowNull, Boolean isProperty, BinaryWriterX.WriteCallback callback)
        {
            Type type = member.Type;
            Object value = member.IsType ? target : member.GetValue(target);

            if (value != null) type = value.GetType();

            // 接口支持
            if (value != null && typeof(IBinaryAccessor).IsAssignableFrom(type))
            {
                // 调用接口
                IBinaryAccessor accessor = value as IBinaryAccessor;
                accessor.Write(writer);
                return true;
            }

            return writer.WriteObject(target, member, encodeInt, true, isProperty, callback);
        }