public void PropertyCompilerGeneratedFieldsIsNotSerialized() { var objserInfo = new ObjectSerializationInfo(typeof(_PropertyCompilerGenerated), true); objserInfo.SerializeMemberInfos.Length.Is(1); objserInfo.SerializeMemberInfos[0].Name.Is(nameof(_PropertyCompilerGenerated.r)); }
public void ReadOnlyFieldsIsNotSerialized() { var objserInfo = new ObjectSerializationInfo(typeof(_ReadOnlyField), true); objserInfo.SerializeMemberInfos.Length.Is(1); objserInfo.SerializeMemberInfos[0].Name.Is(nameof(_ReadOnlyField.c)); }
public void PrivateMembersIsSerialized() { var objserInfo = new ObjectSerializationInfo(typeof(_PrivateMembers), true); objserInfo.SerializeMemberInfos.Length.Is(2); objserInfo.SerializeMemberInfos[0].Name.Is("a"); objserInfo.SerializeMemberInfos[1].Name.Is("b"); }
public void PrivateMembersNonPublicSetterIndex_IsCorrectly() { var objserInfo = new ObjectSerializationInfo(typeof(_PrivateMembers), true); objserInfo.SerializeMemberInfos.Length.Is(2); objserInfo.SerializeMemberInfos[0].NonPublicSetterIndex.Is(0); objserInfo.SerializeMemberInfos[1].NonPublicSetterIndex.Is(1); }
public void ExpentdType_PublicMembersIsSerialized() { var objserInfo = new ObjectSerializationInfo(typeof(_sub), false); objserInfo.SerializeMemberInfos.Length.Is(2); objserInfo.SerializeMemberInfos[0].Name.Is(nameof(_base.B)); objserInfo.SerializeMemberInfos[1].Name.Is(nameof(_sub.F)); }
static Cache() { var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); if (metaInfo != null) { formatter = new ReflectionObjectFormatter <T>(metaInfo); } }
private static bool IsConstructorParameter(ObjectSerializationInfo objectSerializationInfo, MemberSerializationInfo member) { foreach (var parameter in objectSerializationInfo.ConstructorParameters) { if (parameter.Equals(member)) { return(true); } } return(false); }
private static Expression BuildSizeCore(Type type, ObjectSerializationInfo serializationInfo, ParameterExpression instance) { List <Expression> ary = new List <Expression>(); LabelTarget returnTarget = Expression.Label(typeof(int), "returnLable"); if (!type.IsValueType) { //if (value==null) // goto label: 1; ary.Add(CommonExpressionMeta.Block_IfNullSize(instance, type, returnTarget)); } ParameterExpression size = Expression.Variable(typeof(int)); SerializeMemberInfo[] mems = serializationInfo.SerializeMemberInfos; if (mems.Length == 0) { ary.Add(Expression.Assign(size, Expression.Constant(Array3Cache.Empty.Length))); } else { int maxLen = mems[mems.Length - 1].KeyIndex + 1; ary.Add(Expression.Assign(size, Expression.Constant(BssomBinaryPrimitives.Array3HeaderSize(maxLen)))); FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances(); int nullNumber = 0; int realIndex = 0; for (int i = 0; i < maxLen; i++) { if (mems[realIndex].KeyIndex != i) { nullNumber++; } else { //Size(mem.Value) ary.Add(SpecialCodeGenExpression.SizeValues(mems[realIndex], instance, size, memFormatters)); realIndex++; } } if (nullNumber > 0) { ary.Add(Expression.AddAssign(size, Expression.Constant(nullNumber * BssomBinaryPrimitives.NullSize))); } } ary.Add(Expression.Label(returnTarget, size)); return(Expression.Block(new ParameterExpression[] { size }, ary)); }
internal static int WriteMapSerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, byte[][] memberNames, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) { var startOffset = offset; offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, writeMembers.Length); for (int i = 0; i < writeMembers.Length; i++) { offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, memberNames[i]); var memberValue = writeMembers[i].ReflectionLoadValue(value); offset += MessagePackSerializer.NonGeneric.Serialize(writeMembers[i].Type, ref bytes, offset, memberValue, formatterResolver); } return(offset - startOffset); }
private static void GenTypeInternal(Type type) { string path = GenPath + "/" + type.Name + "Formatter.cs"; Debug.Log("Gen " + type.FullName + "\n" + path); //if (File.Exists(path)) // return; FormatterTemplate formatterTemplate = new FormatterTemplate(); formatterTemplate.Namespace = NameSpace; var fields = (from fieldInfo in type.GetFields() where !fieldInfo.IsStatic && !fieldInfo.IsDefined(typeof(IgnoreDataMemberAttribute)) && !fieldInfo.IsDefined(typeof(NonSerializedAttribute)) select fieldInfo) .ToArray(); var members = (from fieldInfo in fields select new MemberSerializationInfo() { IsField = true, Name = fieldInfo.Name, MemberName = fieldInfo.Name, Type = GetPrimitiveTypeName(fieldInfo.FieldType), ShortTypeName = fieldInfo.FieldType.Name, IsReadable = true, IsWritable = true }) .ToArray(); ObjectSerializationInfo objectSerializationInfo = new ObjectSerializationInfo() { Members = members, Name = type.Name, FullName = type.FullName, Namespace = type.Namespace, IsClass = type.IsClass, HasConstructor = true, ConstructorParameters = new MemberSerializationInfo[0] }; formatterTemplate.objectSerializationInfos = new[] { objectSerializationInfo }; var sb = new StringBuilder(); sb.AppendLine(formatterTemplate.TransformText()); Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllText(path, sb.ToString()); }
public static string Classify(ObjectSerializationInfo objectSerializationInfo, string indent, bool canOverwrite) { var memberArray = objectSerializationInfo.Members; var buffer = new StringBuilder(); foreach (var memberInfoTuples in memberArray.Select(member => new MemberInfoTuple(member, IsConstructorParameter(objectSerializationInfo, member))).GroupBy(member => member.Binary.Length)) { var binaryLength = memberInfoTuples.Key; var keyLength = binaryLength >> 3; keyLength += keyLength << 3 == binaryLength ? 0 : 1; buffer.Append(indent).Append("case ").Append(binaryLength).Append(":\r\n"); ClassifyRecursion(buffer, indent, 1, keyLength, memberInfoTuples, canOverwrite); } return(buffer.ToString()); }
internal static int WriteArraySerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) { var startOffset = offset; offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, writeMembers.Length); foreach (var item in metaInfo.Members) { if (item == null) { offset += MessagePackBinary.WriteNil(ref bytes, offset); } else { var memberValue = item.ReflectionLoadValue(value); offset += MessagePackSerializer.NonGeneric.Serialize(item.Type, ref bytes, offset, memberValue, formatterResolver); } } return(offset - startOffset); }
private static void SerializeMemberInfosOrderByKeyIndex(this ObjectSerializationInfo serializationInfo, Type type) { if (serializationInfo.SerializeMemberInfos.Length > 0) { serializationInfo.SerializeMemberInfos = serializationInfo.SerializeMemberInfos.OrderBy(e => e.KeyIndex).ToArray(); SerializeMemberInfo[] serializeMemberInfos = serializationInfo.SerializeMemberInfos; for (int i = 0; i < serializeMemberInfos.Length; i++) { var mem = serializeMemberInfos[i]; if (!mem.KeyIndexHasValue) { throw BssomSerializationTypeFormatterException.Array3MembersMustDefindKeyAttribute(type, mem.Name); } if (i != 0 && mem.KeyIndex == serializeMemberInfos[i - 1].KeyIndex) { throw BssomSerializationTypeFormatterException.Array3KeyAttributeValueRepeated(type); } } } }
public static TypeInfo Build(DynamicFormatterAssembly assembly, ObjectSerializationInfo serializationInfo) { Type type = serializationInfo.Type; TypeBuilder typeBuilder = assembly.DefineFormatterType(type); serializationInfo.SerializeMemberInfosOrderByKeyIndex(type); MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type); MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type); MethodBuilder sizeMethod = TypeBuildHelper.DefineSizeMethod(typeBuilder, type); Type delegateCacheType = typeof(Array3DelegateCache <>).MakeGenericType(type); delegateCacheType.GetMethod(nameof(Array3DelegateCache <int> .Factory), BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { assembly, serializationInfo }); TypeBuildHelper.CallSerializeDelegate(serializeMethod, type, delegateCacheType.GetField(nameof(Array3DelegateCache <int> .Serialize))); TypeBuildHelper.CallSizeDelegate(sizeMethod, type, delegateCacheType.GetField(nameof(Array3DelegateCache <int> .Size))); TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, delegateCacheType.GetField(nameof(Array3DelegateCache <int> .Deserialize))); return(typeBuilder.CreateTypeInfo()); }
public void ExpentdType_PrivateMembersNonPublicSetterIndex_IsCorrectly() { var objserInfo = new ObjectSerializationInfo(typeof(_sub), true); objserInfo.SerializeMemberInfos.Length.Is(7); objserInfo.SerializeMemberInfos[0].Name.Is("A"); objserInfo.SerializeMemberInfos[1].Name.Is("D"); objserInfo.SerializeMemberInfos[2].Name.Is("B"); objserInfo.SerializeMemberInfos[3].Name.Is("C"); objserInfo.SerializeMemberInfos[4].Name.Is("E"); objserInfo.SerializeMemberInfos[5].Name.Is("F"); objserInfo.SerializeMemberInfos[6].Name.Is("G"); objserInfo.SerializeMemberInfos[0].NonPublicSetterIndex.Is(0); objserInfo.SerializeMemberInfos[1].NonPublicSetterIndex.Is(1); objserInfo.SerializeMemberInfos[2].NonPublicSetterIndex.Is(-1); objserInfo.SerializeMemberInfos[3].NonPublicSetterIndex.Is(2); objserInfo.SerializeMemberInfos[4].NonPublicSetterIndex.Is(3); objserInfo.SerializeMemberInfos[5].NonPublicSetterIndex.Is(-1); objserInfo.SerializeMemberInfos[6].NonPublicSetterIndex.Is(4); }
internal static void Factory(DynamicFormatterAssembly assembly, ObjectSerializationInfo objectSerializationInfo) { ParameterExpression instance = Expression.Parameter(objectSerializationInfo.Type, "value"); Expression <Serialize <T> > serializeExpression = Array3DynamicExpressionBuild.BuildSerializeLambda <T>(objectSerializationInfo, instance); Expression <Size <T> > sizeExpression = Array3DynamicExpressionBuild.BuildSizeLambda <T>(objectSerializationInfo, instance); Expression <Deserialize <T> > deserializeExpression = Array3DynamicExpressionBuild.BuildDeserializeLambda <T>(objectSerializationInfo); Serialize = serializeExpression.Compile(); Size = sizeExpression.Compile(); Deserialize = deserializeExpression.Compile(); #if NETFRAMEWORK TypeBuilder typeBuilder = assembly.DefineFormatterDelegateType(objectSerializationInfo.Type); MethodBuilder serializeDelegate = TypeBuildHelper.DefineSerializeDelegate(typeBuilder, typeof(T)); serializeExpression.CompileToMethod(serializeDelegate); MethodBuilder sizeDelegate = TypeBuildHelper.DefineSizeDelegate(typeBuilder, typeof(T)); sizeExpression.CompileToMethod(sizeDelegate); MethodBuilder deserializeDelegate = TypeBuildHelper.DefineDeserializeDelegate(typeBuilder, typeof(T)); deserializeExpression.CompileToMethod(deserializeDelegate); typeBuilder.CreateTypeInfo(); #endif }
internal ReflectionObjectFormatter(ObjectSerializationInfo metaInfo) { this.metaInfo = metaInfo; // for write { var memberNameList = new List <byte[]>(metaInfo.Members.Length); var emmitableMemberList = new List <ObjectSerializationInfo.EmittableMember>(metaInfo.Members.Length); foreach (var item in metaInfo.Members) { if (item.IsWritable) { emmitableMemberList.Add(item); memberNameList.Add(Encoding.UTF8.GetBytes(item.Name)); } } this.writeMemberNames = memberNameList.ToArray(); this.writeMembers = emmitableMemberList.ToArray(); } // for read { var automata = new AutomataDictionary(); var emmitableMemberList = new List <ObjectSerializationInfo.EmittableMember>(metaInfo.Members.Length); int index = 0; foreach (var item in metaInfo.Members) { if (item.IsReadable) { emmitableMemberList.Add(item); automata.Add(item.Name, index++); } } this.readMembers = emmitableMemberList.ToArray(); this.mapMemberDictionary = automata; } }
public static Expression <Size <T> > BuildSizeLambda <T>(ObjectSerializationInfo serializationInfo, ParameterExpression instance) { return(Expression.Lambda <Size <T> >(BuildSizeCore(typeof(T), serializationInfo, instance), CommonExpressionMeta.Par_SizeContext, instance)); }
private static Expression BuildDeserializeCore(Type t, ObjectSerializationInfo serializationInfo) { List <Expression> ary = new List <Expression>(); LabelTarget returnTarget = Expression.Label(t, "returnLable"); //int num; ParameterExpression num = Expression.Variable(typeof(int), "num"); //int for-i; ParameterExpression forVariable = Expression.Variable(typeof(int), "i"); //context.option.Security.DepthStep(ref reader); ary.Add(CommonExpressionMeta.Call_DeserializeContext_Option_Security_DepthStep); //if(reader.TryReadNullWithEnsureBuildInType(BssomType.Array3)) // return default(t); ary.Add(Expression.IfThen(CommonExpressionMeta.Call_Reader_TryReadNullWithEnsureBuildInType(BssomType.Array3), Expression.Return(returnTarget, Expression.Default(t)))); //T t = new T(); ParameterExpression instance = Expression.Parameter(t, "instance"); if (serializationInfo.IsDefaultNoArgsCtor) { ary.Add(Expression.Assign(instance, Expression.New(t))); } else { ParameterInfo[] parInfos = serializationInfo.BestmatchConstructor.GetParameters(); Expression[] pars = new Expression[parInfos.Length]; if (serializationInfo.ConstructorParametersIsDefaultValue) { for (int i = 0; i < parInfos.Length; i++) { pars[i] = Expression.Default(parInfos[i].ParameterType); } ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars))); } else { object[] cps = serializationInfo.ConstructorParameters; for (int i = 0; i < parInfos.Length; i++) { pars[i] = Expression.Constant(cps[i], parInfos[i].ParameterType); } ary.Add(Expression.Assign(instance, Expression.New(serializationInfo.BestmatchConstructor, pars))); } } //reader.SkipVariableNumber() ary.Add(CommonExpressionMeta.Call_Reader_SkipVariableNumber); //num = reader.ReadVariableNumber() ary.Add(Expression.Assign(num, CommonExpressionMeta.Call_Reader_ReadVariableNumber)); //i = 0; ary.Add(Expression.Assign(forVariable, Expression.Constant(0))); var members = serializationInfo.SerializeMemberInfos; if (members.Length > 0) { //reader.Buffer.Seek(offsetSegment, Current) ary.Add(CommonExpressionMeta.Call_Reader_BufferSeek(Expression.Convert(Expression.Multiply(num, Expression.Constant(BssomBinaryPrimitives.FixUInt32NumberSize)), typeof(Int64)), BssomSeekOrgin.Current)); //switch(i) // case 0: instance.Key0 = readValue(); // case 3: instance.Key1 = readValue(); // case 5: instance.Key2 = readValue(); // default: skipObj(); FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances(); SwitchCase[] switchCases = new SwitchCase[members.Length]; for (int i = 0; i < members.Length; i++) { switchCases[i] = Expression.SwitchCase(SpecialCodeGenExpression.ReadValues(members[i], instance, memFormatters), Expression.Constant(members[i].KeyIndex)); } Expression content = Expression.Switch( typeof(void), forVariable, CommonExpressionMeta.Call_Reader_SkipObject, null, switchCases ); ary.Add(For(forVariable, Expression.LessThan(forVariable, num), Expression.Assign(forVariable, Expression.Add(forVariable, Expression.Constant(1))), content)); } //context.Depth--; ary.Add(CommonExpressionMeta.Call_DeserializeContext_Depth_DecrementAssign); ary.Add(Expression.Return(returnTarget, instance)); ary.Add(Expression.Label(returnTarget, instance)); return(Expression.Block(new ParameterExpression[] { instance, num, forVariable, }, ary)); }
public static Expression <Deserialize <T> > BuildDeserializeLambda <T>(ObjectSerializationInfo serializationInfo) { return(Expression.Lambda <Deserialize <T> >(BuildDeserializeCore(typeof(T), serializationInfo), CommonExpressionMeta.Par_Reader, CommonExpressionMeta.Par_DeserializeContext)); }
private static Expression BuildSerializeCore(Type type, ObjectSerializationInfo serializationInfo, ParameterExpression instance) { List <Expression> ary = new List <Expression>(); LabelTarget returnTarget = Expression.Label(typeof(void), "returnLable"); if (!type.IsValueType) { //if (value==null) // writer.WriteNull(); goto label; ary.Add(CommonExpressionMeta.Block_IfNullWriteNullWithReturn(instance, type, returnTarget)); } ParameterExpression[] variables = null; var keys = serializationInfo.SerializeMemberInfos; if (keys.Length == 0) { //writer.WriteRaw(Array3Cache._EmptyBuffer); ary.Add(CommonExpressionMeta.Call_WriteRaw(Expression.Field(null, Array3Cache._EmptyBuffer))); } else { int maxLen = keys[keys.Length - 1].KeyIndex + 1; Type stackallocBlockType = StackallocBlockProvider.GetOrCreateType(maxLen * sizeof(uint)); //long position; //Block{size} block; //IntPtr blockPtr; variables = new ParameterExpression[3]; variables[0] = Expression.Variable(typeof(long), "elementOffPosition"); variables[1] = Expression.Variable(stackallocBlockType, "block"); variables[2] = Expression.Variable(typeof(IntPtr), "blockPtr"); //position = writer.WriteArray3Header(keys.Length); ary.Add(Expression.Assign(variables[0], CommonExpressionMeta.Call_WriteArray3Header(maxLen))); //block = new Block{size}(); ary.Add(Expression.Assign(variables[1], Expression.New(stackallocBlockType))); //blockPtr = AsPointer(ref block); ary.Add(Expression.Assign(variables[2], ExpressionTreeAux.AsPointerExpression(variables[1]))); //0,3,5 --> maxLen = 6 FieldInfo memFormatters = serializationInfo.StoreMemberFormatterInstances(); int realIndex = 0; for (int i = 0; i < maxLen; i++) { //StackallocBlockHelper.WriteUInt(blockPtr, 0, (uint)(writer.Position - position)); ary.Add(Expression.Call(null, StackallocBlockHelper._WriteUIntMethodInfo, variables[2], Expression.Constant(i), Expression.Convert(Expression.Subtract(CommonExpressionMeta.Field_WriterPos, variables[0]), typeof(uint)))); if (keys[realIndex].KeyIndex != i) { //WriteNull() ary.Add(CommonExpressionMeta.Call_Writer_WriteNull); } else { //Writer(mem.Value) ary.Add(SpecialCodeGenExpression.WriteValues(keys[realIndex], instance, memFormatters)); realIndex++; } } //writer.WriteBackArray3Header(blockPtr) ary.Add(CommonExpressionMeta.Call_WriteBackArray3Header(variables[0], variables[2], maxLen)); } ary.Add(Expression.Label(returnTarget)); if (variables != null) { return(Expression.Block(variables, ary)); } return(Expression.Block(ary)); }
internal static object Deserialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] readMembers, int[] constructorParameterIndexes, AutomataDictionary mapMemberDictionary, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { var startOffset = offset; object[] parameters = null; var headerType = MessagePackBinary.GetMessagePackType(bytes, offset); if (headerType == MessagePackType.Nil) { readSize = 1; return(null); } else if (headerType == MessagePackType.Array) { var arraySize = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); offset += readSize; // ReadValues parameters = new object[arraySize]; for (int i = 0; i < arraySize; i++) { var info = readMembers[i]; if (info != null) { parameters[i] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); offset += readSize; } else { offset += MessagePackBinary.ReadNextBlock(bytes, offset); } } } else if (headerType == MessagePackType.Map) { var mapSize = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); offset += readSize; // ReadValues parameters = new object[mapSize]; for (int i = 0; i < mapSize; i++) { var rawPropName = MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); offset += readSize; int index; if (mapMemberDictionary.TryGetValue(rawPropName.Array, rawPropName.Offset, rawPropName.Count, out index)) { var info = readMembers[index]; parameters[index] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); offset += readSize; } else { offset += MessagePackBinary.ReadNextBlock(bytes, offset); } } } else { throw new InvalidOperationException("Invalid MessagePackType:" + MessagePackCode.ToFormatName(bytes[offset])); } // CreateObject object result = null; if (constructorParameterIndexes.Length == 0) { result = Activator.CreateInstance(metaInfo.Type); } else { var args = new object[constructorParameterIndexes.Length]; for (int i = 0; i < constructorParameterIndexes.Length; i++) { args[i] = parameters[constructorParameterIndexes[i]]; } result = Activator.CreateInstance(metaInfo.Type, args); } // SetMembers for (int i = 0; i < readMembers.Length; i++) { var info = readMembers[i]; if (info != null) { info.ReflectionStoreValue(result, parameters[i]); } } readSize = offset - startOffset; return(result); }