public void Check(MessageSerializedPropertyInfo messageSerializedPropertyInfo, SerializationDefaults serializationDefaults, MessageClassAttribute classAttribute) { if (!messageSerializedPropertyInfo.MessagePropertyAttribute.IsIsBcdSpecified && messageSerializedPropertyInfo.PropertyInfo.Name.StartsWith("Bcd", StringComparison.InvariantCultureIgnoreCase)) { messageSerializedPropertyInfo.MessagePropertyAttribute.IsBcd = true; } }
public virtual Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.ElementIsMessageSerializableObject) { return(typeof(TypeSerializerSerializableClass <>).MakeGenericType(new[] { propertyInfo.ElementType })); } return(null); }
public virtual Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.ElementType.FullName == typeof(string).FullName) { return(typeof(TypeSerializerString)); } return(null); }
public Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.PropertyInfo.PropertyType == typeof(byte[])) { return(typeof(TypeSerializerByteArray)); } return(null); }
public virtual Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.ElementType.IsEnum) { return(typeof(TypeSerializerEnum <>).MakeGenericType(new[] { propertyInfo.ElementType })); } return(null); }
public virtual Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.MessagePropertyAttribute.IsBcd && propertyInfo.ElementType.FullName != typeof(DateTime).FullName) { return(typeof(TypeSerializerBcd <>).MakeGenericType(new[] { propertyInfo.ElementType })); } return(null); }
public Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.ElementType.FullName == typeof(DateTime).FullName && propertyInfo.MessagePropertyAttribute.IsBcd) { return(typeof(TypeSerializerDateTime)); } return(null); }
public virtual Type CheckType(MessageSerializedPropertyInfo propertyInfo) { if (NumericFunctions.IsIntegerType(propertyInfo.ElementType) && NumericFunctions.IsPowerOfTwo((ulong)propertyInfo.MessagePropertyAttribute.Length)) { return(typeof(TypeSerializerNumeric <>).MakeGenericType(new[] { propertyInfo.ElementType })); } return(null); }
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; } }
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; } }
protected T GetApplicableCalculatedFieldAttribute <T>(MessageSerializedPropertyInfo propertyInfo) where T : CalculatedFieldAttribute { foreach (CalculatedFieldAttribute calculatedFieldAttribute in propertyInfo.CalculatedFieldAttributes) { if (calculatedFieldAttribute is T && calculatedFieldAttribute.Name == Name) { return(calculatedFieldAttribute as T); } } return(null); }
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); }
protected CodeExpression GetAssignmentExpressionForByteArray(MessageSerializedPropertyInfo propertyInfo, CodePropertyReferenceExpression propertyReferenceExpression) { // _serializerWhatever.Serialize(typedObject.Whatever); CodeExpression assignmentExpression = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), "Serialize", new CodeExpression[] { propertyReferenceExpression }); return(assignmentExpression); }
protected Type GetFieldType(MessageSerializedPropertyInfo propertyInfo) { foreach (ITypeSelector typeSelector in _typeSelectors) { Type fieldType = typeSelector.CheckType(propertyInfo); if (fieldType != null) { return(fieldType); } } throw new Exception($"Don't know what TypeSerializer to use for property {propertyInfo.PropertyInfo.Name} of type {propertyInfo.ElementType.FullName}"); }
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)); }
protected SortedSet <int> GetIncludedPropertyIndexes(int startIndex, int endIndex, List <MessageSerializedPropertyInfo> properties) { var includedPropertyIndexes = new SortedSet <int>(); for (int index = startIndex; index <= endIndex; ++index) { MessageSerializedPropertyInfo propertyInfo = properties[index]; CalculatedFieldAttribute calculatedFieldAttribute = GetApplicableCalculatedFieldAttribute <CalculatedFieldAttribute>(propertyInfo); if (calculatedFieldAttribute == null || !calculatedFieldAttribute.Exclude) { includedPropertyIndexes.Add(index); } } return(includedPropertyIndexes); }
protected List <MessageSerializedPropertyInfo> GetPropertiesForType(Type type, ConfigClassInfo configClassInfo, ref int totalLengthWithoutVariableData, ref int nonVaryingLengthPartOfMessageLength) { PropertyInfo[] objectProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); List <MessageSerializedPropertyInfo> messageSerializedProperties = new List <MessageSerializedPropertyInfo>(); int indexInMessage = 0; foreach (PropertyInfo propertyInfo in objectProperties) { MessagePropertyAttribute messagePropertyAttribute = GetMessageSerializedPropertyAttributeFromClassInfo(propertyInfo, configClassInfo, MessageClassAttribute.DefaultExcludeProperty) ?? GetMessageSerializedPropertyAttribute(propertyInfo, MessageClassAttribute.DefaultExcludeProperty); if (messagePropertyAttribute.Exclude) { continue; } // Note: If you want to check something with the attribute you should use it after creating the MessageSerializablePropertyInfo // as that is what initializes any of the unset values MessageSerializedPropertyInfo messageSerializedPropertyInfo = new MessageSerializedPropertyInfo(indexInMessage++, propertyInfo, messagePropertyAttribute, SerializationDefaults, MessageClassAttribute); if (messagePropertyAttribute.MaxLength != -1 && messagePropertyAttribute.MaxLength < messagePropertyAttribute.MinLength) { throw new Exception(string.Format("For {0} the MinLength ({1}) > MaxLength ({2}) which is not allowed", messageSerializedPropertyInfo.PropertyInfo.Name, messageSerializedPropertyInfo.MessagePropertyAttribute.MinLength, messageSerializedPropertyInfo.MessagePropertyAttribute.MaxLength)); } if (messageSerializedPropertyInfo.IsVariableLength) { IsVariableLength = true; } int propertyLength = messageSerializedPropertyInfo.MessagePropertyAttribute.Length; if (messageSerializedPropertyInfo.MessagePropertyAttribute.BlobType == BlobTypes.Data) { ContainsBlobData = true; } else if (!messageSerializedPropertyInfo.IsVariableLength) { totalLengthWithoutVariableData += propertyLength; } messageSerializedProperties.Add(messageSerializedPropertyInfo); } return(messageSerializedProperties); }
public void Check(MessageSerializedPropertyInfo messageSerializedPropertyInfo, SerializationDefaults serializationDefaults, MessageClassAttribute classAttribute) { if (!messageSerializedPropertyInfo.ContainsAuthenticationAttribute && messageSerializedPropertyInfo.PropertyInfo.Name.StartsWith("Crc", StringComparison.InvariantCultureIgnoreCase)) { messageSerializedPropertyInfo.CalculatedFieldAttributes.Add(new CalculatedAuthenticationResultAttribute(typeof(CalculatorAuthenticationCrc16))); } // By default authentication fields are excluded from length calculations if (!messageSerializedPropertyInfo.ContainsLengthAttribute && messageSerializedPropertyInfo.PropertyInfo.Name.StartsWith("Crc", StringComparison.InvariantCultureIgnoreCase)) { messageSerializedPropertyInfo.CalculatedFieldAttributes.Add(new CalculatedLengthAttribute() { Exclude = true }); } }
protected CodeExpression GetPropertyLengthExpression(MessageSerializedPropertyInfo propertyInfo) { if (propertyInfo.ElementIsMessageSerializableObject) { // Serializer.Instance.GetFixedLength<ElementType>() return(new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(Serializer)), "Instance"), "GetFixedLength", new CodeTypeReference[] { new CodeTypeReference(propertyInfo.ElementType) }))); } return(new CodePrimitiveExpression(propertyInfo.MessagePropertyAttribute.Length)); }
public virtual Type CheckType(MessageSerializedPropertyInfo propertyInfo) { Type specifiedClass = propertyInfo.MessagePropertyAttribute.TypeSerializerClass; if (specifiedClass != null) { // Double check that TypeSerializerClass actually inherits from TypeSerializerBase for (Type currentType = propertyInfo.MessagePropertyAttribute.TypeSerializerClass; currentType != null && currentType != typeof(object); currentType = currentType.BaseType) { Type typeToCheck = currentType.IsGenericType ? currentType.GetGenericTypeDefinition() : currentType; if (typeof(TypeSerializerBase <>) == typeToCheck) { return(specifiedClass); } } throw new Exception($"{specifiedClass.FullName} was specified as the TypeSerializerClass to use for property {propertyInfo.PropertyInfo.Name} of type {propertyInfo.ElementType.FullName} but it does not inherit from TypeSerializerBase<>"); } return(null); }
public void Check(MessageSerializedPropertyInfo messageSerializedPropertyInfo, SerializationDefaults serializationDefaults, MessageClassAttribute classAttribute) { if (messageSerializedPropertyInfo.ElementType.FullName == typeof(DateTime).FullName) { var messagePropertyAttribute = messageSerializedPropertyInfo.MessagePropertyAttribute; if (!messagePropertyAttribute.IsIsBcdSpecified) { messagePropertyAttribute.IsBcd = true; } if (!messagePropertyAttribute.IsFormatSpecified) { messagePropertyAttribute.Format = "MMddyyyyHHmmss"; } if (!messagePropertyAttribute.IsLengthSpecified) { messagePropertyAttribute.Length = messagePropertyAttribute.Format.Length / 2; // BCD } } }
//protected int GetIndex(MessageSerializedPropertyInfo calculatorPropertyInfo, List<MessageSerializedPropertyInfo> properties, string fieldName, Func<CalculatedFieldAttribute, bool, Position> getPositionFunction) protected int GetIndex( MessageSerializedPropertyInfo calculatorPropertyInfo, List <MessageSerializedPropertyInfo> properties, string fieldName, Func <CalculatedFieldAttribute, Position> getPositionFunction, Func <CalculatedFieldResultAttribute, Position> getDefaultPositionFunction) { // Find the class that has the value defined and then get the index from that // If there isn't a class with the value defined use the default MessageSerializedPropertyInfo valuePropertyInfo = null; int indexToUse = -1; int defaultIndex = -1; for (int currentIndex = 0; currentIndex < properties.Count; ++currentIndex) { MessageSerializedPropertyInfo propertyInfo = properties[currentIndex]; CalculatedFieldAttribute calculatedFieldAttribute = GetApplicableCalculatedFieldAttribute <CalculatedFieldAttribute>(propertyInfo); Position position = calculatedFieldAttribute == null ? Position.Unspecified : getPositionFunction(calculatedFieldAttribute); if (calculatedFieldAttribute != null && position != Position.Unspecified) { if (valuePropertyInfo != null) { throw new Exception($"For calculated field {Name}, property {propertyInfo.PropertyInfo.Name} specified {fieldName}, but {fieldName} was already specified on {valuePropertyInfo.PropertyInfo.Name}"); } valuePropertyInfo = propertyInfo; indexToUse = GetIndexFromPosition(position, currentIndex, properties.Count); } if (propertyInfo == calculatorPropertyInfo) { defaultIndex = GetIndexFromPosition(getDefaultPositionFunction(calculatedFieldAttribute as CalculatedFieldResultAttribute), currentIndex, properties.Count); } } return(valuePropertyInfo == null ? defaultIndex : indexToUse); }
protected CodeStatementCollection CreateBlobLengthStatements(string blobDataArrayName, MessageSerializedPropertyInfo blobDataPropertyInfo, List <MessageSerializedPropertyInfo> properties) { // First we need to get the property info for the length property // Then we need to assign the length to the size of the blobArray // Then we need to serialize the length MessageSerializedPropertyInfo blobLengthPropertyInfo = GetPropertyInfo(properties, blobDataPropertyInfo.MessagePropertyAttribute.AssociatedBlobProperty); string blobLengthArrayName = GetArrayName(blobLengthPropertyInfo); CodeStatementCollection codeStatementCollection = new CodeStatementCollection(); CodeAssignStatement assignLength = new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(TypedObjectFieldName), blobLengthPropertyInfo.PropertyInfo.Name), new CodeCastExpression( blobLengthPropertyInfo.ElementType, new CodePropertyReferenceExpression( new CodeVariableReferenceExpression(blobDataArrayName), "Length"))); codeStatementCollection.Add(assignLength); codeStatementCollection.AddRange(GetConvertToByteArrayStatement(blobLengthArrayName, blobLengthPropertyInfo)); return(codeStatementCollection); }
protected MessageSerializedPropertyInfo GetCalculatorPropertyInfo(List <MessageSerializedPropertyInfo> properties, out int calculatedFieldIndex) { MessageSerializedPropertyInfo calculatorPropertyInfo = null; calculatedFieldIndex = 0; for (int currentIndex = 0; currentIndex < properties.Count; ++currentIndex) { MessageSerializedPropertyInfo propertyInfo = properties[currentIndex]; CalculatedFieldResultAttribute calculatedFieldResultAttribute = GetApplicableCalculatedFieldAttribute <CalculatedFieldResultAttribute>(propertyInfo); if (calculatedFieldResultAttribute != null && calculatedFieldResultAttribute.Calculator != null) { if (calculatorPropertyInfo != null) { throw new Exception($"For calculated field {Name}, property {propertyInfo.PropertyInfo.Name} has a calculator type defined of {calculatedFieldResultAttribute.Calculator.FullName} but the the class already has a calculator type defined on property {calculatorPropertyInfo.PropertyInfo.Name}"); } Type actualCalculatorType = calculatedFieldResultAttribute.GetActualCalculatedType(propertyInfo.PropertyInfo); Type expectedCalculatorType = typeof(CalculatorBase <>).MakeGenericType(new Type[] { propertyInfo.PropertyInfo.PropertyType }); if (!CheckIsType(actualCalculatorType, expectedCalculatorType, false)) { throw new Exception($"For calculated field {Name}, property {propertyInfo.PropertyInfo.Name}, a calculator type was defined of {actualCalculatorType.FullName} but it is not of type {expectedCalculatorType.FullName}"); } calculatorPropertyInfo = propertyInfo; calculatedFieldIndex = currentIndex; } } if (calculatorPropertyInfo == null) { throw new Exception($"Calculated field {Name} does not have any property attributes that define a calculator for the class"); } return(calculatorPropertyInfo); }
public TypeSerializerByteArray(MessageSerializedPropertyInfo propertyInfo) : base(propertyInfo) { }
public TypeSerializerString(MessageSerializedPropertyInfo propertyInfo) : base(propertyInfo) { }
protected CodeExpression CreateToStringStatementForProperty(CodeExpression elementExpression, string nameToUse, MessageSerializedPropertyInfo propertyInfo, bool isFirstProperty) { //_serializerWhatever.ToString(typedObject.Whatever, indentLevel, formatProperties, isFirstProperty)); CodeMethodInvokeExpression toStringExpression = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression(GetSerializerMemberVariableName(propertyInfo)), "ToString", new CodeExpression[] { elementExpression, new CodeVariableReferenceExpression("indentLevel"), new CodeVariableReferenceExpression("formatProperties"), new CodePrimitiveExpression(isFirstProperty) }); return(toStringExpression); }
// TODO: It would be nice to be able to declare a TypeSerializerNumeric using the UnderlyingType but that doesn't seem possible public TypeSerializerEnum(MessageSerializedPropertyInfo propertyInfo) : base(propertyInfo) { }
protected TypeSerializerBase(MessageSerializedPropertyInfo propertyInfo) { _propertyInfo = propertyInfo; }