public ConfigMessageSerializerClass CreateClassInfoFromType(Type type, SerializationDefaults serializationDefaults = null) { if (serializationDefaults == null) { serializationDefaults = new SerializationDefaults(); } MessageSerializedClassInfo messageSerializedClassInfo = new MessageSerializedClassInfo(type, null, serializationDefaults); ConfigMessageSerializerClass configMessageSerializerClass = new ConfigMessageSerializerClass(); ConfigClassInfo configClassInfo = new ConfigClassInfo(); configClassInfo.AssemblyName = messageSerializedClassInfo.ClassType.Assembly.FullName; configClassInfo.ClassFullName = messageSerializedClassInfo.ClassType.FullName; configClassInfo.MessageClassAttribute = messageSerializedClassInfo.MessageClassAttribute; configMessageSerializerClass.ClassInfo = configClassInfo; foreach (MessageSerializedPropertyInfo messageSerializedPropertyInfo in messageSerializedClassInfo.Properties) { ConfigPropertyInfo configPropertyInfo = new ConfigPropertyInfo(); configPropertyInfo.Name = messageSerializedPropertyInfo.PropertyInfo.Name; //configPropertyInfo._messagePropertyAttribute = messageSerializedPropertyInfo.MessagePropertyAttribute; configPropertyInfo.Attributes.Add(messageSerializedPropertyInfo.MessagePropertyAttribute); configClassInfo.Properties.Add(configPropertyInfo); } return(configMessageSerializerClass); }
public byte[] Serialize <T>(T objectToSerialize) where T : class, IMessageSerializable { MessageSerializedClassInfo classInfo = GetClassInfo(typeof(T)); return(classInfo.Serializer.Serialize(objectToSerialize)); }
public DeserializeResults <T> DeserializeEx <T>(byte[] bytes, ref int currentArrayIndex, bool suppressExceptions) where T : class, IMessageSerializable { MessageSerializedClassInfo classInfo = GetClassInfo(typeof(T)); return(classInfo.Serializer.Deserialize <T>(bytes, ref currentArrayIndex, suppressExceptions)); }
protected virtual CodeStatementCollection GetVerifyCalculatedFieldStatements(MessageSerializedClassInfo classInfo) { CodeStatementCollection statements = new CodeStatementCollection(); foreach (CalculatedFieldInfo calculatedFieldInfo in classInfo.CalculatedFields) { if (calculatedFieldInfo.CalculatorResultAttribute.Verify) { // _calculator.Verify(status, typedObject.CalculatorField, array1, array2, ...); var verifyExpression = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression(GetCalculatorMemberVariableName(calculatedFieldInfo)), "Verify", new CodeExpression[] { new CodeVariableReferenceExpression("status"), new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(TypedObjectFieldName), calculatedFieldInfo.CalculatorResultPropertyInfo.PropertyInfo.Name), new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(GetListBytesName(calculatedFieldInfo)), "ToArray"), }); statements.Add(verifyExpression); } } return(statements); }
protected CodeStatementCollection AssignListDataFromByteArrayStatement(MessageSerializedClassInfo classInfo, MessageSerializedPropertyInfo propertyInfo, CodeVariableReferenceExpression currentArrayIndexExpression, CodeExpression fieldLengthExpression) { CodeVariableReferenceExpression objectToSerializeExpression = new CodeVariableReferenceExpression(TypedObjectFieldName); CodePropertyReferenceExpression propertyReferenceExpression = new CodePropertyReferenceExpression(objectToSerializeExpression, propertyInfo.PropertyInfo.Name); List <CalculatedFieldInfo> calculatedFieldsThatIncludeThisField = GetCalculatedFieldsThatIncludeThisFieldAndRequireVerification(classInfo.CalculatedFields, propertyInfo); CodeStatementCollection codeStatementCollection = new CodeStatementCollection(); CodeExpression assignmentExpression; if (calculatedFieldsThatIncludeThisField.Count == 0) { // _serializerWhatever.DeserializeList<List<Type>>(bytes, ref currentArrayIndex, length, status); assignmentExpression = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), "DeserializeList", new CodeTypeReference[] { new CodeTypeReference(propertyInfo.PropertyInfo.PropertyType) }), new CodeExpression[] { new CodeVariableReferenceExpression("bytes"), new CodeDirectionExpression(FieldDirection.Ref, currentArrayIndexExpression), fieldLengthExpression, new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression("status")) }); } else { List <CodeExpression> argumentsToDeserialize = new List <CodeExpression>() { new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), new CodeVariableReferenceExpression("bytes"), new CodeDirectionExpression(FieldDirection.Ref, currentArrayIndexExpression), fieldLengthExpression, new CodeVariableReferenceExpression("status") }; argumentsToDeserialize.AddRange(calculatedFieldsThatIncludeThisField.Select(item => new CodeVariableReferenceExpression(GetListBytesName(item)))); // this.DeserializeList<List<Type>>(_serializerWhatever, bytes, ref currentArrayIndex, length, status, array1, array2); assignmentExpression = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeThisReferenceExpression(), "DeserializeList", new CodeTypeReference[] { new CodeTypeReference(propertyInfo.PropertyInfo.PropertyType), new CodeTypeReference(propertyInfo.ElementType) }), argumentsToDeserialize.ToArray()); } codeStatementCollection.Add(new CodeAssignStatement(propertyReferenceExpression, assignmentExpression)); return(codeStatementCollection); }
protected void CreateCodeForClass(CodeNamespace codeNamespace, Type type, MessageSerializedClassInfo classInfo) { CodeTypeDeclaration classDeclaration = CreateClassDeclaration(type, codeNamespace); classDeclaration.Members.AddRange(CreateMemberVariables(classInfo)); classDeclaration.Members.Add(CreateConstructor(classInfo)); classDeclaration.Members.Add(CreateSerializeMethod(classInfo)); classDeclaration.Members.Add(CreateDeserializeMethod(classInfo)); classDeclaration.Members.Add(CreateToStringMethod(classInfo)); }
protected CodeConstructor CreateConstructor(MessageSerializedClassInfo classInfo) { string classInfoVariableName = "classInfo"; CodeConstructor constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public; constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(MessageSerializedClassInfo), classInfoVariableName)); // new the TypeSerializers for (int index = 0; index < classInfo.Properties.Count; ++index) { MessageSerializedPropertyInfo propertyInfo = classInfo.Properties[index]; Type fieldType = GetFieldType(propertyInfo); // _serializerFieldName = new TypeSerializerNumeric<Type>(classInfo.Properties[index]); CodeAssignStatement createSerializer = new CodeAssignStatement( new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), new CodeObjectCreateExpression( fieldType, new CodeArrayIndexerExpression( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(classInfoVariableName), "Properties"), new CodePrimitiveExpression(index)))); constructor.Statements.Add(createSerializer); } // new the Calculators foreach (CalculatedFieldInfo calculatedFieldInfo in classInfo.CalculatedFields) { // _calculatorFieldName = this.CreateCalculator<CalculatorType, ResultType>(name, classInfo); CodeAssignStatement createCalculator = new CodeAssignStatement( new CodeVariableReferenceExpression(GetCalculatorMemberVariableName(calculatedFieldInfo)), new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeThisReferenceExpression(), "CreateCalculator", new CodeTypeReference[] { new CodeTypeReference(calculatedFieldInfo.CalculatorType), new CodeTypeReference(calculatedFieldInfo.CalculatorResultPropertyInfo.ElementType), }), new CodeExpression[] { new CodePrimitiveExpression(calculatedFieldInfo.Name), new CodeVariableReferenceExpression(classInfoVariableName) })); constructor.Statements.Add(createCalculator); } return(constructor); }
public void Check(MessageSerializedPropertyInfo messageSerializedPropertyInfo, SerializationDefaults serializationDefaults, MessageClassAttribute classAttribute) { var elementType = messageSerializedPropertyInfo.ElementType; var messagePropertyAttribute = messageSerializedPropertyInfo.MessagePropertyAttribute; if (!messagePropertyAttribute.IsLengthSpecified && NumericFunctions.IsIntegerType(elementType)) { // If we are using BCD the max length isn't the number of bytes of the type, // it's however long the maximum number is. Sort of. // As an example, the MaxUInt is 4294967295, which is 10 digits. // So really, it is 9 digits. Of course that doesn't quite work // because that is 4 1/2 bytes so really we should support 5 bytes but limit // how many we fill in but for now we will just say it is the minimum number // of bytes that things can safely be fit in. // elementType.GetField("MaxValue").GetValue(null).ToString() // The call to GetField uses Reflection to the get static MaxValue field. // The call to GetValue(null) gets the value of the MaxValue field (the null is because it's static) // Then the ToString is to figure out the number of digits that can be used. Type lengthType = elementType.IsEnum ? Enum.GetUnderlyingType(elementType) : elementType; messagePropertyAttribute.Length = messagePropertyAttribute.IsBcd ? (lengthType.GetField("MaxValue").GetValue(null).ToString().Length + 1) / 2 : Marshal.SizeOf(lengthType); } if (!messagePropertyAttribute.IsLengthSpecified && messageSerializedPropertyInfo.ElementIsMessageSerializableObject) { MessageSerializedClassInfo classInfo = Serializer.Instance.GetClassInfo(elementType); messagePropertyAttribute.Length = classInfo.TotalLengthWithoutVariableData; } if (!messagePropertyAttribute.IsVariableLengthSpecified && messagePropertyAttribute.BlobType == BlobTypes.Data) { messagePropertyAttribute.VariableLength = true; } if (!messagePropertyAttribute.IsVariableLengthSpecified && messagePropertyAttribute.Length == 0 && elementType.FullName == typeof(string).FullName) { messagePropertyAttribute.VariableLength = true; } if (!messagePropertyAttribute.IsMinLengthSpecified) { messagePropertyAttribute.MinLength = 0; } if (!messagePropertyAttribute.IsMaxLengthSpecified) { messagePropertyAttribute.MaxLength = -1; } if (!messagePropertyAttribute.IsMinimizeVariableLengthSpecified) { messagePropertyAttribute.MinimizeVariableLength = false; } }
public override void SetFieldInfo(string name, MessageSerializedClassInfo classInfo) { base.SetFieldInfo(name, classInfo); _nonVaryingLengthPartOfMessageLength = 0; foreach (int propertyIndex in _calculatedFieldInfo.IncludedPropertyIndexes) { MessageSerializedPropertyInfo propertyInfo = classInfo.Properties[propertyIndex]; if (!propertyInfo.IsVariableLength) _nonVaryingLengthPartOfMessageLength += propertyInfo.MessagePropertyAttribute.Length; } }
protected CodeStatementCollection GetAssignFromByteArrayStatement(MessageSerializedClassInfo classInfo, MessageSerializedPropertyInfo propertyInfo, CodeVariableReferenceExpression currentArrayIndexExpression, CodeExpression fieldLengthExpression) { CodePropertyReferenceExpression propertyReferenceExpression = new CodePropertyReferenceExpression(new CodeVariableReferenceExpression(TypedObjectFieldName), propertyInfo.PropertyInfo.Name); List <CalculatedFieldInfo> calculatedFieldsThatIncludeThisField = GetCalculatedFieldsThatIncludeThisFieldAndRequireVerification(classInfo.CalculatedFields, propertyInfo); CodeStatementCollection codeStatementCollection = new CodeStatementCollection(); CodeExpression assignmentExpression; if (calculatedFieldsThatIncludeThisField.Count == 0) { // If there aren't any calculated fields that depend on this field then typeSerializer.Deserialize can just be called directly //assignmentExpression = GetDeserializeTypeExpression(propertyInfo, currentArrayIndexExpression, fieldLengthExpression); // _serializerWhatever.Deserialize(bytes, ref currentArrayIndex, length, ref status); assignmentExpression = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), "Deserialize", new CodeExpression[] { new CodeVariableReferenceExpression("bytes"), new CodeDirectionExpression(FieldDirection.Ref, currentArrayIndexExpression), fieldLengthExpression, new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression("status")) }); } else { // Otherwise we need to call SerializerBase.Deserialize with the arrays that need to have the bytes from this field added // so that the calculated field can be recalculated to verify the received value matches. // this.Deserialize<TResultType>(_serializerWhatever, bytes, ref currentArrayIndex, length, status, array1, array2); List <CodeExpression> argumentsToDeserialize = new List <CodeExpression>() { new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), new CodeVariableReferenceExpression("bytes"), new CodeDirectionExpression(FieldDirection.Ref, currentArrayIndexExpression), fieldLengthExpression, //new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression("status")), new CodeVariableReferenceExpression("status") }; argumentsToDeserialize.AddRange(calculatedFieldsThatIncludeThisField.Select(item => new CodeVariableReferenceExpression(GetListBytesName(item)))); assignmentExpression = new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "Deserialize", argumentsToDeserialize.ToArray()); } codeStatementCollection.Add(new CodeAssignStatement(propertyReferenceExpression, assignmentExpression)); return(codeStatementCollection); }
protected CodeMemberMethod CreateDeserializeMethod(MessageSerializedClassInfo classInfo) { CodeMemberMethod method = new CodeMemberMethod(); method.Attributes = MemberAttributes.Public | MemberAttributes.Override; method.Name = "Deserialize"; method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(byte[]), "bytes")); CodeParameterDeclarationExpression currentArrayParameterDeclarationExpression = new CodeParameterDeclarationExpression(typeof(int), "currentArrayIndex"); currentArrayParameterDeclarationExpression.Direction = FieldDirection.Ref; method.Parameters.Add(currentArrayParameterDeclarationExpression); method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(DeserializeStatus), "status")); method.ReturnType = new CodeTypeReference(typeof(object)); // If there are calculated fields that have the Verify flag set we need to create a List<byte[]> // for each of them to put the bytes that should be used for the calculation for the verification method.Statements.AddRange(GetCreateListBytesVariables(classInfo)); // ClassType typedObject = new ClassType(); CodeVariableDeclarationStatement typedObjectDeclaration = new CodeVariableDeclarationStatement( new CodeTypeReference(classInfo.ClassType), TypedObjectFieldName, new CodeObjectCreateExpression(classInfo.ClassType)); method.Statements.Add(typedObjectDeclaration); CodeVariableReferenceExpression currentArrayIndexExpression = new CodeVariableReferenceExpression("currentArrayIndex"); foreach (MessageSerializedPropertyInfo propertyInfo in classInfo.Properties) { if (!propertyInfo.IsVariableLength) { method.Statements.AddRange(GetAssignFromByteArrayStatement(classInfo, propertyInfo, currentArrayIndexExpression, GetPropertyLengthExpression(propertyInfo))); } else if (propertyInfo.MessagePropertyAttribute.BlobType == BlobTypes.Data) { method.Statements.AddRange(GetAssignDataFromBlobByteArrayStatement(propertyInfo, currentArrayIndexExpression, classInfo.Properties, classInfo)); } else { method.Statements.AddRange(GetAssignStatementForVariableLengthField(propertyInfo, classInfo)); } } // If we have any calculated fields that need to be verified now is the time to call the Verify method method.Statements.AddRange(GetVerifyCalculatedFieldStatements(classInfo)); method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression(TypedObjectFieldName))); return(method); }
public SerializerBase CreateSerializerClassForType(MessageSerializedClassInfo classInfo) { Type type = classInfo.ClassType; CodeCompileUnit compileUnit = new CodeCompileUnit(); GenerateCodeFromType(type, compileUnit, classInfo); CompilerResults results = CompileCode(type, compileUnit); Type createdType = results.CompiledAssembly.GetType(string.Format(type.Namespace + "." + GetClassName(type)), true, true); SerializerBase serializerBase = (SerializerBase)Activator.CreateInstance(createdType, new object[] { classInfo }); return(serializerBase); }
protected CodeTypeMember CreateToStringMethod(MessageSerializedClassInfo classInfo) { CodeMemberMethod method = new CodeMemberMethod(); method.Attributes = MemberAttributes.Public | MemberAttributes.Override; method.Name = "ToString"; method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "objectToPrint")); method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "indentLevel")); method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ToStringFormatProperties), "formatProperties")); method.ReturnType = new CodeTypeReference(typeof(string)); CodeVariableDeclarationStatement typedObjectDeclaration = new CodeVariableDeclarationStatement( new CodeTypeReference(classInfo.ClassType), TypedObjectFieldName, new CodeCastExpression( new CodeTypeReference(classInfo.ClassType), new CodeVariableReferenceExpression("objectToPrint"))); method.Statements.Add(typedObjectDeclaration); CodeVariableDeclarationStatement stringResultExpression = new CodeVariableDeclarationStatement( typeof(string), "stringResult", new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty")); method.Statements.Add(stringResultExpression); bool isFirstProperty = true; foreach (MessageSerializedPropertyInfo propertyInfo in classInfo.Properties) { CodePropertyReferenceExpression propertyExpression = new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(TypedObjectFieldName), propertyInfo.PropertyInfo.Name); method.Statements.Add(CreateAddToStringResultStatement(CreateToStringStatementForProperty(propertyExpression, propertyInfo.PropertyInfo.Name, propertyInfo, isFirstProperty))); isFirstProperty = false; } method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("stringResult"))); return(method); }
protected virtual CodeStatementCollection GetCreateListBytesVariables(MessageSerializedClassInfo classInfo) { CodeStatementCollection statements = new CodeStatementCollection(); foreach (CalculatedFieldInfo calculatedFieldInfo in classInfo.CalculatedFields) { if (calculatedFieldInfo.CalculatorResultAttribute.Verify) { // List<byte[]> listBytesName = new List<byte[]>(); CodeVariableDeclarationStatement arrayDeclaration = new CodeVariableDeclarationStatement( new CodeTypeReference(typeof(List <byte[]>)), GetListBytesName(calculatedFieldInfo), new CodeObjectCreateExpression(typeof(List <byte[]>))); statements.Add(arrayDeclaration); } } return(statements); }
public string ToString(IMessageSerializable objectToPrint, bool includeBytes, int indentLevel = 0, string separator = null, string bytesSeparator = null, bool putBytesAfter = false, ToStringFormatProperties formatProperties = null) { MessageSerializedClassInfo classInfo = GetClassInfo(objectToPrint.GetType()); string stringResult = string.Empty; if ((includeBytes && (putBytesAfter == false))) { stringResult += ArrayOps.GetHexStringFromByteArray(classInfo.Serializer.Serialize(objectToPrint), bytesSeparator) + separator; } stringResult += classInfo.Serializer.ToString( objectToPrint, indentLevel, formatProperties ?? ToStringFormatProperties.Default); if ((includeBytes && putBytesAfter)) { stringResult += separator + ArrayOps.GetHexStringFromByteArray(classInfo.Serializer.Serialize(objectToPrint), bytesSeparator); } return(stringResult); }
protected CodeTypeMemberCollection CreateMemberVariables(MessageSerializedClassInfo classInfo) { CodeTypeMemberCollection codeTypeMemberCollection = new CodeTypeMemberCollection(); // Create TypeSerializers foreach (MessageSerializedPropertyInfo propertyInfo in classInfo.Properties) { string memberVariableName = GetSerializerMemberVariableName(propertyInfo); Type fieldType = GetFieldType(propertyInfo); codeTypeMemberCollection.Add(CreateField(memberVariableName, fieldType)); } // Create Calculators foreach (CalculatedFieldInfo calculatedFieldInfo in classInfo.CalculatedFields) { string memberVariableName = GetCalculatorMemberVariableName(calculatedFieldInfo); Type fieldType = calculatedFieldInfo.CalculatorType; codeTypeMemberCollection.Add(CreateField(memberVariableName, fieldType)); } return(codeTypeMemberCollection); }
public MessageSerializedClassInfo GetClassInfo(Type type, List <ConfigMessageSerializerClass> configMessageSerializerClasses, bool replaceIfExists, SerializationDefaults serializationDefaults = null) { lock (_lock) { if (_classInfos.ContainsKey(type.FullName)) { if (!replaceIfExists) { return(_classInfos[type.FullName]); } _classInfos.Remove(type.FullName); } if (serializationDefaults == null) { serializationDefaults = new SerializationDefaults(); } MessageSerializedClassInfo messageSerializedClassInfo = new MessageSerializedClassInfo(type, configMessageSerializerClasses, serializationDefaults); _classInfos.Add(type.FullName, messageSerializedClassInfo); return(messageSerializedClassInfo); } }
protected virtual CalculatedFieldInfo GetMyCalculatedFieldInfo(MessageSerializedClassInfo classInfo) { return(classInfo.CalculatedFields.Single(calculatedFieldInfo => calculatedFieldInfo.Name == _name)); }
protected CodeMemberMethod CreateSerializeMethod(MessageSerializedClassInfo classInfo) { CodeMemberMethod method = new CodeMemberMethod(); method.Attributes = MemberAttributes.Public | MemberAttributes.Override; method.Name = "Serialize"; method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "objectToSerialize")); method.ReturnType = new CodeTypeReference(typeof(byte[])); CodeVariableDeclarationStatement typedObjectDeclaration = new CodeVariableDeclarationStatement( new CodeTypeReference(classInfo.ClassType), TypedObjectFieldName, new CodeCastExpression( new CodeTypeReference(classInfo.ClassType), new CodeVariableReferenceExpression("objectToSerialize"))); method.Statements.Add(typedObjectDeclaration); List <string> arrayNames = new List <string>(); foreach (MessageSerializedPropertyInfo propertyInfo in classInfo.Properties) { string arrayName = GetArrayName(propertyInfo); arrayNames.Add(arrayName); if (propertyInfo.IsCalculatedResult) { continue; } // Now get the actual assignment statement // For blob length fields we have to wait until we've figured out the length before we can serialize if (propertyInfo.MessagePropertyAttribute.BlobType != BlobTypes.Length) { method.Statements.AddRange(GetConvertToByteArrayStatement(arrayName, propertyInfo)); } // Since we got the data now we need to set the blob length and serialize it if (propertyInfo.MessagePropertyAttribute.BlobType == BlobTypes.Data) { method.Statements.AddRange(CreateBlobLengthStatements(arrayName, propertyInfo, classInfo.Properties)); } } method.Statements.AddRange(GetCalculatedFieldStatements(classInfo, arrayNames)); // Add call to combine method to put all the arrays together CodeExpression[] combineParameters = new CodeExpression[arrayNames.Count]; for (int index = 0; index < arrayNames.Count; ++index) { combineParameters[index] = new CodeVariableReferenceExpression(arrayNames[index]); } CodeVariableDeclarationStatement combineStatement = new CodeVariableDeclarationStatement( typeof(byte[]), "serialized", new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(ArrayOps)), "Combine", combineParameters)); method.Statements.Add(combineStatement); method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("serialized"))); return(method); }
protected void GenerateCodeFromType(Type type, CodeCompileUnit codeCompileUnit, MessageSerializedClassInfo classInfo) { AddReferences(codeCompileUnit, type); CodeNamespace codeNamespace = CreateUsingStatements(type.Namespace, codeCompileUnit); CreateCodeForClass(codeNamespace, type, classInfo); }
public int GetFixedLength <T>() { MessageSerializedClassInfo classInfo = GetClassInfo(typeof(T)); return(classInfo.TotalLengthWithoutVariableData); }
public string GetClassInfoString(IMessageSerializable objectForInfo, int indentLevel = 0) { MessageSerializedClassInfo classInfo = GetClassInfo(objectForInfo.GetType()); return(classInfo.ToString(indentLevel)); }
protected CodeStatementCollection GetAssignStatementForVariableLengthField(MessageSerializedPropertyInfo variableLengthFieldPropertyInfo, MessageSerializedClassInfo classInfo) { CalculatedFieldInfo messageLengthCalculatedFieldInfo = classInfo.GetCalculatedLengthInfo(); if (messageLengthCalculatedFieldInfo == null) { throw new Exception($"Class {classInfo.ClassType.FullName}, property {variableLengthFieldPropertyInfo.PropertyInfo.Name} is a variable length non-blob field but there isn't a related calculated length field"); } CodeVariableReferenceExpression currentArrayIndexExpression = new CodeVariableReferenceExpression("currentArrayIndex"); IEnumerable <int> blobLengthIndexes = messageLengthCalculatedFieldInfo.GetAssociatedBlobLengthFieldIndexes(classInfo.Properties); var getVaryingLengthFieldLengthArguments = new List <CodeExpression>(); // (int)typedObject.LengthFieldName getVaryingLengthFieldLengthArguments.Add( new CodeCastExpression( typeof(int), new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(TypedObjectFieldName), messageLengthCalculatedFieldInfo.CalculatorResultPropertyInfo.PropertyInfo.Name))); foreach (int blobLengthIndex in blobLengthIndexes) { // (int)typedObject.BlobLengthFieldName getVaryingLengthFieldLengthArguments.Add( new CodeCastExpression( typeof(int), new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(TypedObjectFieldName), classInfo.Properties[blobLengthIndex].PropertyInfo.Name))); } // _calculatorLength.GetVaryingLengthFieldLength((int)typedObject.LengthFieldName, (int)typedObject.BlobLength1, (int)typedObject.BlobLength2) CodeMethodInvokeExpression variableLengthFieldLengthExpression = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression(GetCalculatorMemberVariableName(messageLengthCalculatedFieldInfo)), "GetVaryingLengthFieldLength", getVaryingLengthFieldLengthArguments.ToArray()); CodeStatementCollection codeStatementCollection = new CodeStatementCollection(); if (variableLengthFieldPropertyInfo.IsList) { codeStatementCollection.AddRange(AssignListDataFromByteArrayStatement(classInfo, variableLengthFieldPropertyInfo, currentArrayIndexExpression, variableLengthFieldLengthExpression)); } else { codeStatementCollection.AddRange(GetAssignFromByteArrayStatement(classInfo, variableLengthFieldPropertyInfo, currentArrayIndexExpression, variableLengthFieldLengthExpression)); } return(codeStatementCollection); }
protected CodeStatementCollection GetAssignDataFromBlobByteArrayStatement(MessageSerializedPropertyInfo blobDataPropertyInfo, CodeVariableReferenceExpression currentArrayIndexExpression, List <MessageSerializedPropertyInfo> properties, MessageSerializedClassInfo classInfo) { MessageSerializedPropertyInfo blobLengthPropertyInfo = GetPropertyInfo(properties, blobDataPropertyInfo.MessagePropertyAttribute.AssociatedBlobProperty); CodeExpression fieldLengthExpression = new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(TypedObjectFieldName), blobLengthPropertyInfo.PropertyInfo.Name); if (blobDataPropertyInfo.IsList) { return(AssignListDataFromByteArrayStatement(classInfo, blobDataPropertyInfo, currentArrayIndexExpression, fieldLengthExpression)); } return(GetAssignFromByteArrayStatement(classInfo, blobDataPropertyInfo, currentArrayIndexExpression, fieldLengthExpression)); }
public virtual void SetFieldInfo(string name, MessageSerializedClassInfo classInfo) { _name = name; _calculatedFieldInfo = GetMyCalculatedFieldInfo(classInfo); }
protected CodeStatementCollection GetCalculatedFieldStatements(MessageSerializedClassInfo classInfo, List <string> arrayNames) { CodeStatementCollection codeStatementCollection = new CodeStatementCollection(); // This is to have a placeholder for instances where the variable has already been declared // so that it should not be declared again when doing the actual assignment. This is related // to when two calculated fields depend on each other in some way. HashSet <int> alreadyDeclaredIndexes = new HashSet <int>(); for (int currentIndex = 0; currentIndex < classInfo.CalculatedFields.Count; ++currentIndex) { var calculatedFieldInfo = classInfo.CalculatedFields[currentIndex]; string arrayName = GetArrayName(calculatedFieldInfo.CalculatorResultPropertyInfo); // If the calculated field is included in the calculation for some reason then // then we need to declare the array and get the bytes right now. This also holds // true for any calculated fields that have a later priority but are included in // this calculation. An example where this situation could happen is if there is // a length field in the message and the length includes a CRC-16 field at the end // of the message. The length needs to include the length of the CRC. In this // scenario, the calculation for the CRC might need to include the length which // would need to be the correct value before the calculation can be done so the length // needs to have a lower priority to make sure it is calculated first. Where this // would be invalid would be if the CRC was a variable length field but that doesn't // logically make sense anyways. for (int followingIndex = currentIndex; followingIndex < classInfo.CalculatedFields.Count; ++followingIndex) { var followingCalculatedFieldInfo = classInfo.CalculatedFields[followingIndex]; if (calculatedFieldInfo.IncludedPropertyIndexes.Contains(followingCalculatedFieldInfo.CalculatedResultIndex) && !alreadyDeclaredIndexes.Contains(followingCalculatedFieldInfo.CalculatedResultIndex)) { codeStatementCollection.AddRange(GetConvertToByteArrayStatement(GetArrayName(followingCalculatedFieldInfo.CalculatorResultPropertyInfo), followingCalculatedFieldInfo.CalculatorResultPropertyInfo)); alreadyDeclaredIndexes.Add(followingIndex); } } CodeExpression[] calculateArrayArguments = new CodeExpression[calculatedFieldInfo.IncludedPropertyIndexes.Count]; int arrayArgumentIndex = 0; foreach (int includedPropertyIndex in calculatedFieldInfo.IncludedPropertyIndexes) { calculateArrayArguments[arrayArgumentIndex++] = new CodeVariableReferenceExpression(arrayNames[includedPropertyIndex]); } CodePropertyReferenceExpression propertyReferenceExpression = new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(TypedObjectFieldName), calculatedFieldInfo.CalculatorResultPropertyInfo.PropertyInfo.Name); // typedObject.FieldName = _calculator.Calculate(array1, array2, ...) CodeAssignStatement calculateAuthenticationStatement = new CodeAssignStatement( propertyReferenceExpression, new CodeMethodInvokeExpression( new CodeVariableReferenceExpression(GetCalculatorMemberVariableName(calculatedFieldInfo)), "Calculate", calculateArrayArguments)); codeStatementCollection.Add(calculateAuthenticationStatement); if (!alreadyDeclaredIndexes.Contains(currentIndex)) { // We need to declare the array now codeStatementCollection.AddRange(GetConvertToByteArrayStatement(arrayName, calculatedFieldInfo.CalculatorResultPropertyInfo)); } else { // We already declared the array above // arrayFieldName = _serializer.Serialize(typedObject.FieldName); CodeAssignStatement assignBytesAgainStatement = new CodeAssignStatement( new CodeVariableReferenceExpression(arrayName), GetAssignmentExpressionForByteArray(calculatedFieldInfo.CalculatorResultPropertyInfo, propertyReferenceExpression)); codeStatementCollection.Add(assignBytesAgainStatement); } } return(codeStatementCollection); }
// Called by the generated class when creating a calculator protected TCalculatorType CreateCalculator <TCalculatorType, TResultType>(string name, MessageSerializedClassInfo classInfo) where TCalculatorType : CalculatorBase <TResultType>, new() { TCalculatorType calculator = new TCalculatorType(); calculator.SetFieldInfo(name, classInfo); return(calculator); }
public string GetClassInfoString(Type type, int indentLevel = 0) { MessageSerializedClassInfo classInfo = GetClassInfo(type); return(classInfo.ToString(indentLevel)); }