ObjectsTypesBytesHelper


namespace Microshaoft
{
    using System;
    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Collections.Concurrent;
    using System.Linq.Expressions;
    public static class ObjectsTypesBytesHelper
    {
        public static byte[] ObjectToBytes<T>
                                 (
                                    T Object
                                    , Func
                                        <
                                            int
                                            , int
                                            , MemberInfo
                                            , Type                                    //Member Data Type
                                            , MemberSequenceBytesLengthAttribute
                                            , DynamicPropertyOrFieldAccessor
                                            , byte[]                                // return
                                        > processObjectMemberBytesBlockFunc
                                 )
        {
            Type type = typeof(T);
            Tuple
                <
                    Type
                    , ClassOrStructBytesLengthAttribute
                    , List
                        <
                            Tuple
                                <
                                    Type
                                    , ClassOrStructBytesLengthAttribute
                                    , MemberInfo
                                    , Type
                                    , MemberSequenceBytesLengthAttribute
                                    , DynamicPropertyOrFieldAccessor
                                >
                        >
                > entry = ObjectsTypesCache.GetOrAdd(type);
            int p = 0;
            List<byte[]> buffersList = new List<byte[]>();
            int i = 1;
            entry.Item3.ForEach
                            (
                                (x) =>
                                {
                                    byte[] buffer = processObjectMemberBytesBlockFunc
                                                        (
                                                            i
                                                            , p                    //累计长度
                                                            , x.Item3
                                                            , x.Item4
                                                            , x.Item5
                                                            , x.Item6
                                                        );
                                    p += buffer.Length;
                                    buffersList.Add(buffer);
                                }
                            );
            ClassOrStructBytesLengthAttribute attribute = entry.Item2;
            int offset = attribute.BytesLength;
            byte[] buff = new byte[offset];
            byte[] buf = BitConverter.GetBytes(p);
            int count = (buf.Length < buff.Length ? buf.Length : buff.Length);
            Buffer.BlockCopy
                        (
                            buf
                            , 0
                            , buff
                            , 0
                            , count
                        );
            Array.Reverse(buff);
            byte[] bytes = new byte[p + offset];
            p = 0;
            Buffer.BlockCopy
                        (
                            buff
                            , 0
                            , bytes
                            , 0
                            , buff.Length
                        );
            p += buff.Length;
            buffersList.ForEach
                            (
                                (x) =>
                                {
                                    Buffer.BlockCopy
                                                (
                                                    x
                                                    , 0
                                                    , bytes
                                                    , p
                                                    , x.Length
                                                );
                                    p += x.Length;
                                }
                            );
            return bytes;
        }
    }
    public static class ObjectsTypesCache
    {
        public static ConcurrentDictionary
                                    <
                                        Type
                                        , Tuple
                                            <
                                                Type            //类的类型
                                                , ClassOrStructBytesLengthAttribute
                                                , List
                                                    <
                                                        Tuple
                                                            <
                                                                Type                                    //类的类型
                                                                , ClassOrStructBytesLengthAttribute
                                                                , MemberInfo
                                                                , Type                                    //Member Data Type
                                                                , MemberSequenceBytesLengthAttribute
                                                                , DynamicPropertyOrFieldAccessor
                                                            >
                                                    >
                                            >
                                    > TypesMembersInfosAccessorsDictionaryCache
        {
            get;
            private set;
        }
        static ObjectsTypesCache()
        {
            TypesMembersInfosAccessorsDictionaryCache = new ConcurrentDictionary
                                                                        <
                                                                            Type
                                                                            , Tuple
                                                                                <
                                                                                    Type
                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                    , List
                                                                                        <
                                                                                            Tuple
                                                                                                <
                                                                                                    Type
                                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                                    , MemberInfo
                                                                                                    , Type
                                                                                                    , MemberSequenceBytesLengthAttribute
                                                                                                    , DynamicPropertyOrFieldAccessor
                                                                                                >
                                                                                        >
                                                                                >
                                                                        >();
        }
        public static Tuple
                        <
                            Type
                            , ClassOrStructBytesLengthAttribute
                            , List
                                <
                                    Tuple
                                        <
                                            Type
                                            , ClassOrStructBytesLengthAttribute
                                            , MemberInfo
                                            , Type
                                            , MemberSequenceBytesLengthAttribute
                                            , DynamicPropertyOrFieldAccessor
                                        >
                                >
                        > GetOrAdd(Type type)
        {
            return TypesMembersInfosAccessorsDictionaryCache.GetOrAdd
                                                                (
                                                                    type
                                                                    , (t) =>
                                                                    {
                                                                        ClassOrStructBytesLengthAttribute typeAttribute =
                                                                                                    (
                                                                                                        (ClassOrStructBytesLengthAttribute[])
                                                                                                        t.GetCustomAttributes
                                                                                                                (
                                                                                                                    typeof(ClassOrStructBytesLengthAttribute)
                                                                                                                    , false
                                                                                                                )
                                                                                                    ).OrderBy
                                                                                                        (
                                                                                                            (x) =>
                                                                                                            {
                                                                                                                return x.AttributeSequence;
                                                                                                            }
                                                                                                        ).ToList().First();
                                                                        Tuple
                                                                            <
                                                                                Type            //类的类型
                                                                                , ClassOrStructBytesLengthAttribute
                                                                                , List
                                                                                    <
                                                                                        Tuple
                                                                                            <
                                                                                                Type                                        //类的类型
                                                                                                , ClassOrStructBytesLengthAttribute
                                                                                                , MemberInfo
                                                                                                , Type                                        //Member Data Type
                                                                                                , MemberSequenceBytesLengthAttribute
                                                                                                , DynamicPropertyOrFieldAccessor
                                                                                            >
                                                                                    >
                                                                            > entry =
                                                                                    new Tuple
                                                                                            <
                                                                                                Type
                                                                                                , ClassOrStructBytesLengthAttribute
                                                                                                , List
                                                                                                    <
                                                                                                        Tuple
                                                                                                            <
                                                                                                                Type
                                                                                                                , ClassOrStructBytesLengthAttribute
                                                                                                                , MemberInfo
                                                                                                                , Type
                                                                                                                , MemberSequenceBytesLengthAttribute
                                                                                                                , DynamicPropertyOrFieldAccessor
                                                                                                            >
                                                                                                    >
                                                                                            >
                                                                                            (
                                                                                                type
                                                                                                , typeAttribute
                                                                                                , GetTypeAllMembersInfosList(type, typeAttribute)
                                                                                            );
                                                                        return entry;
                                                                    }
                                                                );
        }
        private static List
                        <
                            Tuple
                                <
                                    Type                                        //类的类型
                                    , ClassOrStructBytesLengthAttribute
                                    , MemberInfo
                                    , Type                                        //Member Data Type
                                    , MemberSequenceBytesLengthAttribute
                                    , DynamicPropertyOrFieldAccessor
                                >
                        > GetTypeAllMembersInfosList(Type t, ClassOrStructBytesLengthAttribute typeAttribute)
        {
            List
                <
                    Tuple
                        <
                            Type                                                //类的类型
                            , ClassOrStructBytesLengthAttribute
                            , MemberInfo
                            , Type                                                //Member Data Type
                            , MemberSequenceBytesLengthAttribute
                            , DynamicPropertyOrFieldAccessor
                        >
                > list = null;
            t.GetMembers().ToList().Where
                                            (
                                                (mi) =>
                                                {
                                                    var r = false;
                                                    if (mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property)
                                                    {
                                                        var attributes =
                                                                        (
                                                                            (MemberSequenceBytesLengthAttribute[])mi.GetCustomAttributes
                                                                                                    (
                                                                                                        typeof(MemberSequenceBytesLengthAttribute)
                                                                                                        , false
                                                                                                    )
                                                                         ).OrderBy
                                                                                                        (
                                                                                                            (x) =>
                                                                                                            {
                                                                                                                return x.AttributeSequence;
                                                                                                            }
                                                                                                        ).ToList();
                                                        if (attributes.Count > 0)
                                                        {
                                                            var attribute = attributes.First();
                                                            if (list == null)
                                                            {
                                                                list = new List
                                                                                <
                                                                                    Tuple
                                                                                        <
                                                                                            Type                                    //类的类型
                                                                                            , ClassOrStructBytesLengthAttribute
                                                                                            , MemberInfo
                                                                                            , Type                                    //Member Data Type
                                                                                            , MemberSequenceBytesLengthAttribute
                                                                                            , DynamicPropertyOrFieldAccessor
                                                                                        >
                                                                                >();
                                                            }
                                                            Type type = null;
                                                            if (mi.MemberType == MemberTypes.Field)
                                                            {
                                                                type = ((FieldInfo)mi).FieldType;
                                                            }
                                                            else if (mi.MemberType == MemberTypes.Property)
                                                            {
                                                                type = ((PropertyInfo)mi).PropertyType;
                                                            }
                                                            Tuple
                                                                <
                                                                     Type
                                                                    , ClassOrStructBytesLengthAttribute
                                                                    , MemberInfo
                                                                    , Type                                                    //Member Data Type
                                                                    , MemberSequenceBytesLengthAttribute
                                                                    , DynamicPropertyOrFieldAccessor
                                                                 > entry = new Tuple
                                                                                <
                                                                                    Type                                    //类的类型
                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                    , MemberInfo
                                                                                    , Type                                    //Member Data Type
                                                                                    , MemberSequenceBytesLengthAttribute
                                                                                    , DynamicPropertyOrFieldAccessor
                                                                                >
                                                                                (
                                                                                    t
                                                                                    , typeAttribute
                                                                                    , mi
                                                                                    , type
                                                                                    , attribute
                                                                                    , new DynamicPropertyOrFieldAccessor(mi)
                                                                                 );
                                                            list.Add(entry);
                                                            r = true;
                                                        }
                                                    }
                                                    return r;
                                                }
                                            ).ToList();
            var result = list.OrderBy
                                (
                                    (entry) =>
                                    {
                                        return entry.Item5.AttributeSequence;
                                    }
                                ).ToList();
            return result;
        }
    }
    public class DynamicPropertyOrFieldAccessor
    {
        private Func<object, object> m_getter;
        //public DynamicPropertyAccessor(Type type, string propertyName)
        //    : this(type.GetProperty(propertyName))
        //{
        //}
        public DynamicPropertyOrFieldAccessor(MemberInfo memberInfo)
        {
            // target: (object)((({TargetType})instance).{Property})
            // preparing parameter, object type
            ParameterExpression instance = Expression.Parameter
                                                            (
                                                                typeof(object),
                                                                "instance"
                                                            );
            // ({TargetType})instance
            Expression instanceCast = Expression.Convert
                                                    (
                                                        instance
                                                        , memberInfo.ReflectedType
                                                    );
            // (({TargetType})instance).{Property}
            Expression memberAccess = Expression.PropertyOrField
                                                        (
                                                            instanceCast
                                                            , memberInfo.Name
                                                        );
            // (object)((({TargetType})instance).{Property})
            UnaryExpression castPropertyValue = Expression.Convert
                                                                (
                                                                    memberAccess
                                                                    , typeof(object)
                                                                );
            // Lambda expression
            Expression<Func<object, object>> lambda = Expression.Lambda<Func<object, object>>
                                                                                    (
                                                                                        castPropertyValue, instance
                                                                                    );
            this.m_getter = lambda.Compile();
        }
        public object GetValue(object o)
        {
            return this.m_getter(o);
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Collections.Concurrent;
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)]
    public class ClassOrStructBytesLengthAttribute : Attribute
    {
        public int BytesLength
        {
            get;
            set;
        }
        public int AttributeSequence
        {
            get;
            set;
        }
    }
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
    public class MemberSequenceBytesLengthAttribute : Attribute
    {
        public int MemberSequence
        {
            get;
            set;
        }
        public int AttributeSequence
        {
            get;
            set;
        }
        public int BytesLength
        {
            get;
            set;
        }
    }
}

posted @ 2012-04-17 01:37  于斯人也  阅读(314)  评论(0编辑  收藏  举报