/// <summary> /// 指定されたビットアクセッサの指定位置から指定タイプのオブジェクトを取得する /// </summary> /// <param name="ba">ビットアクセッサ、LittleEndian プロパティが取得構造体の BitStructAttribute 属性に合わせて変更されるので注意</param> /// <param name="position">ビット位置</param> /// <param name="type">取得するオブジェクト型</param> /// <returns>オブジェクト</returns> public static object ToObject(BitAccessor ba, int position, Type type) { var result = Activator.CreateInstance(type); CopyToObject(ba, position, result); return(result); }
/// <summary> /// 指定されたビットアクセッサの指定位置から指定タイプのオブジェクトを取得する /// </summary> /// <typeparam name="T">取得する型</typeparam> /// <param name="ba">ビットアクセッサ、LittleEndian プロパティが取得構造体の BitStructAttribute 属性に合わせて変更されるので注意</param> /// <param name="position">ビット位置</param> /// <returns>オブジェクト</returns> public static T ToObject <T>(BitAccessor ba, int position) where T : new() { var result = new T(); CopyToObject(ba, position, result); return(result); }
/// <summary> /// 指定された位置から構造体を取得する /// </summary> /// <param name="position">ファイル内での位置(bytes)</param> /// <param name="type">構造体型</param> /// <returns>構造体</returns> public object Read(ulong position, Type type) { unsafe { var bits = BitMarshal.BitsOf(type); if (bits != 0) { int structSize = (bits + 7) / 8; var obj = Activator.CreateInstance(type); using (var ba = new BitAccessor(this.ReadBytes(position, structSize))) { BitMarshal.CopyToObject(ba, 0, obj); } return(obj); } else { int structSize = Marshal.SizeOf(type); if (position < this.CurrentViewPosition || this.CurrentViewPosition + this.CurrentViewSize < position + (ulong)structSize) { ReAllocateView(position); } return(Marshal.PtrToStructure(new IntPtr((byte *)this.CurrentViewAddress.ToPointer() + position - this.CurrentViewPosition), type)); } } }
/// <summary> /// 指定されたビットアクセッサの指定位置から指定タイプのオブジェクトを取得する /// </summary> /// <param name="ba">ビットアクセッサ、LittleEndian プロパティが取得構造体の BitStructAttribute 属性に合わせて変更されるので注意</param> /// <param name="position">ビット位置</param> /// <param name="obj">コピー先オブジェクト</param> /// <returns>オブジェクト</returns> public static void CopyToObject(BitAccessor ba, int position, object obj) { var type = obj.GetType(); var atr = type.GetCustomAttributes(typeof(BitStructAttribute), true).FirstOrDefault() as BitStructAttribute; var fields = type.GetFields().OrderBy(field => field.MetadataToken); int offset = 0; if (atr != null) { ba.LittleEndian = atr.LittleEndian; } foreach (var f in fields) { var ft = f.FieldType; Extract ext; if (!_SupportedTypes.TryGetValue(ft, out ext)) { throw new NotSupportedException("Field \"" + f.Name + "\" type of " + ft.FullName + "\" is not supported."); } var fatr = f.GetCustomAttributes(typeof(BitsAttribute), true).FirstOrDefault() as BitsAttribute; if (fatr == null) { throw new NotSupportedException("Field \"" + f.Name + "\" has no BitsAttribute."); } if (0 <= fatr.Offset) { offset = fatr.Offset; } try { f.SetValue(obj, ext(ba, position + offset, fatr.Bits)); } catch (Exception ex) { throw new IndexOutOfRangeException("\"" + f.Name + "\" has exceeded the size of the array.", ex); } offset += fatr.Bits; } }