示例#1
0
        /// <summary>
        /// バイト配列内の指定位置にあるバイト列から構造体に変換する
        /// </summary>
        /// <param name="value">バイト配列</param>
        /// <param name="startIndex">value 内の開始位置</param>
        /// <param name="endian">エンディアン</param>
        /// <returns></returns>
        public static object ToStruct(byte[] value, int startIndex, Endian endian, Type type)
        {
            if (!type.IsValueType)
            {
                throw new ArgumentException();
            }

            // プリミティブ型は専用メソッドへ飛ばす
            TypeCode code = Type.GetTypeCode(type);

            switch (code)
            {
            case TypeCode.Boolean:
                return(ToBoolean(value, startIndex, endian));

            case TypeCode.Byte:
                return(value[startIndex]);

            case TypeCode.Char:
                return(ToChar(value, startIndex, endian));

            case TypeCode.Double:
                return(ToDouble(value, startIndex, endian));

            case TypeCode.Int16:
                return(ToInt16(value, startIndex, endian));

            case TypeCode.Int32:
                return(ToInt32(value, startIndex, endian));

            case TypeCode.Int64:
                return(ToInt64(value, startIndex, endian));

            case TypeCode.SByte:
                return(value[startIndex]);

            case TypeCode.Single:
                return(ToSingle(value, startIndex, endian));

            case TypeCode.UInt16:
                return(ToUInt16(value, startIndex, endian));

            case TypeCode.UInt32:
                return(ToUInt32(value, startIndex, endian));

            case TypeCode.UInt64:
                return(ToUInt64(value, startIndex, endian));

            default:
                break;     // 多分その他のstructなので以下処理する
            }

            // 構造体の全フィールドを取得
            FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            // 型情報から新規インスタンスを生成 (返却値)
            object obj    = Activator.CreateInstance(type);
            int    offset = 0;

            foreach (FieldInfo info in fields)
            {
                // フィールドの値をバイト列から1つ取得し、objの同じフィールドに設定
                Type fieldType = info.FieldType;
                if (!fieldType.IsValueType)
                {
                    throw new InvalidOperationException();
                }
                object fieldValue = BitConverterEx.ToStruct(value, startIndex + offset, endian, fieldType);
                info.SetValue(obj, fieldValue);
                // 次のフィールド値を見るためフィールドのバイトサイズ分進める
                offset += Marshal.SizeOf(fieldType);
            }

            return(obj);
        }