protected override Tuple <Expression, Expression> GetDeSerializerExp(Expression codec)
            {
                //
                // long stateVar;
                //
                bool needToInit;
                ParameterExpression stateVarExp = StateStore.GetOrCreateStateVar(
                    StateName, typeof(long), out needToInit);

                //
                // ++stateVar;
                // return stateVar;
                //
                Expression deltaExp =
                    Expression.Block(
                        Expression.PreIncrementAssign(stateVarExp),
                        DebugValueExp(codec, stateVarExp, "MultFld ReadDelta"),
                        stateVarExp);

                //
                // stateVar = codec.ReadSignedValue();
                // return stateVar;
                //
                Expression initExp =
                    needToInit
                        ? Expression.Block(
                        Expression.Assign(stateVarExp, ReadSignedValue(codec)),
                        DebugValueExp(codec, stateVarExp, "MultFld ReadInit"),
                        stateVarExp)
                        : deltaExp;

                return(new Tuple <Expression, Expression>(initExp, deltaExp));
            }
            protected override Tuple <Expression, Expression> GetSerializerExp(Expression valueExp, Expression codec)
            {
                //
                // long stateVar;
                //
                bool needToInit;
                ParameterExpression stateVarExp = StateStore.GetOrCreateStateVar(
                    StateName, typeof(long), out needToInit);

                ParameterExpression varState2Exp = Expression.Variable(typeof(long), "state2");

                //
                // stateVar2 = valueGetter();
                // if (checked(stateVar2 - stateVar) != (long) 1)
                //     throw new SerializerException();
                // stateVar = stateVar2;
                // return true;
                //
                Expression deltaExp =
                    Expression.Block(
                        typeof(bool),
                        new[] { varState2Exp },
                        Expression.Assign(varState2Exp, valueExp),
                        Expression.IfThen(
                            Expression.NotEqual(
                                Expression.SubtractChecked(varState2Exp, stateVarExp),
                                Expression.Constant((long)1)),
                            Expression.Throw(
                                Expression.New(
                                    // ReSharper disable AssignNullToNotNullAttribute
                                    typeof(SerializerException).GetConstructor(new[] { typeof(string) }),
                                    // ReSharper restore AssignNullToNotNullAttribute
                                    Expression.Constant("Index values are not sequential")))),
                        Expression.Assign(stateVarExp, varState2Exp),
                        DebugValueExp(codec, stateVarExp, "MultFld WriteDelta"),
                        Expression.Constant(true)
                        );

                //
                // stateVar = valueGetter();
                // codec.WriteSignedValue(stateVar);
                //
                Expression initExp =
                    needToInit
                        ? Expression.Block(
                        Expression.Assign(stateVarExp, valueExp),
                        DebugValueExp(codec, stateVarExp, "MultFld WriteInit"),
                        WriteSignedValue(codec, stateVarExp))
                        : deltaExp;

                return(new Tuple <Expression, Expression>(initExp, deltaExp));
            }
Beispiel #3
0
        protected override Tuple <Expression, Expression> GetDeSerializerExp(Expression codec)
        {
            //
            // long stateVar;
            //
            bool needToInit;
            ParameterExpression stateVarExp = StateStore.GetOrCreateStateVar(StateName, typeof(long), out needToInit);

            Expression stateToValueExp = StateToValue(stateVarExp);

            //
            // Only if the state needs to be initialized:
            //
            // stateVar = codec.ReadValue();
            // return stateVar * scale;
            //
            Expression initExp =
                needToInit
                    ? Expression.Block(
                    Expression.Assign(stateVarExp, ReadSignedValue(codec)),
                    DebugValueExp(codec, stateVarExp, "DeltaFld ReadInit"),
                    stateToValueExp)
                    : null;

            //
            // stateVar += codec.ReadValue();
            // return stateVar * scale;
            //
            Expression deltaExp =
                Expression.Block(
                    Expression.AddAssign(stateVarExp, ReadDeltaExp(codec)),
                    DebugValueExp(codec, stateVarExp, "DeltaFld ReadDelta"),
                    stateToValueExp);

            return(new Tuple <Expression, Expression>(initExp ?? deltaExp, deltaExp));
        }
Beispiel #4
0
        protected override Tuple <Expression, Expression> GetSerializerExp(Expression valueExp, Expression codec)
        {
            //
            // long stateVar;
            //
            bool needToInit;
            ParameterExpression stateVarExp = StateStore.GetOrCreateStateVar(StateName, typeof(long), out needToInit);

            Expression getValExp = ValueToState(codec, valueExp);

            Expression validationExp = OnWriteValidation(codec, valueExp, stateVarExp);

            //
            // stateVar = valueGetter();
            // DEBUG: stateVar
            //
            // codec.WriteSignedValue(stateVar);
            //
            Expression initExp =
                needToInit
                    ? Expression.Block(
                    Expression.Assign(stateVarExp, getValExp),
                    DebugValueExp(codec, stateVarExp, "ScaledFld WriteInit"),
                    validationExp ?? Expression.Empty(),
                    // The first item is always stored as a signed long
                    WriteSignedValue(codec, stateVarExp))
                    : null;

            ParameterExpression varState2Exp = Expression.Variable(typeof(long), "state2");
            ParameterExpression varDeltaExp  = Expression.Variable(typeof(long), "delta");

            //
            // stateVar2 = valueGetter();
            // delta = stateVar2 - stateVar
            //
            var exprs =
                new List <Expression>
            {
                Expression.Assign(varState2Exp, getValExp),
                Expression.Assign(varDeltaExp, Expression.Subtract(varState2Exp, stateVarExp))
            };

            Expression exp = ValidateDeltaExp(codec, varDeltaExp, varState2Exp);

            if (exp != null)
            {
                exprs.Add(exp);
            }

            //
            // stateVar = stateVar2;
            // DEBUG: DebugValue(stateVar);
            // Optional: ValidateState
            //
            exprs.Add(Expression.Assign(stateVarExp, varState2Exp));
            exprs.Add(DebugValueExp(codec, stateVarExp, "ScaledFld WriteDelta"));
            if (validationExp != null)
            {
                exprs.Add(validationExp);
            }

            exprs.Add(WriteDeltaValue(codec, varDeltaExp));

            Expression deltaExp = Expression.Block(
                typeof(bool),
                new[] { varState2Exp, varDeltaExp },
                exprs);

            return(new Tuple <Expression, Expression>(initExp ?? deltaExp, deltaExp));
        }
        protected override Tuple <Expression, Expression> GetDeSerializerExp(Expression codec)
        {
            //
            // long stateVar;
            //
            bool needToInit;
            ParameterExpression stateVarExp = StateStore.GetOrCreateStateVar(StateName, typeof(long), out needToInit);

            //
            // valueGetter():
            //    if non-integer: (decimal)value * ((decimal)Divider / Multiplier)
            //    if integer:     (type)value * divider
            //

            Expression getValExp = stateVarExp;

            if (_multiplier != 1 || _divider != 1)
            {
                if (!_isInteger)
                {
                    switch (FieldType.GetTypeCode())
                    {
                    case TypeCode.Single:
                        getValExp = Expression.Divide(
                            Expression.Convert(getValExp, typeof(float)),
                            Expression.Constant((float)_multiplier / _divider));
                        break;

                    case TypeCode.Double:
                        getValExp = Expression.Divide(
                            Expression.Convert(getValExp, typeof(double)),
                            Expression.Constant((double)_multiplier / _divider));
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                else
                {
                    if (_multiplier != 1)
                    {
                        throw new InvalidOperationException();
                    }
                    if (getValExp.Type != FieldType)
                    {
                        getValExp = Expression.Convert(getValExp, FieldType);
                    }
                    getValExp = Expression.Multiply(getValExp, _dividerExp);
                }
            }
            else if (getValExp.Type != FieldType)
            {
                getValExp = Expression.Convert(getValExp, FieldType);
            }


            MethodCallExpression readValExp = ReadSignedValue(codec);

            //
            // stateVar += codec.ReadSignedValue();
            // return stateVar;
            //
            Expression deltaExp =
                Expression.Block(
                    Expression.AddAssign(stateVarExp, readValExp),
                    DebugValueExp(codec, stateVarExp, "MultFld ReadDelta"),
                    getValExp);

            //
            // stateVar = codec.ReadSignedValue();
            // return stateVar;
            //
            Expression initExp =
                needToInit
                    ? Expression.Block(
                    Expression.Assign(stateVarExp, readValExp),
                    DebugValueExp(codec, stateVarExp, "MultFld ReadInit"),
                    getValExp)
                    : deltaExp;

            return(new Tuple <Expression, Expression>(initExp, deltaExp));
        }
        protected override Tuple <Expression, Expression> GetSerializerExp(Expression valueExp, Expression codec)
        {
            //
            // long stateVar;
            //
            bool needToInit;
            ParameterExpression stateVarExp = StateStore.GetOrCreateStateVar(StateName, typeof(long), out needToInit);

            //
            // valueGetter():
            //    if non-integer: (#long) Math.Round(value * Multiplier / Divider, 0)
            //    if integer:     (#long) (value / divider)
            //

            Expression getValExp = valueExp;

            if (_multiplier != 1 || _divider != 1)
            {
                if (!_isInteger)
                {
                    switch (FieldType.GetTypeCode())
                    {
                    case TypeCode.Single:
                    {
                        // floats support 7 significant digits
                        float dvdr     = (float)_multiplier / _divider;
                        float maxValue = (float)Math.Pow(10, 7) / dvdr;

                        getValExp = FloatingGetValExp(codec, getValExp, dvdr, -maxValue, maxValue);
                    }
                    break;

                    case TypeCode.Double:
                    {
                        // doubles support at least 15 significant digits
                        double dvdr     = (double)_multiplier / _divider;
                        double maxValue = Math.Pow(10, 15) / dvdr;

                        getValExp = FloatingGetValExp(codec, getValExp, dvdr, -maxValue, maxValue);
                    }
                    break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
                else
                {
                    if (_multiplier != 1)
                    {
                        throw new InvalidOperationException();
                    }
                    getValExp = Expression.Divide(getValExp, _dividerExp);
                }
            }

            // for integer types, do not check, ulong would not fit otherwise
            if (getValExp.Type != typeof(long))
            {
                getValExp =
                    _isInteger
                        ? Expression.Convert(getValExp, typeof(long))
                        : Expression.ConvertChecked(getValExp, typeof(long));
            }


            ParameterExpression varState2Exp = Expression.Variable(typeof(long), "state2");
            ParameterExpression varDeltaExp  = Expression.Variable(typeof(long), "delta");

            //
            // stateVar2 = valueGetter();
            // delta = stateVar2 - stateVar
            // stateVar = stateVar2;
            // return codec.WriteSignedValue(delta);
            //
            Expression deltaExp =
                Expression.Block(
                    typeof(bool),
                    new[] { varState2Exp, varDeltaExp },
                    Expression.Assign(varState2Exp, getValExp),
                    Expression.Assign(varDeltaExp, Expression.Subtract(varState2Exp, stateVarExp)),
                    Expression.Assign(stateVarExp, varState2Exp),
                    DebugValueExp(codec, stateVarExp, "MultFld WriteDelta"),
                    WriteSignedValue(codec, varDeltaExp)
                    );

            //
            // stateVar = valueGetter();
            // codec.WriteSignedValue(stateVar);
            //
            Expression initExp =
                needToInit
                    ? Expression.Block(
                    Expression.Assign(stateVarExp, getValExp),
                    DebugValueExp(codec, stateVarExp, "MultFld WriteInit"),
                    WriteSignedValue(codec, stateVarExp))
                    : deltaExp;

            return(new Tuple <Expression, Expression>(initExp, deltaExp));
        }