📄 classdescriptor.cs
字号:
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 + -