⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classdescriptor.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 2 页
字号:
namespace Perst.Impl
{
    using System;
    using System.Collections;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Text;
    using Perst;
	
    public sealed class ClassDescriptor:Persistent
    {
        internal ClassDescriptor   next;
        internal String            name;
        internal FieldDescriptor[] allFields;
        internal bool              hasReferences;
        internal CustomAllocator   allocator;

        internal static Module     lastModule;

        public class FieldDescriptor : Persistent 
        { 
            internal String          fieldName;
            internal String          className;
            internal FieldType       type;
            internal ClassDescriptor valueDesc;
            [NonSerialized()]
            internal FieldInfo       field;
            [NonSerialized()]
            internal bool            recursiveLoading;
#if USE_GENERICS
            [NonSerialized()]
            internal MethodInfo constructor;
#endif
            public bool equals(FieldDescriptor fd) 
            { 
                return fieldName.Equals(fd.fieldName) 
                    && className.Equals(fd.className)
                    && valueDesc == fd.valueDesc
                    && type == fd.type;
            }
        }    
        [NonSerialized()]
        internal Type cls;
        [NonSerialized()]
        internal bool hasSubclasses;
        [NonSerialized()]
        internal ConstructorInfo defaultConstructor;
        [NonSerialized()]
        internal bool resolved;
        [NonSerialized()]
        internal GeneratedSerializer serializer;
		
        internal static bool serializeNonPersistentObjects;

        public enum FieldType 
        {
            tpBoolean,
            tpByte,
            tpSByte,
            tpShort, 
            tpUShort,
            tpChar,
            tpEnum,
            tpInt,
            tpUInt,
            tpLong,
            tpULong,
            tpFloat,
            tpDouble,
            tpString,
            tpDate,
            tpObject,
            tpOid,
            tpValue,
            tpRaw,
            tpGuid,
            tpDecimal,
            tpLink,
            tpArrayOfBoolean,
            tpArrayOfByte,
            tpArrayOfSByte,
            tpArrayOfShort, 
            tpArrayOfUShort,
            tpArrayOfChar,
            tpArrayOfEnum,
            tpArrayOfInt,
            tpArrayOfUInt,
            tpArrayOfLong,
            tpArrayOfULong,
            tpArrayOfFloat,
            tpArrayOfDouble,
            tpArrayOfString,
            tpArrayOfDate,
            tpArrayOfObject,
            tpArrayOfOid,
            tpArrayOfValue,
            tpArrayOfRaw,
            tpArrayOfGuid,
            tpArrayOfDecimal,
            tpCustom,
            tpLast
        };
		
        internal static int[] Sizeof = new int[] 
        {
            1, // tpBoolean,
            1, // tpByte,
            1, // tpSByte,
            2, // tpShort, 
            2, // tpUShort,
            2, // tpChar,
            4, // tpEnum,
            4, // tpInt,
            4, // tpUInt,
            8, // tpLong,
            8, // tpULong,
            4, // tpFloat,
            8, // tpDouble,
            0, // tpString,
            8, // tpDate,
            4, // tpObject,
            4, // tpOid,
            0, // tpValue,
            0, // tpRaw,
            16,// tpGuid,
            16,// tpDecimal,
            0, // tpLink,
            0, // tpArrayOfBoolean,
            0, // tpArrayOfByte,
            0, // tpArrayOfSByte,
            0, // tpArrayOfShort, 
            0, // tpArrayOfUShort,
            0, // tpArrayOfChar,
            0, // tpArrayOfEnum,
            0, // tpArrayOfInt,
            0, // tpArrayOfUInt,
            0, // tpArrayOfLong,
            0, // tpArrayOfULong,
            0, // tpArrayOfFloat,
            0, // tpArrayOfDouble,
            0, // tpArrayOfString,
            0, // tpArrayOfDate,
            0, // tpArrayOfObject,
            0, // tpArrayOfOid,
            0, // tpArrayOfValue,
            0, // tpArrayOfRaw,
            0, // tpArrayOfGuid,
            0, // tpArrayOfDecimal,
            0  // tpCustom
    };
		
        internal static Type[] defaultConstructorProfile = new Type[0];
        internal static object[] noArgs = new object[0];
	
#if COMPACT_NET_FRAMEWORK
        static internal object parseEnum(Type type, String value) 
        {
            foreach (FieldInfo fi in type.GetFields()) 
            {
                if (fi.IsLiteral && fi.Name.Equals(value)) 
                {
                    return fi.GetValue(null);
                }
            }
            throw new ArgumentException(value);
        }
#endif

        public bool equals(ClassDescriptor cd) 
        { 
            if (cd == null || allFields.Length != cd.allFields.Length) 
            { 
                return false;
            }
            for (int i = 0; i < allFields.Length; i++) 
            { 
                if (!allFields[i].equals(cd.allFields[i])) 
                { 
                    return false;
                }
            }
            return true;
        }
        
        internal Object newInstance()
        {
            try
            {
                return defaultConstructor.Invoke(noArgs);
            }
            catch (System.Exception x)
            {
                throw new StorageError(StorageError.ErrorCode.CONSTRUCTOR_FAILURE, cls, x);
            }
        }
		
#if COMPACT_NET_FRAMEWORK
        internal void generateSerializer() {}
#else
        private static CodeGenerator serializerGenerator = CodeGenerator.Instance;

