/// <summary> /// 读取扩展成员 /// </summary> /// <param name="reader"></param> /// <param name="dataItem"></param> public virtual void ReadExtendProperty(BinaryReader reader, DataFieldItem dataItem) { PropertyInfo property = dataItem.Property; DataFieldAttribute att = dataItem.Attribute; if (att.RefType == typeof(Int32)) { return; } long offset = 0; if (property.PropertyType == typeof(Int32)) { offset = (Int32)property.GetValue(this, null); } else { offset = (Int16)property.GetValue(this, null); } if (offset <= 0) { return; } // 检查位移是否超出文件结尾 long address = GetRealAddress(offset, att.RefKind); // 超出文件结尾时,终止读取 if (address <= 0 || address > reader.BaseStream.Length) { Extends.Add(property.Name, null); return; } // 读取扩展数据 if (att.RefType == typeof(String)) { // 字符串仅仅是偏移量,需要加上基地址 //Seek(reader, Address + offset); Seek(reader, address); String str = ReadString(reader); //Extends[property.Name] = str; Extends.Add(property.Name, str); } else { //offset = GetRealAddress(offset, att.RefKind); // 简单对象/对象集合 if (String.IsNullOrEmpty(att.SizeField)) { #region 简单对象 // 首先判断是否在全局缓存里面 if (!Info.Objects.ContainsKey(address)) { // 创建对象 EntityBase2 entity = Activator.CreateInstance(att.RefType) as EntityBase2; if (entity == null) { throw new InvalidOperationException(String.Format("引用成员{0}.{1}的引用类型{2}无法识别!", this.GetType().Name, property.Name, att.RefType.Name)); } Seek(reader, address); entity.Info = Info; // 读取对象 entity.Read(reader); //Extends[property.Name] = entity; //Info.Objects[offset] = entity; // 故意使用Add方法,避免重新赋值 Extends.Add(property.Name, entity); //Info.Objects.Add(offset, entity); } else { //Extends[property.Name] = Info.Objects[offset]; Extends.Add(property.Name, Info.Objects[address]); //#if DEBUG // WriteLine("地址0x{0:X}已分析!", offset); //#endif } #endregion } else { // Info.Objects只存单个对象,不存集合,所以这里不用判断 // 创建对象 EntityBase2 entity = Activator.CreateInstance(att.RefType) as EntityBase2; if (entity == null) { throw new InvalidOperationException(String.Format("引用成员{0}.{1}的引用类型{2}无法识别!", this.GetType().Name, property.Name, att.RefType.Name)); } Int32 size = Convert.ToInt32(this[att.SizeField]); if (size > 0) { // 先移到第一个对象所在位置 Seek(reader, address); entity.Info = Info; Object list = entity.ReadExtendList(reader, size); //Extends[property.Name] = list; //Info.Objects[offset] = list; Extends.Add(property.Name, list); //Info.Objects.Add(offset, list); } } } }
/// <summary> /// 读取指定成员 /// </summary> /// <param name="reader"></param> /// <param name="dataItem"></param> public virtual void ReadProperty(BinaryReader reader, DataFieldItem dataItem) { PropertyInfo property = dataItem.Property; DataFieldAttribute att = dataItem.Attribute; switch (Type.GetTypeCode(property.PropertyType)) { case TypeCode.Boolean: break; case TypeCode.Byte: property.SetValue(this, reader.ReadByte(), null); return; case TypeCode.Char: break; case TypeCode.DBNull: break; case TypeCode.DateTime: break; case TypeCode.Decimal: break; case TypeCode.Double: break; case TypeCode.Empty: break; case TypeCode.Int16: property.SetValue(this, reader.ReadInt16(), null); return; case TypeCode.Int32: property.SetValue(this, reader.ReadInt32(), null); return; case TypeCode.Int64: property.SetValue(this, reader.ReadInt64(), null); return; case TypeCode.Object: if (property.PropertyType == typeof(Byte[])) { if (att.Size <= 0) { throw new InvalidOperationException(String.Format("字节数组{0}.{1}的大小未设置!", this.GetType().Name, property.Name)); } property.SetValue(this, reader.ReadBytes(att.Size), null); return; } break; case TypeCode.SByte: break; case TypeCode.Single: break; case TypeCode.String: Int32 size = att.Size; if (size <= 0) { if (!String.IsNullOrEmpty(att.SizeField)) { size = Convert.ToInt32(this[att.SizeField]); } if (size <= 0) { throw new InvalidOperationException(String.Format("字符串{0}.{1}的长度未设置!", this.GetType().Name, property.Name)); } } Byte[] buf = reader.ReadBytes(size); List <Byte> list = new List <Byte>(); foreach (Byte item in buf) { if (item != 0) { list.Add(item); } } if (list.Count > 0) { buf = list.ToArray(); property.SetValue(this, Encoding.UTF8.GetString(buf), null); } return; case TypeCode.UInt16: property.SetValue(this, reader.ReadUInt16(), null); return; case TypeCode.UInt32: property.SetValue(this, reader.ReadUInt32(), null); return; case TypeCode.UInt64: property.SetValue(this, reader.ReadUInt64(), null); return; default: break; } throw new InvalidOperationException(String.Format("{0}.{1}的类型{2}不受支持!", this.GetType().Name, property.Name, property.PropertyType.Name)); }