/// <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); }
/// <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; }
/// <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); }
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); }
/// <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; }
/// <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); }
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); }
/// <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; }
/// <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); }
/// <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); }
/// <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); }