Beispiel #1
0
        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);
        }
Beispiel #2
0
        public byte[] Serialize <T>(T objectToSerialize)
            where T : class, IMessageSerializable
        {
            MessageSerializedClassInfo classInfo = GetClassInfo(typeof(T));

            return(classInfo.Serializer.Serialize(objectToSerialize));
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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;
            }
        }
Beispiel #9
0
        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;
            }
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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);
            }
        }
Beispiel #18
0
 protected virtual CalculatedFieldInfo GetMyCalculatedFieldInfo(MessageSerializedClassInfo classInfo)
 {
     return(classInfo.CalculatedFields.Single(calculatedFieldInfo => calculatedFieldInfo.Name == _name));
 }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        protected void GenerateCodeFromType(Type type, CodeCompileUnit codeCompileUnit, MessageSerializedClassInfo classInfo)
        {
            AddReferences(codeCompileUnit, type);

            CodeNamespace codeNamespace = CreateUsingStatements(type.Namespace, codeCompileUnit);

            CreateCodeForClass(codeNamespace, type, classInfo);
        }
Beispiel #21
0
        public int GetFixedLength <T>()
        {
            MessageSerializedClassInfo classInfo = GetClassInfo(typeof(T));

            return(classInfo.TotalLengthWithoutVariableData);
        }
Beispiel #22
0
        public string GetClassInfoString(IMessageSerializable objectForInfo, int indentLevel = 0)
        {
            MessageSerializedClassInfo classInfo = GetClassInfo(objectForInfo.GetType());

            return(classInfo.ToString(indentLevel));
        }
Beispiel #23
0
        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);
        }
Beispiel #24
0
        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));
        }
Beispiel #25
0
 public virtual void SetFieldInfo(string name, MessageSerializedClassInfo classInfo)
 {
     _name = name;
     _calculatedFieldInfo = GetMyCalculatedFieldInfo(classInfo);
 }
Beispiel #26
0
        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);
        }
Beispiel #27
0
        // 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);
        }
Beispiel #28
0
        public string GetClassInfoString(Type type, int indentLevel = 0)
        {
            MessageSerializedClassInfo classInfo = GetClassInfo(type);

            return(classInfo.ToString(indentLevel));
        }