        internal void generateSerializer()
        {
            if (!cls.IsPublic || defaultConstructor == null || !defaultConstructor.IsPublic) 
            { 
                return;
            }
            FieldDescriptor[] flds = allFields;
            for (int i = 0, n = flds.Length; i < n; i++) 
            {
                FieldDescriptor fd = flds[i];
                switch (fd.type) 
                { 
                    case FieldType.tpValue:
                    case FieldType.tpArrayOfValue:
                    case FieldType.tpArrayOfObject:
                    case FieldType.tpArrayOfEnum:
                    case FieldType.tpArrayOfRaw:
#if USE_GENERICS
                    case FieldType.tpLink:
                    case FieldType.tpArrayOfOid:
#endif
    
                        return;
                    default:
                        break;
                }
                FieldInfo f = flds[i].field;
                if (f == null || !f.IsPublic) 
                {
                    return;
                }
            }
            serializer = serializerGenerator.Generate(this);
        }
        
        static private bool isObjectProperty(Type cls, FieldInfo f)
        {
            return typeof(PersistentWrapper).IsAssignableFrom(cls) && f.Name.StartsWith("r_");
        }
#endif

#if USE_GENERICS
        MethodInfo GetConstructor(FieldInfo f, string name)
        { 
            MethodInfo mi = typeof(StorageImpl).GetMethod(name, BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.DeclaredOnly);
            return mi.MakeGenericMethod(f.FieldType.GetGenericArguments());
        }
#endif

        internal static String getTypeName(Type t)
        {
#if USE_GENERICS
            if (t.IsGenericType)
            { 
                Type[] genericArgs = t.GetGenericArguments();
                t = t.GetGenericTypeDefinition();
                StringBuilder buf = new StringBuilder(t.FullName);
                buf.Append('=');
                char sep = '[';
                for (int j = 0; j < genericArgs.Length; j++) 
                { 
                     buf.Append(sep);
                     sep = ',';
                     buf.Append(getTypeName(genericArgs[j]));
                }
                buf.Append(']');
                return buf.ToString();
            }
#endif
            return t.FullName;
        }

        static bool isPerstInternalType(Type t)
        {
            return t.Namespace == typeof(IPersistent).Namespace
                && t != typeof(IPersistent)
#if !COMPACT_NET_FRAMEWORK
                && t != typeof(PersistentContext) 
#endif
                && t != typeof(Persistent);
        }

        internal void  buildFieldList(StorageImpl storage, System.Type cls, ArrayList list)
        {
            System.Type superclass = cls.BaseType;
            if (superclass != null && superclass != typeof(MarshalByRefObject))
            {
                buildFieldList(storage, superclass, list);
            }
            FieldInfo[] flds = cls.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly);
#if !COMPACT_NET_FRAMEWORK 
            bool isWrapper = typeof(PersistentWrapper).IsAssignableFrom(cls);
            bool hasTransparentAttribute = cls.GetCustomAttributes(typeof(TransparentPersistenceAttribute), true).Length != 0;
#else
            bool hasTransparentAttribute = false;
#endif

            for (int i = 0; i < flds.Length; i++)
            {
                FieldInfo f = flds[i];
                if (!f.IsNotSerialized && !f.IsStatic && !typeof(Delegate).IsAssignableFrom(f.FieldType))
                {
                    FieldDescriptor fd = new FieldDescriptor();
                    fd.field = f;
                    fd.fieldName = f.Name;
                    fd.className = getTypeName(cls);
                    Type fieldType = f.FieldType;
                    FieldType type = getTypeCode(fieldType);
                    switch (type) 
                    {
#if !COMPACT_NET_FRAMEWORK 
                        case FieldType.tpInt:
                            if (isWrapper && isObjectProperty(cls, f)) 
                            {
                                hasReferences = true;
                                type = FieldType.tpOid;
                            } 
                            break;
#endif
#if USE_GENERICS
                        case FieldType.tpArrayOfOid:
                            fd.constructor = GetConstructor(f, "ConstructArray");
                            hasReferences = true;
                            break;
                        case FieldType.tpLink:
                            fd.constructor = GetConstructor(f, "ConstructLink");
                            hasReferences = true;
                            break;
#else
                        case FieldType.tpArrayOfOid:
                        case FieldType.tpLink:
#endif
                        case FieldType.tpArrayOfObject:
                        case FieldType.tpObject:
                            hasReferences = true;
                            if (hasTransparentAttribute && isPerstInternalType(fieldType))
                            {
                                fd.recursiveLoading = true; 
                            }
                            break;
                        case FieldType.tpValue:
                            fd.valueDesc = storage.getClassDescriptor(f.FieldType);
                            hasReferences |= fd.valueDesc.hasReferences;
                            break;
                        case FieldType.tpArrayOfValue:
                            fd.valueDesc = storage.getClassDescriptor(f.FieldType.GetElementType());
                            hasReferences |= fd.valueDesc.hasReferences;
                            break;
                    }
                    fd.type = type;
                    list.Add(fd);
                }
            }
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -