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)); }
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)); }
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)); }